pylabrobot icon indicating copy to clipboard operation
pylabrobot copied to clipboard

YoLink API Integration to PLR

Open ericguan04 opened this issue 4 months ago • 9 comments

Added YoLink API wrapper to PLR to integrate the YoLink family of devices. More information can be found in the forum post: https://discuss.pylabrobot.org/t/yolink-api-integration-advice/297

In the main pylabrobot directory, I added the yolink directory and tried my best to follow the conventions already set.

There are two ways to use the YoLink API wrapper:

  • Method 1 allows the user to directly use the YoLink access token to setup the YoLink backend
from pylabrobot.yolink import YoLink, Sensor, Outlet

api_key = "..."

backend = YoLink(api_key=api_key)
s = Sensor(backend=backend, sensor_name="Coldspot Fridge Sensor")

await s.setup()

temp = await s.get_temperature()
humidity = await s.get_humidity()

await s.stop()
  • Method 2 allows the user to use their YoLink api credentials (UAID and secret key) to setup the YoLink backend
from pylabrobot.yolink import YoLink, Sensor, Outlet

client_id = "..."
client_secret = "..."

backend = YoLink(client_id=client_id, client_secret=client_secret)
s = Sensor(backend=backend, sensor_name="Coldspot Fridge Sensor")

await s.setup()

temp = await s.get_temperature()
humidity = await s.get_humidity()

await s.stop()

More details about getting UAID, Secret Key, and Access Token can be found here: http://doc.yosmart.com/docs/overall/qsg_uac

  • I personally found it a bit confusing the first time going through it so I can probably write some documentation on how to set this up.

Currently, the two types of devices I implemented are the Sensor() and the Outlet(). The sensor can return readings such as temperature, humidity, etc, while the outlet (yolink smart power strip) includes both read and write commands. The forum post has more details about this.

YoLink also comes with a few additional dependencies that aren't already in pylabrobot:

dependencies = [
  "aiohttp>=3.8.1",
  "aiomqtt>=2.0.0,<3.0.0",
  "pydantic>=2.0.0",
  "tenacity>=8.1.0",
]

How should these be handled?

I am setting this as a draft PR since I have only done preliminary testing with the API wrapper. Theoretically, the rest of the PLR code should function as normal since the YoLink code doesn't interact with the rest of the codebase, but testing needs to be done to be sure. Additionally, I tried to follow PLR conventions + best practices but feedback on the code structure and implementation from someone more experienced would be great.

ericguan04 avatar Aug 20 '25 21:08 ericguan04

this seems to copy a lot of files from https://github.com/YoSmart-Inc/yolink-api into PLR. why not have this code as a dependency?

rickwierenga avatar Aug 20 '25 21:08 rickwierenga

this seems to copy a lot of files from https://github.com/YoSmart-Inc/yolink-api into PLR. why not have this code as a dependency?

I think this would be a good idea - YoLink has a dependency that can be installed through pip but I haven't really tested that out to see if it works properly. I'm also not familiar with adding custom dependencies, but I can take a look into this

ericguan04 avatar Aug 20 '25 21:08 ericguan04

see setup.py for examples.

installing from pypi would be best if they offer it

having a dependency means we can use their updates moving forward and are not responsible for maintenance

rickwierenga avatar Aug 20 '25 21:08 rickwierenga

see setup.py for examples.

installing from pypi would be best if they offer it

Tried out the pypi installation of yolink-api and it seems to be working fine - I also added it as an extra dependency following the examples in setup.py

ericguan04 avatar Aug 21 '25 14:08 ericguan04

@rickwierenga if I were to add documentation for setting up and using the yolink api, where should I include it? Looking at the current doc setup, it would make sense to add something in User guide and maybe in API (not too sure about this one). Within User guide however, which subsection would be the most appropriate? It might be a little tricky classifying yolink because there are many supported yolink devices with different functions, however majority of the devices are "read data" sensors with only a few "read-write data" controllers

ericguan04 avatar Aug 26 '25 00:08 ericguan04

definitely put it under user guide, make a new section for sensors (next to plate readers, under analytical). we group by function first rather than manufacturer.

if in the future we have other devices that are not sensors we can make sections for those

API is for documenting all classes functions etc. it is auto generated

docs are very important to actually getting people to adopt and use your code

rickwierenga avatar Aug 26 '25 00:08 rickwierenga

definitely put it under user guide, make a new section for sensors (next to plate readers, under analytical). we group by function first rather than manufacturer.

if in the future we have other devices that are not sensors we can make sections for those

sounds good!

ericguan04 avatar Aug 26 '25 00:08 ericguan04

thank you for adding yolink as a dependency. it is much easier to review this PR and code will be maintainable in the future.

since this API is introducing a Sensor class, we should have a package for that (pylabrobot.sensors). This includes a front end, an abstract backend and the specific concrete backend for yolink sensors. These things all have equivalents in PLR, but please let me know if I should expand further.

The current YoLink class should probably be an io object. It fits there naturally. and at this layer, we can have a nice validation equivalent so we can run io validation on these devices.

rickwierenga avatar Aug 26 '25 00:08 rickwierenga

made a forum posts to discuss outlets: https://discuss.pylabrobot.org/t/integrating-outlets-in-plr/323

rickwierenga avatar Aug 26 '25 00:08 rickwierenga

please reopen in the future

rickwierenga avatar Dec 03 '25 22:12 rickwierenga