Jan-21-2022, 12:04 PM
I am trying to run three simple tasks in parallel using asyncio and sharing global variables.
Two of them are working perfectly. One read websockets ("async with websockets.connect("ws://192.168.1.137:9000") as websocket:" Another one access IO via a dedicated library.
I did not find any solution and the good syntax for getting AsyncModbusTCPClient running within the third task (sync MODBUS is easy to implement but would not fit within async task)
The following would just block everything:
Two of them are working perfectly. One read websockets ("async with websockets.connect("ws://192.168.1.137:9000") as websocket:" Another one access IO via a dedicated library.
I did not find any solution and the good syntax for getting AsyncModbusTCPClient running within the third task (sync MODBUS is easy to implement but would not fit within async task)
The following would just block everything:
async def get_var_modbus(loop): client = await AsyncModbusTCPClient( schedulers.ASYNC_IO,host="192.168.1.200", loop=loop, port=502, timeout=20, unit=3) while True: print("INIT") print("Reading coils") rr = await client.read_input_registers(0, 1, unit=0x03) print(rr.registers) await asyncio.sleep(1)Full code below
from pymodbus.client.asynchronous import schedulers from pymodbus.client.asynchronous.tcp import AsyncModbusTCPClient import json import time from pypx800v5 import * import aiohttp import asyncio import requests_async as requests import numpy as np import logging from datetime import datetime import websockets import contextvars import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # SDM230 via MODBUS SDM230A=["Voltage","Current","Active Power","Apparent Power","Reactive Power","Power Factor","Phase Angle","Frequency","Import Active Energy","Export Active Energy","Import Reactive Energy","Export Reactive Energy"] SDM230B=["Total system power demand","Maximum total system power demand","Current system positive power demand","Maximum system positive power demand","Current system reverse power demand","Maximum system reverse power demand"] SDM230C=["Current demand","Maximum current Demand"] SDM230D=["Total Active Energy","Total Reactive Energy"] SDM230Labels=SDM230A+SDM230B+SDM230C+SDM230D SDM230Var=["Voltage","Current","ActivePower","ApparentPower","ReactivePower","PowerFactor","PhaseAngle","Frequency","ImportActiveEnergy","ExportActiveEnergy","ImportReactiveEnergy","ExportReactiveEnergy","TotalSysPowerDemand","MaxTotalSysPowerDemand","CurrentSysPositivePowerDemand","MaxSysPositivePowerDemand","CurrentSysReversePowerDemand","MaxSysReversePowerDemand","CurrentDemand","MaximumCurrentDemand","TotalActiveEnergy","TotalReactiveEnergy"] VoltageAdd=262199 CurrentAdd=262200 ActivePowerAdd=262201 ImportActiveEnergyAdd=262202 # inversor via Websockets TempChaudiereAdd=262198 PuissMaxChauffeauAdd=262193 WREDAdd=262194 PacBat6TLAdd=262195 totPVAdd=262196 SOC6TLAdd=262197 # shared variables WRED= 0 PacBat6TL=0 PacPV6TL=0 Pac6TLM=0 SOC6TL=0 PAC6TL=0 totPV=0 # --------------------------------------------------------------------------- # # configure the client logging # --------------------------------------------------------------------------- # logging.basicConfig() log = logging.getLogger() log.setLevel(logging.DEBUG) async def get_var_modbus(loop): client = await AsyncModbusTCPClient( schedulers.ASYNC_IO,host="192.168.1.200", port=502, loop=loop, timeout=20, unit=3) while True: print("INIT") print("Reading coils") rr = await client.read_input_registers(0, 1, unit=0x03) print(rr.registers) await asyncio.sleep(1) async def get_var_socket(): global WRED global PacBat6TL global PacPV6TL global Pac6TLM global SOC6TL global PAC6TL global totPV print("") i=0 dict={} async with websockets.connect("ws://192.168.1.137:9000") as websocket: while True: i=i+1 data=(await websocket.recv()) try: message=json.loads(data) except: break if "product" in message: if message["product"]=="ems": print(message) if "WRED" in message: WRED=message["WRED"] if "PacBat6TL" in message: PacBat6TL=message["PacBat6TL"] if "PacPV6TL" in message: PacPV6TL=message["PacPV6TL"] totPV=PacPV6TL if "Pac6TLM" in message: Pac6TLM=message["Pac6TLM"] totPV=totPV+Pac6TLM if "SOC6TL" in message: SOC6TL=message["SOC6TL"] if "PAC6TL" in message: PAC6TL=message["PAC6TL"] async def get_ipx_update(): print("") i=0 dict={} async with IPX800(host='192.168.1.139', api_key='API') as ipx: await ipx.init_config() while True: try: await ipx.update_ana(WREDAdd,WRED) except: print("ERROR") try: await ipx.update_ana(PacBat6TLAdd,PacBat6TL) except: print("ERROR") try: await ipx.update_ana(totPVAdd,totPV) except: print("ERROR") try: await ipx.update_ana(SOC6TLAdd,SOC6TL) except: print("ERROR") await asyncio.sleep(1) def main(): loop = asyncio.get_event_loop() loop.create_task(get_var_socket()) loop.create_task(get_ipx_update()) loop.create_task(get_var_modbus(loop)) loop.run_forever() if __name__ == '__main__': try: main() except Exception as f: print('main error: ', f) sleep(3)