Доработка. Приём и отправка сообщений по протоколу modbus.

This commit is contained in:
MaD_CaT
2024-10-15 08:46:48 +03:00
parent 4161bc2ef7
commit 686966a40a
5 changed files with 44 additions and 21 deletions

View File

@@ -10,6 +10,7 @@ import json
import argparse
import time
from socket import *
from threading import Timer
import logger
from pymodbus.client.sync import ModbusSerialClient
@@ -25,6 +26,15 @@ EXCEPT_MSGS = {
}
def on_timer(*args):
sock = args[0]
json_encoder = args[1]
udp_addr = args[2]
udp_port_tx = args[3]
tx_data = json_encoder.encode({'code': 'info', 'data': 'ok'})
sock.sendto(bytes(tx_data, 'utf-8'), (udp_addr, udp_port_tx))
Timer(1, on_timer, args).start()
def main():
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--modbus-unit', default=1, type=int, help='Номер устройства Modbus')
@@ -52,6 +62,7 @@ def run_sync_client(udp_addr, udp_port_rx, udp_port_tx, serial_port, serial_baud
log.info('подключен к серверу через \"%s\" на скорости %d бод' % (serial_port, serial_baud))
Timer(1, on_timer, [sock, json_encoder, udp_addr, udp_port_tx]).start()
while True:
udp_data = sock.recv(2048) # Ждать команду от приложения
udp_data = udp_data.decode('utf-8')
@@ -69,6 +80,9 @@ def run_sync_client(udp_addr, udp_port_rx, udp_port_tx, serial_port, serial_baud
data = message['data']
rq = client.write_registers(data[0], data[1:], unit=unit_num)
rc = rq.isError()
if not rc:
tx_data = json_encoder.encode({'code': 'response', 'data': ''})
sock.sendto(bytes(tx_data, 'utf-8'), (udp_addr, udp_port_tx))
elif message['code'] == 'read_holding':
data = message['data']
rq = client.read_holding_registers(data[0], data[1], unit=unit_num)
@@ -82,7 +96,7 @@ def run_sync_client(udp_addr, udp_port_rx, udp_port_tx, serial_port, serial_baud
rc = rq.isError()
if not rc:
tx_data = json_encoder.encode({'code': 'response', 'data': rq.registers})
sock.sendto(bytes(tx_data), (udp_addr, udp_port_tx))
sock.sendto(bytes(tx_data, 'utf-8'), (udp_addr, udp_port_tx))
elif message['code'] == '<unknown>':
rc = False
@@ -91,7 +105,7 @@ def run_sync_client(udp_addr, udp_port_rx, udp_port_tx, serial_port, serial_baud
data = message['data']
rc_msg = EXCEPT_MSGS[code]
tx_data = json_encoder.encode({'code': 'exception', 'data': rc_msg})
sock.sendto(bytes(tx_data), (udp_addr, udp_port_tx))
sock.sendto(bytes(tx_data, 'utf-8'), (udp_addr, udp_port_tx))
log.error(
'ошибка при выполнении команды: \"%s\". данные: \"%s\", порт: \"%s\", скорость: %s'
% (code, data, serial_port, serial_baud))

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.INFO)
log.setLevel(logging.DEBUG)
file_handler = logging.FileHandler(f'{log_dir}/{source_file}.log')
file_handler.setFormatter(logging.Formatter(log_format))
log.addHandler(file_handler)

View File

@@ -2,7 +2,6 @@ class_name mod_bus extends Node
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды.
class ModbusClient:
## Состояние автомата выполнения команды.
@@ -24,13 +23,12 @@ class ModbusClient:
static var json_conv: = JSON.new()
signal command_done() ## Вызывается при успешном выполнении команды.
signal command_fail() ## Вызывается при возникновении ошибки во время выполнения команды.
signal line_changed() ## Вызывается при смене состояния связи с ячейкой.
signal command_fail(unit: ModbusClient) ## Вызывается при возникновении ошибки во время выполнения команды.
signal line_changed(unit: ModbusClient) ## Вызывается при смене состояния связи с ячейкой.
signal data_received() ## Вызывается при приёме сообщения, до его разбора.
signal parse_failed(msg: String) ## Вызывается при возникновении ошибки во время разбора пакета. Передаёт сообщение об ошибке.
signal holding_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения.
signal input_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров входов.
signal responce_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения.
signal info_received(msg: String) ## Вызывается при получении информационного сообщения.
signal except_received(msg: String) ## Вызывается при получении сообщения об исключительной ситуации.
@@ -43,10 +41,10 @@ class ModbusClient:
func process(tick: int):
if online and ((tick - tick_rx) > ONLINE_TIMEOUT):
online = false
emit_signal('line_changed')
emit_signal('line_changed', self)
if (cmd_state == CmdState.WAIT) or (cmd_state == CmdState.SEND):
#cmd_state = CmdState.FAIL
emit_signal('command_fail')
cmd_state = CmdState.FAIL
emit_signal('command_fail', self)
var rc = Error.ERR_BUSY
if cmd_state == CmdState.SEND:
rc = Error.OK
@@ -61,7 +59,7 @@ class ModbusClient:
tick_rx = tick
if not online:
online = true
emit_signal('line_changed')
emit_signal('line_changed', self)
var utf8_data = data.get_string_from_utf8()
if Error.OK == json_conv.parse(utf8_data):
emit_signal('data_received')
@@ -71,14 +69,10 @@ class ModbusClient:
var message_code = message['code']
var message_data = message['data']
match message_code:
'read_input':
'response':
var addr = message_data[0]
var regs = message_data.slice(1)
emit_signal('input_received', addr, regs)
'read_holding':
var addr = message_data[0]
var regs = message_data.slice(1)
emit_signal('holding_received', addr, regs)
emit_signal('responce_received', addr, regs)
'info':
var msg = message['data']
emit_signal('info_received', msg)
@@ -95,7 +89,7 @@ class ModbusClient:
emit_signal('command_done')
elif (cmd_state == CmdState.WAIT) and (not rc):
cmd_state = CmdState.FAIL
emit_signal('command_fail')
emit_signal('command_fail', self)
else:
var message = json_conv.get_error_message()
emit_signal('parse_failed', message)
@@ -115,7 +109,7 @@ class ModbusClient:
## [param addr] - Начальный адрес регистров.[br]
## [param count] - Количество регистров от начального адреса.[br]
func read_holdind(addr: int, count: int = 1) -> bool:
#if cmd_state != CmdState.DONE: return false
if cmd_state != CmdState.DONE: return false
var json_dict = {'code': 'read_holding', 'data': [addr, count]}
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
cmd_state = CmdState.SEND

View File

@@ -67,6 +67,7 @@ func _ready() -> void:
poll_sockets.append(create_socket('уарэп-яу07-частный'))
poll_sockets.append(create_socket('уарэп-яу07-общий'))
poll_sockets.append(create_socket('уарэп-капсрпб'))
poll_sockets.append(create_socket('уарэп-щ3'))
sock_unicast = poll_sockets[0]
sock_capsrpb = poll_sockets[2]

View File

@@ -1,13 +1,27 @@
extends Node
var cnt: int = 0
var rw: bool = true
func _ready():
var unit_key = repsettings.get_unit_key('уарэп-щ3')
var unit = repnetwork.units[unit_key]
var timer = Timer.new()
add_child(timer)
unit.connect('command_fail', Callable(self, 'on_command_fail'))
timer.connect('timeout', Callable(self, 'on_timer').bind(unit))
timer.start(1.0)
func on_timer(unit):
unit.read_holdind(0x0000)
cnt +=1
if rw:
unit.write(0x0000, [cnt])
else:
unit.read_holdind(0x0000)
rw = not rw
func on_command_fail(unit):
unit.cmd_state = unit.CmdState.DONE
print_debug('on_command_fail')