Metadata-Version: 2.4
Name: AMFTools
Version: 0.1.11
Summary: AMF Tools is a python package to control Advanced Microfluics SA devices
Home-page: https://amf.ch
Author: Advanced_Microfluidics_SA
Author-email: support@amf.ch
License: proprietary license (Advanced Microfluidics SA)
Classifier: Programming Language :: Python :: 3
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Security
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: licence
Requires-Dist: pyserial
Requires-Dist: ftd2xx
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# AMF Tools Python Library <a id= "amf-tools-python-library"></a>

## Description

AMF Tools Python Library is a python library to control Advanced Microfluidics products (RVMFS, RVMLP, SPM and LSPone) with a serial connection protocol.
This library is provided as an example to help getting started with our products. We do not guarantee that it is working in any conditions.  

## Installation

### Requirements

- Python 3.8 or higher
- pyserial 3.4 or higher
- ftd2xx 1.1.2 or higher

Currently only tested on Windows 11 with Python 3.11, an update could be made for alternative OS.

### Installation with pip

```bash
pip install AMFTools
```

## License

This Library is proprietary software of **Advanced Microfluidics S.A**. It is distributed under a proprietary license [[1](#license-text)].

This Library is free to use for Advanced Microfluidics SA customers. It is not free to use for non-customers of Advanced Microfluidics SA.

If you have any questions about the license, please contact Advanced Microfluidics SA: 
- Chem. de la Dent d'Oche 1A, 1024 Ecublens (Switzerland)
- +41 21 552 14 30
- support@amf.ch

## Usage

*This version of the data sheet is for the version [0.1.11](#0.1.11) of the AMFTools library.*

### Example

```python
import amfTools
import time

list_amf = amfTools.util.getProductList() # Get the list of AMF products connected to the computer
print("\n******* List of AMF products connected to the computer *******")
for amf in list_amf:
    print(amf)
print("**************************************************************\n")

amf : amfTools.AMF = None

try:
    if len(list_amf) < 1:
        raise ConnectionAbortedError("No AMF product connected to the computer. Please check your connections")
        
    # Connect to the first AMF product of the list
    amf = amfTools.AMF(list_amf[0])        
    
    print(f"Connected to product {amf.getType()} on port {amf.getSerialPort()}\n")
    
    # Check if the product is homed (if not, home it)
    if not amf.getHomeStatus():
        amf.home()
    
    # Move to the port 2, wait 3 seconds and move to the port 4
    amf.valveShortestPath(2) # Blocking function, will return only once the move is done
    print("Valve on port 2")
    time.sleep(3)
    amf.valveShortestPath(4) 
    
    print(f"Valve on port {amf.getValvePosition()}")
    
    # Move to the port 3
    amf.valveShortestPath(3, block= False)  # Non blocking function
    # Wait until the move is done
    amf.pullAndWait()
    print("Valve on port 3")
    print(f"Valve Status: {amf.checkValveStatus()}")
    
finally:
    if amf:
        amf.disconnect()
```


## Changelog

### 0.1.11 <a id= "0.1.11"></a>
- Add compatibility with new RVM mini product
- Add pump and valve errors descriptions
- Improve *pullAndWait()* function behaviour in case of pump blocked error
  - Add an argument to automatically clear pump blocked error status
- Allow use of float numbers with volume-based functions for the pump

- Add some functions:
  - Add *getPlungerForce()* function
  - Add *clearPumpBlockedError()* function

### 0.1.10 <a id= "0.1.10"></a>
- Fix known issues from [0.1.9](#0.1.9)  version
- Add a quick mode to the *pullAndWait()* function
- Improve *setSyringeSize()* and *getSyringeSize()* functions: if possible, syringe size is read/written from/into the product's memory (depending on the firmware version)
- Add some functions:
  - Add *setPullAndWaitDetailedMode()* function
  - Add *getProductFamily()* function
  - Add *halt()* and *resume()* functions
  - Add *valveClockwiseMove()* and *valveCounterClockwiseMove()* functions again (they were removed in version [0.1.9](#0.1.9))
- Rename *close_shared_serial()* to *closeSharedSerial()*
- Change some functions' arguments:
  - *\_\_init__()*: Add *silentMode* argument
  - *prepareCommand()*: add *customCmd* argument
  - *pullAndWait()*: add *detailed_mode* and *warning_error* arguments
  - *getProductList()*: add *product_family* argument
  - *setFlowRate()*: add *silentMode* argument
  - *setSyringeSize()*: add *silentMode* argument
  - *getFlowRate()*: add *silentMode* argument
  - *getSyringeSize()*: add *silentMode* argument
  - *getUniqueID()*: add *short_ID* argument
  - *sendBrute()*: add *check_ans* and *ans_type* arguments
  - *hardStop()*: add *clear_status* argument
  - *getProductList()*: add *product_family* and *silent_mode* arguments
- Add firmware update recommendations in some functions (*setSyringeSize(), getSyringeSize(), setFlowRate(), getFlowRate()*)
  - These recommendations can be turned off using the *silentMode = True* argument
- Miscellaneous improvements and corrections

### 0.1.9 <a id= "0.1.9"></a>
- Add RS485 compatibility (several products can share the same COM port)
- Add automatic verification of product's answer with the set functions to detect if the command was accepted or not
- Improve the *pullAndWait()* function:
  - Improve errors descriptions
  - Add an error counter to avoid errors generated by communication issues
- Add some functions:
  - Add *setSpeedLowFlow()* and *setSpeedUltraLowFlow()* functions
  - Add *getSpeedPump()* and *getSpeedModePump()* functions
  - Add *setFlowRate()* and *getFlowRate()* functions
  - Add *getReductionRatio()* function
  - Add *valveMoveBy()* function
  - Add *close_shared_serial()* function
- Rename some functions:
  - Rename *setNoAwser()* function to *setNoAnswer()*
  - Rename *getSpeedMode()* function to *getSpeedModeValve()*
  - Rename *getValveAddress()* function to *getAddress()*
  - Rename *getValveConfiguration()* function to *getProductConfiguration()*
- Remove some functions:
  - Remove *setSpeedVolume()* function
  - Remove *valveClockwiseMove()* and *valveCounterClockwiseMove()* functions
- Change some functions' arguments:
  - *\_\_init__()*: Add *typeProduct* and *connectionMode* arguments
  - *send()*: 
    - Add *data* and *full_ans* arguments
    - Rename *force_aws* to *force_ans*
  - *receive()*:
    - Add *data* and *full_ans* arguments
    - Remove *float* argument
  - *setPumpStrengthAndHome()*: rename *strength* to *force*
  - *setNoAnswer()*: add *no_ans* argument
  - *getSerialPort()*: remove *serialNumber* argument
  - *getSerialNumber()*: remove *serialPort* argument
  - *getDeviceInformation()*: add *full* argument
  - *sendBrute()*: rename *blocked* to *block*, rename *force_aws* to *force_ans*
  - *internalReset()*: add *block* argument
  - *executeLastCommand()*: add *block* argument
  - *delay()*: add *block* argument
  - *pumpPickup()*: rename *position* to *move_length*
  - *pumpRelativePickup()*: rename *position* to *move_length*
  - *pumpDispense()*: rename *position* to *move_length*
  - *pumpRelativeDispense()*: rename *position* to *move_length*
  - *getProductList()*:
    - Add *connection_mode*, *port*, *address_list*
    - Remove *specified_type*
- Miscellaneous improvements and corrections

#### Known issues in 0.1.9 version
- getProductList() function may leave a COM port open, causing errors when trying to connect to it
  - It occurs if the function is called with unspecified "connection_mode" and if only 1 COM port is available on the computer
  - Providing an argument for the "connection_mode" parameter will solve the problem (ex: getProductList("USB"))
- no_ans mode do not work properly for most of the set functions (setPortNumber(), setSpeed()...)
- We recommend using version [0.1.10](#0.1.10) or above instead


<br>
<br>
<br>
<br>
<br>

## License text <a id= "license-text">


``` richtext
AMF Tools Python Package by Advanced Microfluidics SA

Copyright (C) 2023 Advanced Microfluidics SA

This Python Package is distributed to all AMF customers and partners for the sole purpose of using it with AMF products.

The right to use this Python Package is included in the price of all AMF OEM products.

REDISTRIBUTION AND USE in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- (i) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- (ii) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- (iii) Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
- (iv) The use of this Python Package is restricted to AMF products.

WARRANTY OF EVICTION. Advanced Microfluidics SA represents and warrants: 
- (i) that it holds all the Intellectual Property Rights required to enter into the Agreement; 
- (ii) that the Advanced Microfluidics SA Service, as well as the elements necessary for their operation provided in performance of the Agreement, do not infringe the rights of third parties and do not constitute an infringement of any pre-existing work or even infringement of any other software or other intellectual creation belonging to a third party;

RESPONSIBILITY LIMITATION: This package is provided by the copyright holder and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright holder or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.

Advanced Microfluidics SA reserves the right to modify this Agreement at any time by publishing a new version on https://amf.ch . The applicable terms and conditions are those in force on the date of the order.

NUMBER OF COPIES: The Customer may make as many copies of the package as necessary for the use of the Package in accordance with the terms of this Agreement. The Customer may make a copy of the Package for backup purposes. The Customer may not make copies of the Package for any other purpose.

DURATION: This Agreement is effective from the date of delivery of the AMF Product to the Customer and shall remain in force until terminated by either party.

TERMINATION: This Agreement shall terminate automatically if the Customer fails to comply with any of the terms and conditions of this Agreement. In such event, the Customer must destroy all copies of the package.

GEOGRAPHICAL RESTRICTIONS: The Customer may not export or re-export the Package or any copy or adaptation thereof in violation of any applicable locals laws or regulations.

GOVERNING LAW: This Agreement shall be governed by and construed in accordance with the laws of Switzerland. The parties agree that the United Nations Convention on Contracts for the International Sale of Goods is specifically excluded from application to this Agreement.

JURISDICTION: Any dispute arising out of or in connection with this Agreement shall be submitted to the exclusive jurisdiction of the courts of the Canton of Vaud, Switzerland.
```

### [BACK TO THE TOP](#amf-tools-python-library)
