Доработка. Добавлен имитатор сервера Modbus Serial прибора Щ3
This commit is contained in:
76
modbus/server-rtu.py
Normal file
76
modbus/server-rtu.py
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Имитатор сервера Modbus Serial прибора Щ3.
|
||||
Использовать для отладки.
|
||||
"""
|
||||
|
||||
import logger
|
||||
import os
|
||||
import argparse
|
||||
from pymodbus.server.sync import StartSerialServer
|
||||
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext, ModbusSparseDataBlock
|
||||
from pymodbus.transaction import ModbusRtuFramer
|
||||
|
||||
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)
|
||||
|
||||
FX_CODES = {2: 'di', 4: 'ir', 3: 'hr', 6: 'hr', 16: 'hr', 22: 'hr', 23: 'hr', 1: 'co', 5: 'co', 15: 'co'}
|
||||
""" Кодировка регистров в pymodbus """
|
||||
|
||||
|
||||
class CallbackModbusSlaveContext(ModbusSlaveContext):
|
||||
""" Блок данных, который сохраняет новое значение
|
||||
в памяти и передаёт операцию в очередь сообщений
|
||||
для дальнейшей процедуры обработки. """
|
||||
|
||||
def __init__(self):
|
||||
""" """
|
||||
super(CallbackModbusSlaveContext, self).__init__()
|
||||
|
||||
def setValues(self, fx, address, values):
|
||||
""" Устанавливает требуемые значения хранилища данных.
|
||||
:param fx:
|
||||
:param address: Начальный адрес.
|
||||
:param values: Новые значения, которые необходимо установить.
|
||||
"""
|
||||
super(CallbackModbusSlaveContext, self).setValues(fx, address, values)
|
||||
fx = FX_CODES[fx] if fx in FX_CODES else '**error**'
|
||||
log.debug(f'setValues() fx:{fx} address:{address} values:{values}')
|
||||
|
||||
def getValues(self, fx, address, count=1):
|
||||
""" Устанавливает требуемые значения хранилища данных.
|
||||
:param fx:
|
||||
:param address: Начальный адрес
|
||||
:param count:
|
||||
"""
|
||||
values = super(CallbackModbusSlaveContext, self).getValues(fx, address, count)
|
||||
fx = FX_CODES[fx] if fx in FX_CODES else '**error**'
|
||||
log.debug(f'getValues() fx:{fx} address:{address} values:{values}')
|
||||
return values
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument('-modbus-unit', default=1, type=int, help='Номер устройства Modbus')
|
||||
parser.add_argument('-serial-baud', default=115200, type=int, help='Скорость последовательного порта, бод')
|
||||
parser.add_argument('-serial-port', default=DEF_SERIAL, type=str, help='Последовательный порт для подключения клиента Modbus ')
|
||||
opts, opts_unk = parser.parse_known_args()
|
||||
print_opts_error(opts_unk)
|
||||
run_server(opts.serial_port, opts.serial_baud)
|
||||
|
||||
|
||||
def run_server(serial_port, serial_baud):
|
||||
store = CallbackModbusSlaveContext()
|
||||
context = ModbusServerContext(slaves=store, single=True)
|
||||
# timeout=.005 - нужно обязательно указать, иначе не работает
|
||||
StartSerialServer(context=context, framer=ModbusRtuFramer, port=serial_port, timeout=.005, baudrate=serial_baud)
|
||||
|
||||
|
||||
def print_opts_error(opts: list) -> None:
|
||||
for opt in opts:
|
||||
log.debug('внимание: неизвестный аргумент: \"%s\"\n' % opt)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SERIAL_PORT2="/home/$(whoami)/tty2" # Порт для подключения драйвера клиента
|
||||
SERIAL_PORT3="/home/$(whoami)/tty3" # Порт для подключения сервера Modbus
|
||||
SERIAL_PORT3="/home/$(whoami)/tty3" # Порт для подключения сервера Modbus Serial (Прибор Щ3)
|
||||
UDP_ADDR="localhost"
|
||||
UDP_PORT_RX="44100"
|
||||
UDP_PORT_TX="48000"
|
||||
@@ -50,6 +50,12 @@ fi
|
||||
# \---------------------------------------------------------------------------------/
|
||||
|
||||
|
||||
# /---------------------------------------------------------------------------------\
|
||||
# Запустить сервер Modbus Serial (Прибор Щ3)
|
||||
xterm -geometry 120x5 -fa Monospace -fs 12 -hold -T "Сервер Modbus Serial Щ3 \"${SERIAL_PORT3}\"" -e "python3 server-rtu.py -serial-port ${SERIAL_PORT3}" &
|
||||
# \---------------------------------------------------------------------------------/
|
||||
|
||||
|
||||
# /---------------------------------------------------------------------------------\
|
||||
# Запустить драйвер клиента Modbus
|
||||
xterm -geometry 120x5 -fa Monospace -fs 12 -hold -T "Драйвер клиента Modbus Serial \"${SERIAL_PORT2} ${UDP_ADDR}:${UDP_PORT_RX}\"" -e "python3 client-serial-tcp.py -serial-port ${SERIAL_PORT2} -udp-addr ${UDP_ADDR} -udp-port-rx ${UDP_PORT_RX} -udp-port-tx ${UDP_PORT_TX}" &
|
||||
|
||||
Reference in New Issue
Block a user