Change Log
Version 2.1.0
Fix bugs and updated with new features, including convenience functions for working with SiLA. First released 29 Sep 2025.
Added
- [core.device] added
AnyDeviceandWebsocketDevice - [core.factory] added functionality to
load_parts()to reference parts defined in separate YAML file usingconfig_fileandconfig_namefields - [core.notification] added parameter to define the decoder function; defaults to
base64.b64decode() - [core.position] added
convert_to_position()intoPosition.fromArray() - [examples.sila] added functions to create new SiLA packges, resolve annotation types, and modify implementation code for the generated package
- added new tests, tutorial files and code
Changed
- [Transfer.Liquid.Pipette.Sartorius] update how the model name is parsed
- [core.connection] update
get_addresses()to cover both MAC address and non Mac address references - [core.control] update the priority counter of
TwoTierQueue - [core.factory] update
get_setup()to disconnect devices upon setup failure - [core.safety] updated module to support dynamic changing of safety levels
- [examples.gui.tkinter.gui] bug fix
- updated tests, documentation, and type hints
Removed
- removed unused and outdated script files in
scripts/
Version 2.0.0
Major overhaul and package rebuilt from the ground. First released 27 Jun 2025.
Added
- added
tests/written with pytest - added test execution with tox
- added documentation building with Mkdocs
- added documentation hosting with ReadTheDocs
- added proper logging facility with Python
loggingmodule - [core] new core modules and features added
- [control] added
TwoTierQueuefor queuing both priority and normal jobs; newControllerto relay data over a communication gap (either application-wise or network-wise) to enable remote calls; newProxyto mimic object behavior that is on the other end of a Controller-Controller bridge - [datalogger] functions to trigger data streaming and recording, conversion of data sequence to Pandas dataframe, and live plotting of data
- [device] base classes for tools of different connection modes (e.g. serial, socket)
- [file_handler] added function to zip files, and add repository to sys.path
- [interpreter] added interpreters to serialize data for transfer over network (i.e.
JSONInterpreter) - [log_filters] added logging filters to selectively toggle the verbosity of individual objects
- [notification] added notifiers to send large data/files (i.e.
EmailNotifier) - [position] added
Positionclass, consisting of anumpy.ndarrayfor 3D coordinates and ascipy.spatial.transform.Rotationfor 3D rotation for better description of positioning in 3D space; addedSlotthat defines the available space onDeckforLabwareto be placed on;BoundingVolumeandBoundingBoxto describe an envelope of space to avoid or stay within - [Make.Heat] added new
HeaterMixinto augment objects with temperature control related methods - [Make.Mixture] added new class for magnetic stirrer
TwoMag - [Measure.Electrical.BioLogic] added
BioLogicviaeasy-biologiclibrary - [Move] added a generic
GCodethat can use different variants of G-code (i.e. GRBL, Marlin) - [Transfer.Liquid.Pipette.Sartorius] added separate API module/class for direct implementation from manual
- [View] added placeholder image as bytestring in .py file
- [View] added
Camera.processImage()method to allow user to define custom image processing callbacks, including detection algorithms - [external] added sub-package to contain required libraries written by external parties that are not installable through PyPI; credits documented in
docs/ATTRIBUTIONS.md - [examples.control] added example implementations for
Controllercommunication layers using FastAPI and sockets - [examples.gui] GUI example implementation in tkinter with only implementations for translation, liquid transfer, and vision
- [example.sila] added XML generator for SiLA2 configuration files; refer to SiLA2 documentation for full usage of SiLA; Control-lab-ly simplifies the implementation definition step in using SiLA
Changed
- consolidated packaging to single
pyproject.tomlfile - move all
requirements_*.txtfiles todev/ - change minimum Python version to 3.10 from 3.8
- changed to
corefrommiscsub-package to better reflect how these modules incoreunderpin the functionalities of Control-lab-ly - [core] clearer separation of scope in
coremodules - [compound] new complex tool definitions described below, containing
Compound,Combined,Ensemble, andMultichannel - [connection] functions relating to getting the IP, port, and machine addresses
- [factory] functions to procedurally parse config files, retrieve object classes, initialize objects, and returning tool setups in preferred form (e.g. dict, namedtuple, NameSpace, dataclass)
- [file_handler] functions relating to file and folder creation, path resolution, and reading files
- [logging] makes use of Python native
loggingmodule to log messages from package - [position] classes that define location (e.g.
Well,Labware,Deck) - [safety] unchanged
- [core.compound] updated paradigm of how complex tools are defined, with
Compoundfor multiple connections, dissimilar parts;Ensemblefor multiple connections, similar parts;Combinedfor single connection, dissimilar parts (or use mixins);Multichannelfor single connection, similar parts - example implementation (using
Compoundand mixins) can be found inCompoundsub-package, and (usingEnsembleandMultichannel) inTransfer.Liquid.Pump.TriContinent.tricontinent - [core.device] all equipment API that does read/write actions inherits from these device classes that provide methods for parsing, connecting, read/write actions, streaming; takes in user-defined templates for read/write parsing
- [Make.Light] uses
threading.Timerfor timing actions (viacore.device.TimedDeviceMixin), instead of running a separate thread to count time - [Measure.Electrical.Keithley] updated code to leverage
PyMeasurelibrary - [Move] support for GRBL and Marlin separated into their respective APIs, and brought up to top level of
Move, as G-code can also be used for jointed robots - [Move.Jointed.Dobot] moved dobot API into
externalsub-module (see above in the 'Added' section) - [Transfer.Liquid] reorganized tools based on type (i.e. Pump, Pipette), then brands
- [Transfer.Substrate] generalized
GripperMixinthat can be used with any translation robot, instead of just Dobot attachments
Removed
- removed
GUIas a top-level sub-package; downgraded to an example implementation using tkinter (see above in 'Added' section) - removed reference guide GUI window in favor of a proper documentation site (i.e. GitHub Pages, ReadTheDocs)
- [core.factory] removed registration of imported modules to keep track of modules
- [Measure] simplify inheritance structure by removing
Programmableclass - [Measure.Electrical] removed Keithley programs that were based on old implementation (before PyMeasure)
- [Measure.Mechanical] removed PiezoRobotics from tool list due to inactive development and use
- [Transfer.Liquid] removed implementations for "syringe" and peristaltic pump due lack of use
- [Transfer.Powder] removed due to lack of use
- [Transfer.Substrate.Dobot] removed Dobot specific implementations; prefer mixins instead (see above in 'Changed' section)
- [View] removed detection methods in
Cameradue to out of scope - [View.Classifiers] removed due to out of scope
Version 1.3.2
Feature enhancements, bug fixes and patches. First released 24 Apr 2024.
Added
- add new
delayparameter inKeithley.programs.IV_Scan
Changed
- fix critical bug in setting sense/source limits for
KeithleyDevice - fix bugs in
KeithleyDevice,Peltier,ForceSensor
Version 1.3.1
Feature enhancements, bug fixes and patches. First released 11 Apr 2024.
Added
- implementation of
TriContinent.pullback() - new
Wellproperties and option in return list of wells by rows instead of columns
Changed
- fix bugs in
Peltier(setTemperature()andgetTemperature()) - fix bugs in
Ender(setTemperature()andgetTemperature()) - fix bug in
Keithley.setFunction() - generalise
IV_Scanto take either currents or voltages
Version 1.3.0
Feature enhancements, bug fixes and patches. First released 19 Feb 2024.
Added
- added check for poor physical connection with
PiezoRoboticsDevice - Keithley
- added new subclasses of
KeithleyDevice:DAQ6510andSMU2450 - added way to read and save model name of
KeithleyDevice - added new Keithley program for DAQ to scan multiple channels
- new methods
clearErrors(),setDisplay(),setFunction()
Changed
- changed the way travel times are calculated for
Movertools, so that they reflect the actual physical travel times more accurately - changed ability to delay initialisation of TriContinent pumps until it is in a more convenient location
- fixed few bugs with
SentronProbetool
Removed
- removed old archived files
Version 1.2.0
Feature enhancements, bug fixes and patches. First released 22 Aug 2023.
Added
ForceClampSetupclassLoadCellclassBalanceclass (subclass ofLoadCell)
Changed
- update
LEDArrayto delay timing loop by 0.1s - fix bug with initialising
PiezoRoboticsDevice - update
getTemperature()across multiple classes to standardise output Moverclass- speed-related attributes and properties
- add method to calculate travel time based on target speed, acceleration and deceleration
- modify how speeds and max speeds interact with
move()andsafeMoveTo() CartesianclasssetSpeed()andsetSpeedFraction()- get max speed settings from device upon connecting
- change calculation of movement wait times using device speed and acceleration
Primitivclass- change the class name to
GrblandPrimitivas a subclass name to retain compatibility - overload
moveTo()and_query()methods to use jogging mode - modify the sequence of commands to halt movement
- implement
getAcceleration(),getCoordinates(),getMaxSpeed() - clear errors and setting feed rate upon establishing connection
Enderclass- change the class name to
MarlinandEnderas a subclass name to retain compatibility - added method to immediately stop movement
- implement
getAcceleration(),getCoordinates(),getMaxSpeed() - separate methods for
setSpeed()(absolute speed in mm/s) andsetSpeedFraction()(proportional speed to max speed) Dobotclass- added
stop()method - Flir
AX8class - added
invertPalette()method - added data parsing methods
_decode_from_modbus()and_encode_to_modbus() KeithleyDevice()class- added
ip_addressproperty - added options for
_read()method - added
readline()method - implement
disconnect()method - fix bug with Keithley programs using
device.run()instead ofdevice.start()
Removed
Thermalclass- removed dependency on
imutilspackage
Versions 1.1.2 & 1.1.1
Bug fixes and patches. First released 12 Jul 2023.
Added
- import
Deviceclasses in init files to view documentation - added library for GRBL status and error codes
- add
update_root_direcctory()function to Helper
Changed
- fix bug with adding new rows into Dataframes
- use
reset_input_buffer()instead offlushInput()forpyserial.Serialobjects - print the actual string sent to Serial devices
- update methods in
Deck,Labware, andWellto camelCase - update
Deck.isExcluded()to apply strict inequalities when determining out-of-range coordinates - update
LiquidMoverto insert a portion of tip into rack before ejecting - update
Spinner - fix bug with sending commands
- added
_query()method - pass verbosity to individual spinners
- verbosity of
Measureobjects pass through to devices - update
PiezoRoboticsDevice - initialize upon connection
- raise errors when encountering them
- update
Mover - modify
setFlag()to print kwargs instead of raising error if assigned values are not boolean - use
safe_height(if defined) instead of z-coordinate of home insafeMoveTo() - added
getSettings()method - update
Gantryclass - read multiple flines in
_query() - check that commands end with newline before sending to device
- fix bug with changing speeds
- update
Ender - added
getTemperature(),holdTemperature(),isAtTemperature()methods - modified
setTemperature()to use Marlin code to wait for temperature - update
Primitivclass - add
getStatus()andstop()methods - add
_get_settings()method - fix bug in
M1Pro.setHandedness() - update
Sartoriusclass tip_inset_mmnow an instance attribute with initialisation parameters- set
tip_onflag to False when performingeject()
Version 1.1.0
Bug fixes and feature enhancements. First released 15 Jun 2023.
Added
ForceSensor- DIY force sensor (#55)BioShake- orbital shaker from QInstruments (#56)SentronProbe- pH meter probe from Sentron (#75)Maker- added
execute()abstract method and implemented in subclasses - GUI
Guide- documentation guideMakerPanel- daptive GUI controls forMakerobjects (#87)
Changed
M1Pro- fix issue with changing handedness (#86)
Peltier- rename
getTemperatures()togetTemperature() - rename
isReady()toisAtTemperature() - rename
set_pointtoset_temperature Ender- rename
set_pointtoset_temperature TriContinent- rename
step_limittolimits - Refactor and reorganize
GUIcode - Refactor code in
helperandfactory - Updated documentation
Removed
Analysesub-package removedControl.Schedulesub-package removed- Unnecessary commented-out blocks of code
Version 1.0.1
Bug fixes and minor feature enhancements. First released 08 May 2023.
Added
LiquidMover- Added
LiquidMover.touchTip()method to touch the pipette tip against the walls of the vessel to remove excess liquid on the outside of the tip (#62) - Added option to indicate the position of the first available pipette tip in
LiquidMover(#61) - Added adaptive GUI controls for
Liquidobjects (#70) - Added option to indicate which digital IO channel to use with Dobot attachments (#53)
Changed
MassBalance- Updated to the use
pd.concat()instead ofpd.DataFrame.append(), which is going ot be deprecated (#63) - Fixed endless loop for when
MassBalancetries tozero()while recording data (#60) - Changed the
Imageclass and methods into functions within a module (#54) - Fixed the tool offset of pipette when pipette tip is attached, and accounts for the length of pipette that enters the pipette tip (#64)
- Changed to using more precise time interval measurements by moving from
time.time()totime.perf_counter()(#68) - Fixed discrepancy in aspirate and dispense speed for
Sartorius(#73) and let speed return to a global default value (#72) - Updated documentation
Version 1.0.0
Major overhaul in package structure. Standardisation of methods and consolidation of common methods. First released 12 Apr 2023.
Added
- Usage of Abstract Base Classes (ABCs) to define a base class with abstract methods that needs to be implemented through sub-classing (#31)
- Usage of Protocols to provide an interface between different classes of objects (#30)
- Usage of Dataclasses to store complex data
- Usage of decorators to modify methods
- Introduced different functions to parse the program docstring and find program parameters
Changed
- Standardised methods and consolidated common methods
- Added type hints (#28)
- Moved Dobot attachments from Mover to Transfer.Substrate
- Split GUI Panels into individual files
- Split Dobot arms into individual files
- Split functions/methods in
misc.pyinto individual files. - Changed
_flagsto a public attributeflags - Update documentation (#27, #28, #29)
Removed
- Unnecessary commented-out blocks of code
Version 0.0.x
(0.0.4.x) Introduced control for Peltier device and TriContinent Series C syringe pumps. First released 10 Mar 2023.\ (0.0.3.x) Minor changes to movement robot safety and pipette control. Introduced control for LED array. First released 08 Mar 2023.\ (0.0.2.x) Updates in setting up configuration files. First released 24 Feb 2023.\ (0.0.1.x) First release of Control.lab.ly distributed on 23 Feb 2023.\ (0.0.0.x) Pre-release packaging checks
Added
0.0.4
- Added control for
Peltier(#23) - set and get temperatures
- hold temperatures for desired duration
- checks if target temperature has been reached by checking power level lower than a threshold or time passed over a predefined duration, once the temperature is within tolerance
- ability to record temperatures and timestamps
- Added control for
TriContinentandTriContinentEnsemble(#25) - single actions such as
empty,fill,initialise, move actions, set speeds and valves, and wait - compound actions such as
aspirate,dispense, andprime
0.0.3
- Added safety measures for movement actions (#24)
- In
Deck, added exclusion zones when reading thelayout.jsonfile and new methodis_excluded()to check if target coordinate is within the exclusion zone - In
Mover, updateisFeasible()method to check if target coordinates violates the deck's exclusion zone - New function
set_safety()defines safety modes when starting a new session to pause for input (in "high" safety setting) and to wait for safety countdown (in "low" safety setting) Make.Light.LEDArrayfor controlling LEDs in the photo-reactor, as well as timing the LED "on" durations (#35)
0.0.2.2
- Added import of
CompoundSetupclass
0.0.2
Deck.at()method for directly referencing slots using either index numbers or names- New
CompoundSetupclass for common methods ofCompounddevices - New
load_deck()function to loadDeckafter initialisation
0.0.1
- Make
- Multi-channel spin-coater [Arduino]
- Measure
- (Keithley) 2450 Source Measure Unit (SMU) Instrument
- (PiezoRobotics) Dynamic Mechanical Analyser (DMA)
- Precision mass balance [Arduino]
- Move
- (Creality) Ender-3
- (Dobot) M1 Pro
- (Dobot) MG400
- Primitiv [Arduino]
- Transfer
- (Sartorius) rLINEĀ® dispensing modules
- Peristaltic pump and syringe system [Arduino]
- View
- (FLIR) AX8 thermal imaging camera - full functionality in development
- Web cameras [General]
- misc
- Helper class for most common actions
- create_configs: make new directory for configuration files
- create_setup: make new directory for specific setup-related files
- load_setup: initialise setup on import during runtime
Changed
0.0.4
- Update documentation
0.0.3.1
- Update documentation
0.0.3
Sartorius- made the blowout/home optional for the dispense method upon emptying the pipette
- Update documentation
0.0.2.1
- Changed template files for
lab.create_setup()
0.0.2
- Update documentation