From 044e83492bfa18852b1fda648052e01d6653a7ff Mon Sep 17 00:00:00 2001 From: MaD_CaT Date: Tue, 22 Oct 2024 15:15:10 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0.=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BE=D0=B1=D0=BC=D0=B5=D0=BD=20=D0=BF=D0=BE=20Ethern?= =?UTF-8?q?et=20(JSON)=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=20modbus.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modbus/logger.py | 2 +- modbus/server-serial-modbus.py | 62 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/modbus/logger.py b/modbus/logger.py index 548dd40..3f57212 100644 --- a/modbus/logger.py +++ b/modbus/logger.py @@ -8,7 +8,7 @@ def get_logger(source_file, log_dir='logs'): log_format = '[%(asctime)s] %(module)s:%(lineno)s %(message)s' logging.basicConfig(format=log_format) log = logging.getLogger() - log.setLevel(logging.DEBUG) + log.setLevel(logging.INFO) file_handler = logging.FileHandler(f'{log_dir}/{source_file}.log') file_handler.setFormatter(logging.Formatter(log_format)) log.addHandler(file_handler) diff --git a/modbus/server-serial-modbus.py b/modbus/server-serial-modbus.py index a7fbc52..6333b93 100644 --- a/modbus/server-serial-modbus.py +++ b/modbus/server-serial-modbus.py @@ -7,19 +7,75 @@ import logger import os import argparse +import json +from socket import * from pymodbus.server.sync import StartSerialServer from pymodbus.datastore import ModbusSlaveContext from pymodbus.datastore import ModbusServerContext from pymodbus.transaction import ModbusRtuFramer +from threading import Thread DEF_SERIAL = 'COM2' if os.name == 'nt' else '/dev/tty3' log_file_dir = os.path.join(os.path.expanduser('~')) log = logger.get_logger(__file__, log_file_dir) +EXCEPT_MSGS = { + 'write': 'ошибка: запись в регистры не выполнена', + 'read_holding': 'ошибка: чтение регистров хранения не выполнено', + 'read_input': 'ошибка: чтение регистров входов не выполнено', + '': 'ошибка: получена неверная команда' +} + +MAIN_ADDR = ('localhost', 44103) +DST_ADDR = ('localhost', 44203) + +""" Адрес получателя """ FX_CODES = {2: 'di', 4: 'ir', 3: 'hr', 6: 'hr', 16: 'hr', 22: 'hr', 23: 'hr', 1: 'co', 5: 'co', 15: 'co'} """ Кодировка регистров в pymodbus """ +def on_rcv(*args): + store = args[0] + sock = store.sock_udp + dst_addr = store.dst_addr + + json_decoder = json.JSONDecoder() + json_encoder = json.JSONEncoder() + while True: + udp_data = sock.recv(2048) # Ждать команду от приложения + udp_data = udp_data.decode('utf-8') + message = json_decoder.decode(udp_data) # type: dict + + if 'code' not in message: + message['code'] = '' + + if 'data' not in message: + message['data'] = [] + + if message['code'] == 'write': + data = message['data'] + store.setValues(3, data[0], data[1:]) + tx_data = json_encoder.encode({'code': 'response', 'data': ''}) + sock.sendto(bytes(tx_data, 'utf-8'), dst_addr) + elif message['code'] == 'write_input': + data = message['data'] + store.setValues(4, data[0], data[1:]) + tx_data = json_encoder.encode({'code': 'response', 'data': ''}) + sock.sendto(bytes(tx_data, 'utf-8'), dst_addr) + elif message['code'] == 'read_holding': + data = message['data'] + read_data = store.getValues(3, data[0], data[1]) + read_data.insert(0, data[0]) + tx_data = json_encoder.encode({'code': 'response', 'data': read_data}) + sock.sendto(bytes(tx_data, 'utf-8'), dst_addr) + elif message['code'] == 'read_input': + data = message['data'] + read_data = store.getValues(4, data[0], data[1]) + read_data.insert(0, data[0]) + tx_data = json_encoder.encode({'code': 'response', 'data': read_data}) + sock.sendto(bytes(tx_data, 'utf-8'), dst_addr) + + class CallbackModbusSlaveContext(ModbusSlaveContext): """ Блок данных, который сохраняет новое значение в памяти и передаёт операцию в очередь сообщений @@ -27,6 +83,10 @@ class CallbackModbusSlaveContext(ModbusSlaveContext): def __init__(self): """ """ + self.dst_addr = DST_ADDR + self.json_enc = json.JSONEncoder() + self.sock_udp = socket(AF_INET, SOCK_DGRAM) + self.sock_udp.bind(MAIN_ADDR) super(CallbackModbusSlaveContext, self).__init__() def setValues(self, fx, address, values): @@ -61,6 +121,8 @@ def main(): store = CallbackModbusSlaveContext() context = ModbusServerContext(slaves=store, single=True) log.info("серевер-заглушка Modbus serial работает: %s:%d" % (opts.serial_port, opts.serial_baud)) + t = Thread(target=on_rcv, args=[store], daemon=True) + t.start() StartSerialServer(context=context, framer=ModbusRtuFramer, port=opts.serial_port, timeout=opts.timeout, baudrate=opts.serial_baud)