From 92a79ce7eb8d3a6d2a82c02af4cdf0bcc9994338 Mon Sep 17 00:00:00 2001 From: rluan Date: Thu, 23 Dec 2021 23:21:39 +0800 Subject: [PATCH] a workable version on python3.7, fixed some bug --- modbus_simulator/main.py | 2 +- modbus_simulator/ui/gui.py | 4 ++-- modbus_simulator/utils/modbus.py | 37 +++++++++++++++++++++++++++++--- requirements | 5 +++-- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/modbus_simulator/main.py b/modbus_simulator/main.py index 793e21e..0164f34 100755 --- a/modbus_simulator/main.py +++ b/modbus_simulator/main.py @@ -15,7 +15,7 @@ @click.command() @click.option("-p", is_flag=True, help="use pymodbus as modbus backend") def _run(p): - __builtin__.USE_PYMODBUS = p + __builtin__.USE_PYMODBUS = False if "-p" in sys.argv: # cleanup before kivy gets confused sys.argv.remove("-p") diff --git a/modbus_simulator/ui/gui.py b/modbus_simulator/ui/gui.py index 92d105a..0525cdd 100644 --- a/modbus_simulator/ui/gui.py +++ b/modbus_simulator/ui/gui.py @@ -13,7 +13,7 @@ from kivy.uix.settings import SettingsWithSidebar from kivy.uix.listview import ListView, ListItemButton from kivy.adapters.listadapter import ListAdapter -from modbus_simulator.utils.constants import BLOCK_TYPES +from modbus_simulator.utils.constants import BLOCK_TYPES, ADDRESS_RANGE from modbus_simulator.utils.common import configure_modbus_logger from modbus_simulator.ui.settings import SettingIntegerWithRange from modbus_simulator.utils.backgroundJob import BackgroundJob @@ -688,7 +688,7 @@ def refresh(self): def update_backend(self, slave_id, blockname, new_data): self.modbus_device.remove_block(slave_id, blockname) self.modbus_device.add_block(slave_id, blockname, - BLOCK_TYPES[blockname], 0, + BLOCK_TYPES[blockname], ADDRESS_RANGE[BLOCK_TYPES[blockname]], self.block_size) for k, v in new_data.items(): if blockname in ['holding_registers', 'input_registers']: diff --git a/modbus_simulator/utils/modbus.py b/modbus_simulator/utils/modbus.py index a5b7de3..ba78b28 100644 --- a/modbus_simulator/utils/modbus.py +++ b/modbus_simulator/utils/modbus.py @@ -9,8 +9,11 @@ COILS, DISCRETE_INPUTS, HOLDING_REGISTERS, ANALOG_INPUTS) from modbus_tk.modbus_rtu import RtuServer, RtuMaster from modbus_tk.modbus_tcp import TcpServer, TcpMaster +from pymodbus.constants import Endian +from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder from modbus_simulator.utils.common import path, make_dir, remove_file +from modbus_simulator.utils.pymodbus_server import DECODERS, ENCODERS ADDRESS_RANGE = { COILS: 0, @@ -90,7 +93,10 @@ def __init__(self, server="tcp", *args, **kwargs): kwargs['serial'] = self._serial.ser else: kwargs['port'] = int(kwargs['port']) - self.server = SERVERS.get(server, None)(*args, **kwargs) + if server == "tcp": + self.server = TcpServer(*args, port=kwargs['port'],address=kwargs['address']) + else: + self.server = SERVERS.get(server, None)(*args, **kwargs) self.simulate = kwargs.get('simulate', False) @property @@ -124,11 +130,11 @@ def remove_all_blocks(self, slave_id): def set_values(self, slave_id, block_name, address, values): slave = self.server.get_slave(slave_id) - slave.set_values(block_name, address, values) + slave.set_values(block_name, int(address), values) def get_values(self, slave_id, block_name, address, size=1): slave = self.server.get_slave(slave_id) - return slave.get_values(block_name, address, size) + return slave.get_values(block_name, int(address), size) def start(self): self.server.start() @@ -145,6 +151,31 @@ def get_slaves(self): if self.server is not None: return self.server._databank._slaves + def decode(self, slave_id, block_name, offset, formatter): + count = 1 + offset = int(offset) + if '32' in formatter: + count = 2 + elif '64' in formatter: + count = 4 + values = self.get_values(slave_id, block_name, offset, count) + values = list(values) + if values: + decoder = BinaryPayloadDecoder.fromRegisters( + values, byteorder=Endian.Big, wordorder=Endian.Big) + values = getattr(decoder, DECODERS.get(formatter))() + return values, count + + def encode(self, slave_id, block_name, offset, value, formatter): + builder = BinaryPayloadBuilder(byteorder=Endian.Big, + wordorder=Endian.Big) + add_method = ENCODERS.get(formatter) + if 'int' in add_method: # Temp fix + value = int(value) + getattr(builder, add_method)(value) + payload = builder.to_registers() + return self.set_values(slave_id, block_name, int(offset), payload) + def swap_bytes(byte_array): temp = [] diff --git a/requirements b/requirements index 067a8d7..345c266 100644 --- a/requirements +++ b/requirements @@ -7,6 +7,7 @@ pygame==1.9.4 pyglet==1.2.4 Pygments==2.1.3 pymodbus==2.1.0 -pyserial==3.2.1 +pyserial==3.4 requests==2.12.4 -six==1.10.0 +six==1.11.0 +modbus-tk==1.1.2 \ No newline at end of file