import asyncio #from pymodbus.server.async_io import ModbusTcpServer from pymodbus.server.async_io import ModbusTcpServer, StartAsyncTcpServer from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext import comm_m4 import time import struct import signal import sys async def run_server(): with open(os.path.join('./config.json'), encoding='UTF-8') as f: jsonData = json.load server = ModbusTcpServer(context, address=(jsonData['modbus-server']['address'], jsonData['modbus-server']['port'])) task_input = asyncio.create_task(set_input(store)) task_output = asyncio.create_task(set_output(store)) task_stop_output = asyncio.create_task(stop_output(store)) task_cal = asyncio.create_task(set_cal(store)) await asyncio.gather(server.serve_forever(), task_input, task_output, task_stop_output, task_cal) async def set_input(store): while True: try: rsp = store.getValues(16,0, count=10) if rsp[0] == 1: data = aio.voltage_once() byte_data = b''.join(struct.pack('f', d) for d in data) result = {'registers': [0]*16} for i in range(8): result['registers'][2*i+1], result['registers'][2*i] = struct.unpack('H', byte_data[4*i:4*i+2])[0], struct.unpack('H', byte_data[4*i+2:4*i+4])[0] send_data = result['registers'] store.setValues(3,1,send_data) store.setValues(6,0,[0]) except Exception as e: print(f'error input:{e}') await asyncio.sleep(1) async def set_output(store): while True: try: rsp = store.getValues(16,20, count=10) channels = [i + 1 for i, value in enumerate(rsp[:8]) if value != 0] voltages = [value for value in rsp[:8] if value != 0] for ch, vol in zip(channels, voltages): aio.start_output(channel=ch, voltage=vol) store.setValues(16,20,[0]*10) except Exception as e: print(f'error output:{e}') await asyncio.sleep(1) async def stop_output(store): while True: try: rsp = store.getValues(16,30, count=10) channels = [i + 1 for i, value in enumerate(rsp[:8]) if value == 0] for ch in channels: aio.stop_output(channel=ch) store.setValues(16,30,[2]*10) except Exception as e: print(f'error stp[]:{e}') await asyncio.sleep(1) async def set_cal(store): while True: try: rsp = store.getValues(16,40, count=1) if rsp[0] == 0: aio.calibration('AO') elif rsp[0] == 1: aio.calibration('AI') store.setValues(16,40,[2]*6) except Exception as e: print(f'error:{e}') await asyncio.sleep(1) def exit_handler(signum, frame): global aio if aio is not None: del aio sys.exit(0) if __name__ == "__main__": aio = comm_m4.AIO() signal.signal(signal.SIGINT, exit_handler) coil_block = ModbusSequentialDataBlock(0, [0] * 100) holding_block = ModbusSequentialDataBlock(0, [0]*30 + [2]*16 + [0]*(100-36)) store = ModbusSlaveContext( co=coil_block, hr=holding_block ) context = ModbusServerContext(slaves=store, single=True) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(run_server())