Devices
Sending Data from Devices
Sending Data from your devices is a simple 3 step process:
Authenticate and select the device you are sending data from.
You will need to create a representation for your device on Labstep. This can either be done on the web-app or by using the newDevice() method
Detect incoming data from the device.
How you do this will depend on the device and how it outputs data. See below for an example of how to work with simple numerical readings coming of an RS-232 device such as a balance or thermometer and another example for uploading data files being outputted by a more complex instrument such as a plate reader.
Once you have the data from the device, all that’s left is to send it to Labstep with the
addData()method.
Examples
Here is an example of how to set up a script to read from an RS-232 device such as a balance.
This example requires the PySerial package which can be downloaded by running
pip install PySerial
balance_integration_example.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import labstep
import serial
# Authenticate Labstep User
user = labstep.authenticate('myaccount@labstep.com', 'APIKEY')
# Select device
device = user.getDevice(2314)
print(f'Connected to {device.name}')
# Open Serial Port to Device
ser = serial.Serial(port='/dev/ttyACM0', timeout=2)
# Flush input to avoid data overlap and start fresh
ser.flushInput()
# Set up loop to continuously monitor data from device
try:
while True:
# Read line of data stream
raw_input = ser.readline()
# Strip new line characters from the end of the data.
stripped_input = raw_input[0:len(raw_input)-2]
# Decode the raw bytes data to a float
decoded_input = float(stripped_input.decode("utf-8"))
print(decoded_input)
# Send data to Labstep
device.addData(
fieldName='Temperature',
fieldType='numeric',
number=decoded_input,
unit='K')
except KeyboardInterrupt:
print('Stopping')
Here is an example of how to set up a script to watch a folder for data files saved by an instrument such as a plate reader.
This example requires the PySerial package which can be downloaded by running
pip install watchdog
plate_reader_integration_example.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import labstep
import time
from watchdog.observers import Observer
from watchdog.events import RegexMatchingEventHandler
USER_NAME = os.getenv('LABSTEP_USERNAME')
API_KEY = os.getenv('LABSTEP_API_KEY')
# Authenticate Labstep User
user = labstep.authenticate(USER_NAME, API_KEY)
# Select device
device = user.getDevice(2314)
print(f'Connected to {device.name}')
# Define what to do when data is detected
def onDataDetected(event):
device.addData(
fieldName='Raw Data File',
fieldType='file',
filepath=event.src_path
)
# Use watchdog built in regex event handler
# This will detect files that end in .csv
my_event_handler = RegexMatchingEventHandler([r".*\.csv$"])
# Set the handler for when files are created
my_event_handler.on_created(onDataDetected)
# Set up the watchdog observer to watch a specific folder
my_observer = Observer()
path = '/path/to/device/output/folder'
my_observer.schedule(my_event_handler, path)
# Start the observer
my_observer.start()
# Set up loop to stop the script terminating unless interupted
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
my_observer.stop()
my_observer.join()
Further Help
For further help setting up integrations with instruments please contact barney@labstep.com
Importing devices
To import new devices to a specified device category from an xlsx file.
import labstep
import pandas as pd
user = labstep.authenticate()
user.setWorkspace(WORKSPACE_ID) ## Enter Labstep target workspace ID
## Create device category and template
device_category = user.newDeviceCategory('My new device category')
device_template = device_category.getDeviceTemplate()
device_template.addMetadata(fieldName="Serial Number", fieldType="default")
device_template.addMetadata(fieldName="Manufacturer", fieldType="default")
device_template.addMetadata(fieldName="Service date", fieldType="date")
## Create devices
df = pd.read_excel('devices.xlsx')
for index, row in df.iterrows():
newDevice = user.newDevice(name=row['Device name'], device_category_id=device_category.id)
newDevice.addMetadata(fieldName='Serial Number', fieldType='default', value=row['Serial Number'])
newDevice.addMetadata(fieldName='Manufacturer', fieldType='default', value=row['Manufacturer'])
newDevice.addMetadata(fieldName='Service date', fieldType='date', date=str(row['Service date']))
Exporting devices
To export all devices in a workspace including their categories, metadata and URLs.
import pandas as pd
from datetime import datetime
import labstep
from labstep.generic.entityList.model import EntityList
## Authenticate user
user = labstep.authenticate()
workspace = user.getWorkspace(WORKSPACE_ID) ## Add ID of required workspace
print('Fetching devices')
devices = workspace.getDevices()
def export_devices(devices:EntityList, folder_target:str):
df = pd.DataFrame()
columns=['Labstep Device Category','Labstep Device ID','Device Name','QR Code URL']
for device in devices:
print(f'Exporting Device: {device.name}')
row_json={}
row_json['Labstep Device Category'] = None if device.getDeviceCategory() is None else device.getDeviceCategory().name
row_json['Labstep Device ID']=device.id
row_json['Device Name']=device.name
row_json['QR Code URL']=f"https://app.labstep.com/perma-link/{device.guid}"
metadatas = device.getMetadata()
for metadata in metadatas:
if metadata.label not in columns:columns.append(metadata.label)
for column_name in columns:
if column_name not in row_json:
metadata_entity=device.getMetadata().get(column_name)
row_json.update({column_name:metadata_entity.getValue() if metadata_entity is not None else None})
row = pd.Series(row_json, name=device.id) # create data frame row. indexed by labstep id. Keys must correspond to the columns defined above
df_row = pd.DataFrame([row])
df = pd.concat([df, df_row], axis=0, ignore_index=True)# add row to dataframe
## Get date and time of export
now = datetime.now()
# path / file name where csv will be saved.
df.to_csv(f'{folder_target}/devices{now}.csv', index=False)
export_devices(devices=devices, folder_target='exported_devices')