[solved] How to create a forever loop monitoring serial device

Hi all,

I’m quite a while busy with my own home automation project! Let me first explain it a bit before asking my question.

I have Finder 15.81.8.230.0500 relays for dimming my lights in my house. My goal is to control these dimmers with homeassistant.

I designed my own PCB which measures the output voltage of these Finder dimming modules and converts it to a duty cycle which represents the dimming intensity of the lamp. Each PCB contains one Arduino Nano and can control 2 Finder dimmers. The PCB also contains a MAX485 chip in order to communicate between the Arduino Nano and my USB serial device which I have connected to my Synology DS918+. I intend to connect ~16 of these PCBs to my NAS via only one USB serial device in half duplex mode. This all works perfect and I’m able to control and read out my lights via python scripts. For the serial communication between python and the Arduino’s I’m using the pymodbus library.

I’m running Hass.io on synology docker (via the beta Synocommunity app). This works great!
I’m running visual studio code and appdaemon for now. With appdaemon, I’m able to include pymodbus and I’m able to toggle my light.

Now I want to have one python script running which reads continuously the status of all my lamps sequentially by polling the status of each Arduino one by one via the USB serial interface. I want to create other AppDaemon scripts which handles the interaction with Homeassistant. In AppDaemon I created an (async) script. I ready that async would be best suited for such a continuous running script. However, the script stops after a ~20s and AppDaemon completely hangs and can only continue by a restart of the AppDaemon addon.

How should I setup a script in AppDaemon which is constantly (reliably) running and reading/writing to all 16 Arduino Nano’s?

Best regards,

Ruud

Async is definitely the way to go when you are doing i/o. Please post your appdaemon script so we can have a look.

just used a while(true) loop for now to simulate continous operation. this script stops running after ~20s and freezes appdaemon

import appdaemon.plugins.hass.hassapi as hass
import time
from pymodbus.client.sync import ModbusSerialClient

class Modbus_interface(hass.Hass):

  async def initialize(self):
     self.log("Modbus_interface started")
     self.run_in(self.hass_cb, 10)

  async def hass_cb(self, kwargs):
     # do some async stuff  
     i=1
     while(True):
       i=i+1
       self.log(i)

When using asyncio, you need to make sure that you dont block the event loop and this is done by yielding time to the event loop. I haven’t looked into how the implementaion is done in appdaemon, but normally, you could do like this:

import appdaemon.plugins.hass.hassapi as hass
import time
import asyncio  # Needed for yielding to the event loop.
from pymodbus.client.sync import ModbusSerialClient

class Modbus_interface(hass.Hass):

  async def initialize(self):
     self.log("Modbus_interface started")
     await self.run_in(self.hass_cb, 10) # This call also need to be awaited. 

  async def hass_cb(self, kwargs):
     # do some async stuff  
     i=1
     while(True):
       await asyncio.sleep(1) #Time to yield in seconds. Use a shorter time if needed, i.e. 0.1.
       i=i+1
       self.log(i)

The above should not block the event loop and Appdaemon should stay alive. Basically, if you do not have any await calls in your async code, you are blocking the event loop.

Unless you require millisecond monitoring of your Arduino’s, I would use a reasonable scanning interval which would be set by the await asyncio.sleep() call.

2 Likes

this works great, thx Tomas!

Hi,
I’m trying to do the same thing which is reading an RS485 bus via an USB convertor.
However I can’t get the pymodus to work in the appdaemon.
Could you please share how you got it configured and working or share a tip?

Getting this error: ModuleNotFoundError: No module named ‘pymodbus’

Thank you

Regards

How is your setup? Are you running Appdaemon as an addon or in docker or in a venv?

Hi Tomas,
My setup is a raspberry pi running the Hassio image with Appdaemon as an addon.

Hi Jan,
How does your AppDaemon configuration look like?
did you include pymodbus?

python_packages:
   - pymodbus

Hi Ruud,

this did the trick
Thank you !!!