diff --git a/scripts/network.gd b/scripts/network.gd index 3f1f11f2..9e4d8fdf 100644 --- a/scripts/network.gd +++ b/scripts/network.gd @@ -20,31 +20,43 @@ class SocketSerial extends SerialPort: 'N': SerialPort.PARITY_NONE, 'E': SerialPort.PARITY_EVEN, 'O': SerialPort.PARITY_ODD } + static var tick: int - var tx_buffer: PackedByteArray + func on_serial_data(data: PackedByteArray, unit_instance: unit.Unit): + unit_instance.parse(data, tick) - func _init() -> void: - tx_buffer.resize(256) + func on_settings_changed(unit_instance: unit.Unit): + var external_ctl = ProjectSettings.get_setting('application/config/Внешнее управление', false) + try_close() + if external_ctl: + return + var rc = try_open(on_serial_data.bind(unit_instance)) + if rc != Error.OK: + log.message(log.ERROR, 'невозможно открыть %s для \"%s\"' % [self, unit_instance.name]) + else: + log.message(log.INFO, '%s для \"%s\"' % [self, unit_instance.name]) - func send_to(data: PackedByteArray): - """tx_buffer[0] = 0x7e + func format_buffer(data: PackedByteArray): + var buffer: PackedByteArray + buffer.resize(64) var i: = 1 for v in data: if v != 0x7e: - tx_buffer[i] = v - i += 1 + buffer[i] = v; i += 1 else: - tx_buffer[i] = FLAG - i += 1 - tx_buffer[i] = FLAG ^ FLAG_MASK - i += 1 + buffer[i] = FLAG; i += 1 + buffer[i] = FLAG ^ FLAG_MASK; i += 1 var v_sum: = get_check_sum(data) - tx_buffer.encode_u16(i, v_sum) - i += 2 - tx_buffer[i] = FLAG - i += 1""" + buffer.encode_u16(i, v_sum); i += 2 + buffer[i] = FLAG; i += 1 + buffer.resize(i) + return buffer + + func send_to(data: PackedByteArray): + if not is_open(): return + # var buffer = format_buffer(data) # Не проверено, но должно работать # Эта последовательность для запроса состояния, получена от разработчиков СПТ-25 - const tx_tula = [0x7e, 0x01, 0x04, 0xbb, 0x50, 0x7e] + const tx_tula: = [0x7e, 0x01, 0x04, 0xbb, 0x50, 0x7e] write_raw(tx_tula) func _to_string() -> String: return 'последовательный порт \"%s\" @ %d (%s)' % [self.port, self.baudrate, 'открыт' if is_open() else 'закрыт'] @@ -129,9 +141,6 @@ 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) - - ## [param unit_name] - Уникальное имя устройства[br] func create_socket_udp(unit_name: StringName) -> SocketUDP: var st = settings.UnitProfiles[unit_name][1] @@ -192,6 +201,10 @@ func create_serial(unit_name: StringName) -> SocketSerial: return serial +func on_serial_got_error(where: String, what: String, serial: SocketSerial, unit_instance: unit.Unit): + push_error([where, what, serial]) + + ## [param unit_name] - Уникальное имя устройства[br] func create_modbus(unit_name: StringName) -> sch_3.Sch3: var unit_modbus: = sch_3.Sch3.new(unit_name) @@ -266,18 +279,19 @@ func _ready() -> void: bind_modbuses.append([unit_modbus, unit_name]) if proto in SERIAL_PROTO: - var unit_serial = SERIAL_PROTO[proto].new(unit_name) + var unit_instance = SERIAL_PROTO[proto].new(unit_name) var serial: = create_serial(unit_name) - units_serial[unit_name] = unit_serial - units[unit_name] = unit_serial + serial.connect('got_error', on_serial_got_error.bind(serial, unit_instance)) + ProjectSettings.connect('settings_changed', serial.on_settings_changed.bind(unit_instance)) + units_serial[unit_name] = unit_instance + units[unit_name] = unit_instance serials[unit_name] = serial - bind_serials.append([serial, unit_serial, unit_name]) + bind_serials.append([serial, unit_instance, unit_name]) if proto in NULL_PROTO: var unit_null = NULL_PROTO[proto].new(unit_name) units[unit_name] = unit_null - ProjectSettings.connect('settings_changed', Callable(self, '_on_settings_changed_serial').bind(bind_serials)) tcp_sockets.append([create_socket_tcp('уарэп-5п28'), units_tcp['уарэп-5п28']]) for key: StringName in dst_ports: @@ -296,21 +310,6 @@ func _on_settings_changed_modbus(bind_modbuses: Array): var _unit_name = bm[1] -func _on_settings_changed_serial(bind_serials: Array): - var external_ctl = ProjectSettings.get_setting('application/config/Внешнее управление', false) - for bs in bind_serials: - var serial = bs[0] - var unit_serial = bs[1] - var unit_name = bs[2] - serial.try_close() - if not external_ctl: - var rc = serial.try_open(on_serial_data.bind(unit_serial)) - if rc != Error.OK: - log.message(log.ERROR, 'невозможно открыть %s для \"%s\"' % [serial, unit_name]) - else: - log.message(log.INFO, '%s для \"%s\"' % [serial, unit_name]) - - func poll_receive_udp(sock: SocketUDP) -> bool: while sock.get_available_packet_count() > 0: var data: = sock.get_packet() diff --git a/scripts/spt25.gd b/scripts/spt25.gd index 06639a6c..9bc9f601 100644 --- a/scripts/spt25.gd +++ b/scripts/spt25.gd @@ -13,14 +13,11 @@ class SPT25 extends unit.Unit: func _to_string() -> String: return String('СПТ-25 %s %s' % [self.name, ['отключен', 'на связи'][int(online)]]) - func _init(nm) -> void: - self.name = nm - tx_data.resize(6) - tx_data[0] = 0 # Адрес абонента, которому предназначен пакет - tx_data[1] = CmdCode.INFO # Тип пакета, КОД КОМАНДЫ - Получить информацию о состоянии преобразователя - tx_data[2] = 0 # Данные - tx_data[3] = 0 # Данные - tx_data[4] = 0 # Данные + func _init(unit_name) -> void: + self.name = unit_name + tx_data.resize(2) + tx_data[0] = 0 # Адрес абонента, которому предназначен пакет + tx_data[1] = CmdCode.INFO # Тип пакета, КОД КОМАНДЫ - Получить информацию о состоянии преобразователя func parse(rx_data: PackedByteArray, tick: int):