From 39bef3a351a3220df3d091e6ce9516e945cd6e91 Mon Sep 17 00:00:00 2001 From: TotMaxim Date: Fri, 21 Nov 2025 13:02:32 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D1=82=D0=BE?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B0=D1=82=D1=82=20=D0=B8=20=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=82=D1=83=D1=81=20=D0=BC=D0=B5=D0=BD=D0=B5=D0=B4=D0=B6=D0=B5?= =?UTF-8?q?=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StatusManager.gd | 55 +++++++++++++++++++++ StatusManager.gd.uid | 1 + main.gd | 113 ++++++++++++++++++++++++++++--------------- main.tscn | 2 +- udp_broadcast.gd | 46 +++--------------- 5 files changed, 137 insertions(+), 80 deletions(-) create mode 100644 StatusManager.gd create mode 100644 StatusManager.gd.uid diff --git a/StatusManager.gd b/StatusManager.gd new file mode 100644 index 0000000..1b73c91 --- /dev/null +++ b/StatusManager.gd @@ -0,0 +1,55 @@ +class_name StatusManager +extends RefCounted + +var _device + +func _init(device): + _device = device + Callable(_emit_initial_ports).call_deferred() + + +func _emit_initial_ports() -> void: + """Вывод начального состояния через существующий сигнал UDPBroadcast""" + # Просто устанавливаем текущие значения (это вызовет update_isa_ports) + var current_106 = _device.get_isa_port(0x106) + var current_108 = _device.get_isa_port(0x108) + + # Триггерим обновление через установку тех же значений + _device.set_isa_port(0x106, current_106) + _device.set_isa_port(0x108, current_108) + +# Универсальные методы для работы с битовыми полями +func set_status_field(port: int, value: int, bit_mask: int, shift: int = 0) -> void: + var current_value = _device.get_isa_port(port) + var masked_value = (value & bit_mask) << shift + var clear_mask = ~(bit_mask << shift) & 0xFF + var new_value = (current_value & clear_mask) | masked_value + _device.set_isa_port(port, new_value) + +func get_status_field(port: int, bit_mask: int, shift: int = 0) -> int: + return (_device.get_isa_port(port) >> shift) & bit_mask + +# Специфичные методы для каждого статуса +func set_dou2_status(status: int) -> void: + set_status_field(0x106, status, 0b111, 0) + +func get_dou2_status() -> int: + return get_status_field(0x106, 0b111, 0) + +func set_att2_status(status: int) -> void: + set_status_field(0x106, status, 0b111, 3) + +func get_att2_status() -> int: + return get_status_field(0x106, 0b111, 3) + +func set_dou3_status(status: int) -> void: + set_status_field(0x108, status, 0b111, 0) + +func get_dou3_status() -> int: + return get_status_field(0x108, 0b111, 0) + +func set_att3_status(status: int) -> void: + set_status_field(0x108, status, 0b111, 3) + +func get_att3_status() -> int: + return get_status_field(0x108, 0b111, 3) diff --git a/StatusManager.gd.uid b/StatusManager.gd.uid new file mode 100644 index 0000000..7088d0c --- /dev/null +++ b/StatusManager.gd.uid @@ -0,0 +1 @@ +uid://ddgp4l3kdjwg2 diff --git a/main.gd b/main.gd index 9d47c5c..af8aa76 100644 --- a/main.gd +++ b/main.gd @@ -114,11 +114,19 @@ func _ready() -> void: var dou2_arr_node: Array = get_tree().get_nodes_in_group('dou2') for dou2 in dou2_arr_node: - dou2.connect('toggled', _on_modify_dou2.bind(dou2.get_meta('bit'), dou2.get_meta('device'))) - + dou2.toggled.connect(_on_modify_status.bind(dou2.get_meta('bit'), dou2.get_meta('device'), "dou2")) + var dou3_arr_node: Array = get_tree().get_nodes_in_group('dou3') for dou3 in dou3_arr_node: - dou3.connect('toggled', _on_modify_dou3.bind(dou3.get_meta('bit'), dou3.get_meta('device'))) + dou3.toggled.connect(_on_modify_status.bind(dou3.get_meta('bit'), dou3.get_meta('device'), "dou3")) + + var att2_arr_node: Array = get_tree().get_nodes_in_group('att2') + for att2 in att2_arr_node: + att2.toggled.connect(_on_modify_status.bind(att2.get_meta('bit'), att2.get_meta('device'), "att2")) + + var att3_arr_node: Array = get_tree().get_nodes_in_group('att3') + for att3 in att3_arr_node: + att3.toggled.connect(_on_modify_status.bind(att3.get_meta('bit'), att3.get_meta('device'), "att3")) var ip_arr_node: Array = get_tree().get_nodes_in_group('ip') for ip in ip_arr_node: @@ -146,6 +154,7 @@ func on_modify_device(toggled: bool, name_device: String) -> void: udp_broadcast.start_broadcast() dictionary_yau07[name_device] = udp_broadcast print("Устройство %s активировано" % name_device) + dictionary_yau07[name_device].connect('update_isa_ports', _on_update_isa_ports) else: if dictionary_yau07.has(name_device) and dictionary_yau07[name_device]: dictionary_yau07[name_device].close_udp_unit() @@ -182,6 +191,38 @@ func _update_tab_container(): tab_container.visible = has_visible_tabs +func _on_update_isa_ports(isa_ports: Dictionary)->void: + for port_addr in isa_ports: + var value = isa_ports[port_addr] + + # Группы кнопок обновлять для каждого порта + var port_configs = { + 0x106: [ # Порт 0x106 + {'group': 'dou2', 'mask': 0b111, 'shift': 0}, + {'group': 'att2', 'mask': 0b111, 'shift': 3} + ], + 0x108: [ # Порт 0x108 + {'group': 'dou3', 'mask': 0b111, 'shift': 0}, + {'group': 'att3', 'mask': 0b111, 'shift': 3} + ] + } + + if port_configs.has(port_addr): + for config in port_configs[port_addr]: + var status = (value >> config.shift) & config.mask + _update_button_group(config.group, status) + + +func _update_button_group(group_name: String, status: int) -> void: + """Обновление всех кнопок в группе на основе статуса""" + var buttons = get_tree().get_nodes_in_group(group_name) + for button in buttons: + if button.has_meta('bit'): + var bit_value = button.get_meta('bit') + var should_be_pressed = (status == bit_value) + button.set_pressed_no_signal(should_be_pressed) + + ## Функция для установки статусов ячеек на связи (УГ, ЭМС-Г, УКП) func _on_modify_sockets(toggled: bool, bit: int, device: String)->void: if dictionary_yau07.has(device): @@ -202,43 +243,35 @@ func _on_modify_dkm(toggled: bool, bit: int, device: String)->void: print("Статус DKM устройства %s обновлен: 0x%04X" % [device, new_status]) -## Функция для установки статусов ДОУ2 в ПРД -func _on_modify_dou2(toggled: bool, bit: int, device: String)->void: +func _on_modify_status(toggled: bool, bit: int, device: String, status_type: String) -> void: + if not dictionary_yau07.has(device): + return + + var udp_unit = dictionary_yau07[device] + var button_group = get_tree().get_nodes_in_group(status_type) + if not toggled: - var dou2_arr_node = get_tree().get_nodes_in_group('dou2') - for dou2 in dou2_arr_node: - if dou2.has_meta('bit') and dou2.get_meta('bit') == bit: - dou2.set_pressed(true) - if toggled: - var dou2_arr_node = get_tree().get_nodes_in_group('dou2') - for dou2 in dou2_arr_node: - if dou2.has_meta('bit') and dou2.get_meta('bit') != bit and dou2.button_pressed: - dou2.set_pressed_no_signal(false) + # Восстанавливаем предыдущее состояние + for button in button_group: + if button.has_meta('bit') and button.get_meta('bit') == bit: + button.set_pressed(true) + return - # Всегда устанавливаем статус, если кнопка нажата - if toggled and dictionary_yau07.has(device): - var udp_unit = dictionary_yau07[device] - udp_unit.set_dou2_status(bit) - - -## Функция для установки статусов ДОУ3 в ПРД -func _on_modify_dou3(toggled: bool, bit: int, device: String)->void: - if not toggled: - var dou3_arr_node = get_tree().get_nodes_in_group('dou3') - for dou3 in dou3_arr_node: - if dou3.has_meta('bit') and dou3.get_meta('bit') == bit: - dou3.set_pressed(true) - - if toggled: - var dou3_arr_node = get_tree().get_nodes_in_group('dou3') - for dou3 in dou3_arr_node: - if dou3.has_meta('bit') and dou3.get_meta('bit') != bit and dou3.button_pressed: - dou3.set_pressed_no_signal(false) - - # Всегда устанавливаем статус, если кнопка нажата - if toggled and dictionary_yau07.has(device): - var udp_unit = dictionary_yau07[device] - udp_unit.set_dou3_status(bit) + # Выключаем другие кнопки в группе + for button in button_group: + if button.has_meta('bit') and button.get_meta('bit') != bit and button.button_pressed: + button.set_pressed_no_signal(false) + print('button_press_bit: ', bit) + # Устанавливаем статус через менеджер + match status_type: + "dou2": + udp_unit.status_manager.set_dou2_status(bit) + "att2": + udp_unit.status_manager.set_att2_status(bit) + "dou3": + udp_unit.status_manager.set_dou3_status(bit) + "att3": + udp_unit.status_manager.set_att3_status(bit) func _on_modify_ip(toggled: bool, bit: int, device: String): @@ -374,7 +407,7 @@ static func _set_bit(bits: int, index: int, val: bool) -> int: return bits | (1 << index) if val else bits & ~(1 << index) -## Новый метод для работы с ISA портами (если потребуется) +## Новый метод для работы с ISA портами func read_isa_ports(device: String, port_addresses: Array) -> Dictionary: """Чтение ISA портов указанного устройства""" if dictionary_yau07.has(device): @@ -384,7 +417,7 @@ func read_isa_ports(device: String, port_addresses: Array) -> Dictionary: return {} -## Новый метод для записи ISA портов (если потребуется) +## Новый метод для записи ISA портов func write_isa_port(device: String, port_address: int, value: int) -> bool: """Запись значения в ISA порт указанного устройства""" if dictionary_yau07.has(device): diff --git a/main.tscn b/main.tscn index 63d3f88..25a4541 100644 --- a/main.tscn +++ b/main.tscn @@ -440,8 +440,8 @@ layout_mode = 2 [node name="CheckBox" type="CheckBox" parent="TabContainer/ПРД-Н1/TabBar/ug/GridContainer2" groups=["att2"]] layout_mode = 2 text = "АТТ 0 dB" -metadata/att = 0 metadata/device = "ПРД-Н1" +metadata/bit = 0 [node name="CheckBox2" type="CheckBox" parent="TabContainer/ПРД-Н1/TabBar/ug/GridContainer2" groups=["att2"]] layout_mode = 2 diff --git a/udp_broadcast.gd b/udp_broadcast.gd index ac96470..83e5cd7 100644 --- a/udp_broadcast.gd +++ b/udp_broadcast.gd @@ -37,6 +37,7 @@ const ADDRESS_LIST: Dictionary = { const BROADCAST_ADDR: Array = [50000, "10.1.1.255"] # Приватные свойства +var status_manager: StatusManager var _socket: SocketUDP var _self_name: String var _isa_ports: Dictionary = {} @@ -47,27 +48,15 @@ var _dkm_status_bit: int = 0 var _dry_contact_status_bit: int = 0xFF var _cmd_number_count: int = 0 var _last_received_command: int = -1 +var ukp0_data: PackedByteArray +var ukp1_data: PackedByteArray - -# Публичные свойства с контролем доступа -var ukp0_data: PackedByteArray: - set(value): - if value.size() == UKP_DATA_SIZE: - ukp0_data = value - print('Данные UKP0 обновлены') - - -var ukp1_data: PackedByteArray: - set(value): - if value.size() == UKP_DATA_SIZE: - ukp1_data = value - print('Данные UKP1 обновлены') - - +signal update_isa_ports(_isa_ports: Dictionary) func _init(name: String): """Инициализация UDP broadcast клиента""" + status_manager = StatusManager.new(self) _self_name = name _initialize_socket() _initialize_ukp_data() @@ -199,28 +188,6 @@ func get_dkm_status() -> int: return _dkm_status_bit -func set_dou2_status(status: int) -> void: - """Установка статуса DOU""" - var masked_status = status & 0b111 # Маска для первых 3 битов - set_isa_port(0x106, masked_status) - - -func get_dou2_status() -> int: - """Получение статуса DOU""" - return get_isa_port(0x106) & 0b111 - - -func set_dou3_status(status: int) -> void: - """Установка статуса DOU""" - var masked_status = status & 0b111 # Маска для первых 3 битов - set_isa_port(0x108, masked_status) - - -func get_dou3_status() -> int: - """Получение статуса DOU""" - return get_isa_port(0x108) & 0b111 - - func set_ip_status(status: int)->void: """Установка статуса ИП""" _dry_contact_status_bit = status @@ -234,10 +201,11 @@ func get_ip_status()->int: func set_isa_port(port_addr: int, value: int) -> bool: """Установка значения ISA порта""" if port_addr < 0 or port_addr > 0xFFFF: - push_error("Некорректный адрес порта: 0x%04X" % port_addr) + push_error("Некорректный адрес порта: 0x%03X" % port_addr) return false _isa_ports[port_addr] = value + emit_signal('update_isa_ports', _isa_ports) return true