74 lines
3.4 KiB
Python
74 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Имитатор сервера Modbus Serial прибора Щ3.
|
|
Использовать для отладки. Только сохраняет данные регистров.
|
|
"""
|
|
|
|
import logger
|
|
import os
|
|
import argparse
|
|
from pymodbus.server.sync import StartSerialServer
|
|
from pymodbus.datastore import ModbusSlaveContext
|
|
from pymodbus.datastore import ModbusServerContext
|
|
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('setValues() fx:%s address:%s values:%s' % (fx, address, 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('getValues() fx:%s address:%s values:%s' % (fx, address, values))
|
|
return values
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
parser.add_argument('--serial-baud', default=115200, type=int, help='Скорость последовательного порта, бод')
|
|
parser.add_argument('--serial-port', default=DEF_SERIAL, type=str, help='Последовательный порт для подключения клиента')
|
|
parser.add_argument('--timeout', default=0.005, type=str, help='Таймаут последовательного порта')
|
|
opts, opts_unk = parser.parse_known_args()
|
|
print_opts_error(opts_unk)
|
|
store = CallbackModbusSlaveContext()
|
|
context = ModbusServerContext(slaves=store, single=True)
|
|
log.info("серевер-заглушка Modbus serial работает: %s:%d" % (opts.serial_port, opts.serial_baud))
|
|
StartSerialServer(context=context, framer=ModbusRtuFramer, port=opts.serial_port, timeout=opts.timeout, baudrate=opts.serial_baud)
|
|
|
|
|
|
def print_opts_error(opts: list) -> None:
|
|
for opt in opts:
|
|
log.debug('внимание: неизвестный аргумент: \"%s\"\n' % opt)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|