From 58c5ed86e586fe65afb4b53b0139a2530321b0eb Mon Sep 17 00:00:00 2001 From: sasha80 Date: Wed, 27 Aug 2025 08:55:27 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80.=20=D0=A1=D0=B5=D1=82=D0=B5=D0=B2=D0=BE=D0=B9=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=B4=D1=83=D0=BB=D1=8C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/network.gd | 166 +++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 80 deletions(-) diff --git a/scripts/network.gd b/scripts/network.gd index df7532b..7a9d7a0 100644 --- a/scripts/network.gd +++ b/scripts/network.gd @@ -34,8 +34,8 @@ class Serial extends SerialPort: return Error.OK -class Socket extends PacketPeerUDP: - func send_to(addr, data): +class SocketUDP extends PacketPeerUDP: + func send_to(addr: Array, data: PackedByteArray): set_dest_address(addr[0], addr[1]) var rc: = put_packet(data) if rc != Error.OK: @@ -45,7 +45,7 @@ class Socket extends PacketPeerUDP: class SocketTCP extends TCPServer: const RX_TIMEOUT: int = 1000 ## Время сброса счётчика принятия части пакета. var peerstream: = PacketPeerStream.new() - var unit_key: StringName ## Ключ юнита. + var unit_name: StringName ## Уникальное имя устройства var head_len: int = 8 ## Длина заголовка команды. var len_place: int = 4 ## Номер начального байта с длинной блока данных. var type_len: int = 4 ## Количество байт в размере длинны. @@ -55,52 +55,53 @@ class SocketTCP extends TCPServer: var rx_data: PackedByteArray ## Принятые данные. var data_len: int ## Размер ожидаемых данных. - func send_to(data): + func send_to(data: PackedByteArray): var peer = peerstream.get_stream_peer() peer.put_data(data) -var poll_sockets: Array[Socket] -var tcp_sockets: Array[Array] -var units: Dictionary[StringName, unit.Unit] -var units_udp: Dictionary[StringName, unit.Unit] -var units_udprx: Dictionary[StringName, unit.Unit] -var units_tcp: Dictionary[StringName, unit.Unit] -var units_serial: Dictionary[StringName, unit.Unit] -var units_modbus: Dictionary[StringName, unit.Unit] -var serials: Dictionary[StringName, Serial] # Последовательные порты -var mbcs: Dictionary[StringName, unit.Unit] # Клиенты modbus -var dst_ports: Dictionary[StringName, int] -var dst_addrs: Dictionary[StringName, StringName] -var unit_keys: Dictionary[int, StringName] -var sock_unicast: Socket -var sock_capsrpb: Socket -var logger_page: Node -var send_sockets: Dictionary[StringName, Socket] # Таблица <имяустройста>: <сокет> для отправки сообщений -var addr_port_to_unit_name: Dictionary[StringName, StringName] +var poll_sockets: Array[SocketUDP] ## Сокеты для непрерывного опроса наличия новых данных +var tcp_sockets: Array[Array] ## Сокеты для TCP-соединений +var units: Dictionary[StringName, unit.Unit] ## Экземпляры всех сетевых устройств +var units_udp: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с udp-соединением которым нужно передавать данные +var units_udprx: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с udp-соединением от которых приходят данные +var units_tcp: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с tcp-соединением +var units_serial: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с uart-соединением +var units_modbus: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с modbusserial-соединением +var serials: Dictionary[StringName, Serial] ## Последовательные порты (uart) +var dst_ports: Dictionary[StringName, int] ## Преобразование имя устройства в порт назначения +var dst_addrs: Dictionary[StringName, StringName] ## Преобразование имя устройства в адрес назначения +var unit_keys: Dictionary[int, StringName] ## Преобразование порта назначения в имя устройства +var sock_unicast: SocketUDP ## Сокет для приёма широковещательных сообщений от ЯУ-07 +var sock_capsrpb: SocketUDP ## Сокет для приёма сообщений от КАСПРПБ +var logger_page: Node ## Ссылка на журнал работы +var send_sockets: Dictionary[StringName, SocketUDP] ## Таблица <имяустройста>: <сокет> для отправки сообщений +var addr_port_to_unit_name: Dictionary[StringName, StringName] ## Преобразование адрес:порт в имя устройства func on_serial_data(data, unit): unit.parse(data, tick) -func create_socket(nm) -> Socket: - var addr = settings.UnitProfiles[nm][1] - var port = settings.UnitProfiles[nm][2][0] - var broad = settings.UnitProfiles[nm][3] - var bind = settings.UnitProfiles[nm][4] - var sock: = Socket.new() +## [param unit_name] - Уникальное имя устройства[br] +func create_socket_udp(unit_name: StringName) -> SocketUDP: + var addr = settings.UnitProfiles[unit_name][1] + var port = settings.UnitProfiles[unit_name][2][0] + var broad = settings.UnitProfiles[unit_name][3] + var bind = settings.UnitProfiles[unit_name][4] + var sock: = SocketUDP.new() sock.set_broadcast_enabled(broad) var rc = Error.OK if not bind else sock.bind(port, addr) var errlevel = log.INFO if rc == Error.OK else log.ERROR - log.message(errlevel, '\"%s\" привязан к %s:%d? - %s, результат: %s' % [nm, addr, port, ['нет', 'да'][int(bind)], error_string(rc)]) + log.message(errlevel, '\"%s\" привязан к %s:%d? - %s, результат: %s' % [unit_name, addr, port, ['нет', 'да'][int(bind)], error_string(rc)]) return sock -func create_tcpsocket(unit_name: StringName) -> SocketTCP: +## [param unit_name] - Уникальное имя устройства[br] +func create_socket_tcp(unit_name: StringName) -> SocketTCP: var addr = settings.UnitProfiles[unit_name][1] var port = settings.UnitProfiles[unit_name][2][0] var sock: = SocketTCP.new() - sock.unit_key = unit_name + sock.unit_name = unit_name var rc: = sock.listen(port, addr) if rc == Error.OK: log.message(log.INFO, '\"%s\" слушает на %s:%d' % [unit_name, addr, port]) @@ -109,26 +110,28 @@ func create_tcpsocket(unit_name: StringName) -> SocketTCP: return sock -func create_serial(nm) -> Serial: - var port = settings.UnitProfiles[nm][1] - var baud = settings.UnitProfiles[nm][2][0] - var sp: = Serial.new() - sp.port = port - sp.baudrate = baud - sp.timeout = 20000 - return sp +## [param unit_name] - Уникальное имя устройства[br] +func create_serial(unit_name: StringName) -> Serial: + var port = settings.UnitProfiles[unit_name][1] + var baud = settings.UnitProfiles[unit_name][2][0] + var serial: = Serial.new() + serial.port = port + serial.baudrate = baud + serial.timeout = 20000 + return serial -func create_modbus(nm) -> sch_3.Sch3: - var unit_sch3: = sch_3.Sch3.new(nm) - return unit_sch3 +## [param unit_name] - Уникальное имя устройства[br] +func create_modbus(unit_name: StringName) -> sch_3.Sch3: + var unit_modbus: = sch_3.Sch3.new(unit_name) + return unit_modbus 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('навигация')) + poll_sockets.append(create_socket_udp('уарэп-яу07-частный')) + poll_sockets.append(create_socket_udp('уарэп-яу07-общий')) + poll_sockets.append(create_socket_udp('уарэп-капсрпб')) + poll_sockets.append(create_socket_udp('навигация')) sock_unicast = poll_sockets[0] sock_capsrpb = poll_sockets[2] @@ -153,28 +156,28 @@ func _ready() -> void: var bind_modbuses: = [] for unit_name in settings.UnitProfiles: - var st = settings.UnitProfiles[unit_name] - var proto = st[0] + var unit_profile = settings.UnitProfiles[unit_name] + var proto = unit_profile[0] if proto in UDPRX_PROTO: var new_unit = UDPRX_PROTO[proto].new(unit_name) units[unit_name] = new_unit units_udprx[unit_name] = new_unit - dst_ports[unit_name] = st[2][0] + dst_ports[unit_name] = unit_profile[2][0] if proto in UDPTX_PROTO: var new_unit = UDPTX_PROTO[proto].new(unit_name) units[unit_name] = new_unit units_udp[unit_name] = new_unit - dst_ports[unit_name] = st[2][0] - dst_addrs[unit_name] = st[1] + dst_ports[unit_name] = unit_profile[2][0] + dst_addrs[unit_name] = unit_profile[1] if proto in UDPJSON_PROTO: var new_unit = UDPJSON_PROTO[proto].new(unit_name) units[unit_name] = new_unit units_udp[unit_name] = new_unit - dst_ports[unit_name] = st[2][1] - dst_addrs[unit_name] = st[1] + dst_ports[unit_name] = unit_profile[2][1] + dst_addrs[unit_name] = unit_profile[1] if proto in TCP_PROTO: var unit_tcp = TCP_PROTO[proto].new(unit_name) @@ -183,22 +186,22 @@ func _ready() -> void: if proto in MODBUS_PROTO: var unit_modbus = MODBUS_PROTO[proto].new(unit_name) - unit_modbus.port = settings.UnitProfiles[unit_name][1] # TODO: убрать это отсюда (обращение к глобальным данным из экземпляра) - unit_modbus.params = settings.UnitProfiles[unit_name][2] # TODO: убрать это отсюда (обращение к глобальным данным из экземпляра) + unit_modbus.port = unit_profile[1] + unit_modbus.params = unit_profile[2] units[unit_name] = unit_modbus units_modbus[unit_name] = unit_modbus bind_modbuses.append([unit_modbus, unit_name]) if proto in SERIAL_PROTO: var unit_serial = SERIAL_PROTO[proto].new(unit_name) - var serial = create_serial(unit_name) + var serial: = create_serial(unit_name) units_serial[unit_name] = unit_serial units[unit_name] = unit_serial serials[unit_name] = serial ProjectSettings.connect('settings_changed', Callable(self, '_on_settings_changed_serial').bind(bind_serials)) - tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp['уарэп-5п28']]) + tcp_sockets.append([create_socket_tcp('уарэп-5п28'), units_tcp['уарэп-5п28']]) for key: StringName in dst_ports: unit_keys[dst_ports[key]] = key if logger_page: @@ -235,7 +238,7 @@ func _on_settings_changed_serial(bind_serials: Array): log.message(log.INFO, '%s для \"%s\"' % [serial, unit_name]) -func poll_receive_udp(sock: Socket) -> bool: +func poll_receive_udp(sock: SocketUDP) -> bool: while sock.get_available_packet_count() > 0: var data: = sock.get_packet() var addr: = sock.get_packet_ip() @@ -246,9 +249,9 @@ func poll_receive_udp(sock: Socket) -> bool: units[unit_name].parse(data, tick) continue if unit_keys.has(port): - var unit_key: = unit_keys[port] - if units.has(unit_key): - units[unit_key].parse(data, tick) + var unit_name: = unit_keys[port] + if units.has(unit_name): + units[unit_name].parse(data, tick) continue var local_port: = sock.get_local_port() if unit_keys.has(local_port): @@ -267,15 +270,17 @@ func poll_receive_tcp(sock: SocketTCP) -> bool: log.info('подключен: %s:%d к порту: %d' % [ client.get_connected_host(), client.get_connected_port(), client.get_local_port() ] ) var peer = sock.peerstream.get_stream_peer() if peer: - var peer_len_data = peer.get_available_bytes() - if peer_len_data > 0: - get_client_data(sock, peer_len_data, peer) - if sock.unit_key in units_tcp and sock.rx_all: - units_tcp[sock.unit_key].parse(sock.rx_data, tick) + while true: + var peer_len_data: = peer.get_available_bytes() + if peer_len_data <= 0: + break + get_client_data(sock, peer, peer_len_data) + if sock.unit_name in units_tcp and sock.rx_all: + units_tcp[sock.unit_name].parse(sock.rx_data, tick) return false -func get_client_data(sock: SocketTCP, peer_len_data, peer): +func get_client_data(sock: SocketTCP, peer: StreamPeer, peer_len_data: int) -> void: if tick - sock.rx_tick > sock.RX_TIMEOUT: sock.rx_all = true sock.rx_tick = tick @@ -299,35 +304,35 @@ func get_client_data(sock: SocketTCP, peer_len_data, peer): get_tcp_data(sock, peer, len_rx) -func get_tcp_data(sock: SocketTCP, peer, len_rx): +func get_tcp_data(sock: SocketTCP, peer: StreamPeer, len_rx: int): var temp_data = peer.get_data(len_rx)[1] sock.rx_data.append_array(temp_data) sock.rx_len += len_rx - if sock.rx_len >= sock.head_len + sock.data_len: + if sock.rx_len == sock.head_len + sock.data_len: sock.rx_all = true func _process(_delta: float) -> void: tick = Time.get_ticks_msec() RenderingServer.global_shader_parameter_set('tick_curent', tick) - for key: StringName in units_udp: - var unit_udp: = units_udp[key] + for unit_name: StringName in units_udp: + var unit_udp: = units_udp[unit_name] if Error.OK == unit_udp.process(tick): var sock: = send_sockets[unit_udp.name] var tx_data: = unit_udp.tx_data.slice(0, unit_udp.tx_len) - var dst_port: = dst_ports[key] - var dst_addr: = dst_addrs[key] + var dst_port: = dst_ports[unit_name] + var dst_addr: = dst_addrs[unit_name] sock.send_to([dst_addr, dst_port], tx_data) - for key: StringName in units_udprx: - var unit_udprx: = units_udprx[key] + for unit_name: StringName in units_udprx: + var unit_udprx: = units_udprx[unit_name] unit_udprx.process(tick) - for key: StringName in units_serial: - var unit_serial: = units_serial[key] - var serial: = serials[key] + for unit_name: StringName in units_serial: + var unit_serial: = units_serial[unit_name] + var serial: = serials[unit_name] if Error.OK == unit_serial.process(tick): serial.send_to(unit_serial.tx_data) - for key: StringName in units_modbus: - var unit_modbus: = units_modbus[key] + for unit_name: StringName in units_modbus: + var unit_modbus: = units_modbus[unit_name] unit_modbus.process(tick) for sock_unit: Array in tcp_sockets: var sock = sock_unit[0] @@ -338,6 +343,7 @@ func _process(_delta: float) -> void: poll_sockets.any(poll_receive_udp) +## [param unit_name] - Уникальное имя устройства[br] func get_unit_instance(unit_name: StringName) -> unit.Unit: tools.allways(unit_name in units, 'нет такого устройства: \"%s\"' % unit_name) return units[unit_name]