diff --git a/project.godot b/project.godot index fa8a97d8..33b7b088 100644 --- a/project.godot +++ b/project.godot @@ -62,6 +62,7 @@ mercator="*res://scripts/mercator.gd" modbus="*res://scripts/modbus.gd" tcp5p28="*res://scripts/tcp5p28.gd" sch3="*res://scripts/sch3.gd" +spt25="*res://scripts/spt25.gd" [debug] diff --git a/scripts/repnetwork.gd b/scripts/repnetwork.gd index 21d34583..f6155014 100644 --- a/scripts/repnetwork.gd +++ b/scripts/repnetwork.gd @@ -3,6 +3,12 @@ class_name rep_network extends Node const PROTOCOL_TYPES: = {'yau07tx': yau07.YaU07, 'json-capsrpb': capsrpb.CapsRpb, 'udp-json-mbcs': modbus.ModbusClient} const TCP_PROTO: = {'5p28': tcp5p28.TCP5P28} +const SERIAL_PROTO: = {'uart': spt25.SPT25 } + + +class Serial extends SerialPort: + pass + class Socket extends PacketPeerUDP: func send_to(addr, data): @@ -32,6 +38,8 @@ var poll_sockets: Array[Socket] var tcp_sockets: Array var units: Dictionary var units_tcp: Dictionary +var units_serial: Dictionary +var serials: Dictionary var dst_ports: Dictionary var unit_keys: Dictionary var sock_unicast: Socket @@ -62,6 +70,19 @@ func create_tcpsocket(nm) -> SocketTCP: return sock +func create_serial(nm) -> SerialPort: + var port = repsettings.UnitProfiles[nm][1] + var baud = repsettings.UnitProfiles[nm][2][0] + var sp: = SerialPort.new() + sp.baudrate = baud + var rc = sp.open(port) + if rc != Error.OK: + log.message(log.ERROR, 'Невозможно открыть порт \"%s\" для \"%s\"' % [port, nm]) + return null + log.message(log.INFO, 'Последовательный порт \"%s\"@%d открыт для \"%s\"' % [port, baud, nm]) + return sp + + func _ready() -> void: log.info('Модуль работы с сетью готов') poll_sockets.append(create_socket('уарэп-яу07-частный')) @@ -94,6 +115,19 @@ func _ready() -> void: unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key)) unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key)) + if proto in SERIAL_PROTO: + var unit = SERIAL_PROTO[proto].new(unit_name) + var unit_key = repsettings.get_unit_key(unit_name) + if logger_page: + unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key)) + unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key)) + var serial = create_serial(unit_name) + if serial: + units_serial[unit_key] = unit + serials[unit_key] = serial + serial.data_received.connect(unit.parse) + serial.start_monitoring(20000) + tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp[repsettings.get_unit_key('уарэп-5п28')]]) for key in units: log.info('%s %s:%d' % [units[key].name, key[0], key[1]]) @@ -167,6 +201,12 @@ func _process(_delta: float) -> void: match unit.process(tick): Error.OK: sock_unicast.send_to([addr[0], dst_ports[addr]], unit.tx_data) Error.FAILED: emit_signal('socket_error', 'ошибка: %s %s:%d' % [unit, addr[0], addr[1]]) + for key in units_serial: + var unit = units_serial[key] + var serial = serials[key] + match unit.process(tick): + Error.OK: serial.write_str(unit.tx_data) + Error.FAILED: emit_signal('socket_error', 'ошибка: \"%s\"' % unit.name) for sock_unit in tcp_sockets: var sock = sock_unit[0] var unit = sock_unit[1] diff --git a/scripts/signaller.gd b/scripts/signaller.gd index c459e2af..b8b8a8da 100644 --- a/scripts/signaller.gd +++ b/scripts/signaller.gd @@ -5,6 +5,9 @@ class_name Signaller extends Node func conn(sgnl: Signal, clbl: Callable): connect(sgnl.get_name(), clbl) +## Вызывается при +signal serial_error() + ## Вызывается при переходе в режим [b]Работа[/b]. signal режим_работа() diff --git a/scripts/spt25.gd b/scripts/spt25.gd new file mode 100644 index 00000000..aecf7001 --- /dev/null +++ b/scripts/spt25.gd @@ -0,0 +1,18 @@ +extends Node + +class SPT25: + signal line_changed(unit: SPT25) ## Вызывается когда меняется состояние связи + signal command_done(unit: SPT25) ## Вызывается после выполнения команды. + signal command_fail(unit: SPT25) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена. + signal parse_failed(unit: SPT25) ## Вызывается при обнаружении ошибки во входных данных + var online: bool + var name: String + func process(delta: float): pass + func _init(nm) -> void: self.name = nm + func _to_string() -> String: return String('СПТ-25: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]]) + + func parse(rx_data: PackedByteArray): + print_debug(rx_data) + if not self.online: + self.online = true + emit_signal('line_changed', self)