Доработка. Добавлен обмен по Ethernet (JSON) для сервера modbus.

This commit is contained in:
MaD_CaT
2024-10-22 15:15:10 +03:00
parent 0df078f1d6
commit 044e83492b
2 changed files with 63 additions and 1 deletions

View File

@@ -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)

View File

@@ -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': 'ошибка: чтение регистров входов не выполнено',
'<unknown>': 'ошибка: получена неверная команда'
}
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'] = '<unknown>'
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)