extends Control const CONFIG_PATH = "res://config/default_data.json" const BUFFER_SIZE = 32 var udp_broadcast: UDPBroadcast var default_data: Dictionary = {} var dictionary_yau07: Dictionary var dictionary_sockets_bit: Dictionary ## Байт 8 для отправки о состоянии ячеек func _load_default_data(): var file = FileAccess.open(CONFIG_PATH, FileAccess.READ) if file: var json = JSON.new() var error = json.parse(file.get_as_text()) if error == OK: default_data = json.data["default_data"] else: push_error("JSON Parse Error: ", json.get_error_message()) file.close() else: push_error("Failed to load config file: ", CONFIG_PATH) func _apply_default_data(): var prd_nodes = get_tree().get_nodes_in_group('prd') for prd in prd_nodes: var device_name = prd.get_meta('yau07') if default_data.has(device_name): var device_data = default_data[device_name] _fill_ukp_fields(prd, device_data) # Заполняем поля температур func _fill_ukp_fields(prd_node: Control, device_data: Dictionary): var device_name = prd_node.get_meta('yau07') # Заполняем поля температур var temp_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "temperature_ukp") if device_data.has("temperature_ukp"): for i in range(min(temp_fields.size(), device_data["temperature_ukp"].size())): temp_fields[i].text = str(device_data["temperature_ukp"][i]) # Заполняем поля мощности var power_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "power_ukp") if device_data.has("power_ukp"): for i in range(min(power_fields.size(), device_data["power_ukp"].size())): power_fields[i].text = str(device_data["power_ukp"][i]) # Устанавливаем состояния сокетов if device_data.has("sockets"): var socket_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "socket") for i in range(min(socket_fields.size(), device_data["sockets"].size())): socket_fields[i].set_pressed_no_signal(device_data["sockets"][i]) # Устанавливаем состояния ДКМ if device_data.has("dkm"): var dkm_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "dkm") for i in range(min(dkm_fields.size(), device_data["dkm"].size())): dkm_fields[i].set_pressed_no_signal(device_data["dkm"][i]) # Устанавливаем состояния ДОУ2 if device_data.has("dou2"): var dou2_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "dou2") for i in range(min(dou2_fields.size(), device_data["dou2"].size())): dou2_fields[i].set_pressed_no_signal(device_data["dou2"][i]) # Устанавливаем состояния ДОУ3 if device_data.has("dou3"): var dou3_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "dou3") for i in range(min(dou3_fields.size(), device_data["dou3"].size())): dou3_fields[i].set_pressed_no_signal(device_data["dou3"][i]) # Устанавливаем состояния аттенюаторов 2 if device_data.has("att2"): var att2_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "att2") for i in range(min(att2_fields.size(), device_data["att2"].size())): att2_fields[i].set_pressed_no_signal(device_data["att2"][i]) # Устанавливаем состояния аттенюаторов 3 if device_data.has("att3"): var att3_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "att3") for i in range(min(att3_fields.size(), device_data["att3"].size())): att3_fields[i].set_pressed_no_signal(device_data["att3"][i]) # Устанавливаем состояния источников питания (с инверсией) if device_data.has("ip"): var ip_fields = _get_ukp_nodes_for_device(device_name, [prd_node], "ip") for i in range(min(ip_fields.size(), device_data["ip"].size())): # Для IP используется инверсия: true в JSON = нажато = бит 0 ip_fields[i].set_pressed_no_signal(device_data["ip"][i]) func _ready() -> void: var device_yau07: Array = get_tree().get_nodes_in_group('device-addr') for device in device_yau07: device.connect('toggled', on_modify_device.bind(device.get_meta('device'))) var sockets: Array = get_tree().get_nodes_in_group('socket') for soc in sockets: soc.connect('toggled', _on_modify_sockets.bind(soc.get_meta('bit'), soc.get_meta('device'))) ## Мета bit от 0 до 3, мета ПРД var power_ukp_arr_node: Array = get_tree().get_nodes_in_group('power_ukp') for socket_power in power_ukp_arr_node: socket_power.connect('text_submitted', _on_ukp_submitted.bind(socket_power.get_meta('device'))) var temperature_ukp_arr_node: Array = get_tree().get_nodes_in_group('temperature_ukp') for socket_temp in temperature_ukp_arr_node: socket_temp.connect('text_submitted', _on_ukp_submitted.bind(socket_temp.get_meta('device'))) var dkm_arr_node: Array = get_tree().get_nodes_in_group('dkm') for dkm in dkm_arr_node: dkm.connect('toggled', _on_modify_dkm.bind(dkm.get_meta('bit'), dkm.get_meta('device'))) var dou2_arr_node: Array = get_tree().get_nodes_in_group('dou2') for dou2 in dou2_arr_node: 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.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: ip.connect('toggled', _on_modify_ip.bind(ip.get_meta('bit'), ip.get_meta('device'))) _update_tab_container() _load_default_data() _apply_default_data() func _process(_delta: float) -> void: for device in dictionary_yau07: dictionary_yau07[device]._on_poll_timeout() func _exit_tree(): for device in dictionary_yau07: if dictionary_yau07[device]: dictionary_yau07[device].close_udp_unit() func on_modify_device(toggled: bool, name_device: String) -> void: if toggled: udp_broadcast = UDPBroadcast.new(name_device) udp_broadcast.add_timers_to_scene(self) # Исправлено имя метода 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() dictionary_yau07.erase(name_device) print("Устройство %s деактивировано" % name_device) _update_tab_container() func _update_tab_container(): var tab_container = $TabContainer var device_nodes = get_tree().get_nodes_in_group('device-addr') var has_visible_tabs = false # Проходим по всем вкладкам и обновляем их состояние for i in range(tab_container.get_tab_count()): var tab_control = tab_container.get_tab_control(i) var device_name = tab_control.get_meta('yau07', '') # Ищем соответствующую кнопку устройства var device_button = null for device in device_nodes: if device.get_meta('device') == device_name: device_button = device break # Если нашли кнопку, устанавливаем состояние вкладки if device_button: var is_enabled = device_button.button_pressed tab_container.set_tab_disabled(i, !is_enabled) if is_enabled: has_visible_tabs = true # Если все вкладки заблокированы, скрываем TabContainer 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): var udp_unit = dictionary_yau07[device] var current_status = udp_unit.get_sockets_status() # Используем геттер var new_status = _set_bit(current_status, bit, toggled) udp_unit.set_sockets_status(new_status) # Используем сеттер print("Статус сокетов устройства %s обновлен: 0x%04X" % [device, new_status]) ## Функция для установки статусов ДКМ в ПРД func _on_modify_dkm(toggled: bool, bit: int, device: String)->void: if dictionary_yau07.has(device): var udp_unit = dictionary_yau07[device] var current_status = udp_unit.get_dkm_status() # Используем геттер var new_status = _set_bit(current_status, bit, toggled) udp_unit.set_dkm_status(new_status) # Используем сеттер print("Статус DKM устройства %s обновлен: 0x%04X" % [device, new_status]) 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: # Восстанавливаем предыдущее состояние for button in button_group: if button.has_meta('bit') and button.get_meta('bit') == bit: button.set_pressed(true) return # Выключаем другие кнопки в группе 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): if dictionary_yau07.has(device): var udp_unit = dictionary_yau07[device] var current_status = udp_unit.get_ip_status() # Инверсия: нажата = 0, отжата = 1 var bit_value = 0 if toggled else 1 var new_status if bit_value == 0: new_status = current_status & ~(1 << bit) # Устанавливаем бит в 0 else: new_status = current_status | (1 << bit) # Устанавливаем бит в 1 udp_unit.set_ip_status(new_status) print("Статус ИП устройства %s обновлен: 0x%04X" % [device, new_status]) ## Функция для установки значений в ячейках УКП func _on_ukp_submitted(_new_text: String, device: String) -> void: if not dictionary_yau07.has(device): return var prep_temperature_ukp1_array: Array = _on_text_temperature_changed(device, 1) var prep_temperature_ukp2_array: Array = _on_text_temperature_changed(device, 2) var prep_power_ukp1_array: Array = _on_text_power_changed(device, 1) var prep_power_ukp2_array: Array = _on_text_power_changed(device, 2) var combine_data_ukp1: Array = _combine_arrays(prep_temperature_ukp1_array, prep_power_ukp1_array) var combine_data_ukp2: Array = _combine_arrays(prep_temperature_ukp2_array, prep_power_ukp2_array) _form_buffers(device, combine_data_ukp1, 1, dictionary_yau07) _form_buffers(device, combine_data_ukp2, 2, dictionary_yau07) func _on_text_temperature_changed(device: String, number_device: int) -> Array: return _process_ukp_data(device, number_device, "temperature_ukp", _convert_temperature) func _on_text_power_changed(device: String, number_device: int) -> Array: return _process_ukp_data(device, number_device, "power_ukp", _convert_power) func _process_ukp_data(device: String, number_device: int, group_name: String, converter: Callable) -> Array: var prd_module_arr = get_tree().get_nodes_in_group('prd') var current_change: Array = _get_ukp_nodes_for_device(device, prd_module_arr, group_name) var result_arr: Array = [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff] var config: Dictionary = _get_ukp_config(device, number_device) for i in range(config.start_index, config.end_index): if i < current_change.size() and not current_change[i].text.is_empty(): var value = _safe_convert_to_int(current_change[i].text) var offset: int = config.offset if i == config.end_index-1 else 0 var result_index = i - config.start_index + offset if result_index < result_arr.size(): result_arr[result_index] = converter.call(value) return result_arr static func _get_ukp_nodes_for_device(device: String, prd_module_arr: Array, group_name: String) -> Array: for prd in prd_module_arr: if device == prd.get_meta('yau07'): var nodes = [] for node in prd.get_tree().get_nodes_in_group(group_name): if prd.is_ancestor_of(node): nodes.append(node) return nodes return [] static func _get_ukp_config(device: String, number_device: int) -> Dictionary: var is_k_device = device in ['ПРД-К1', 'ПРД-К2', 'ПРД-К3', 'ПРД-К4'] if number_device == 1: return { "start_index": 0, "end_index": 7 if is_k_device else 6, "offset": 1 if is_k_device else 0 } else: return { "start_index": 7 if is_k_device else 6, "end_index": 13 if is_k_device else 12, "offset": 0 } static func _convert_temperature(value: int) -> int: const CONST_MIN_TEMP: int = -25 const MAXIMUM_CODE_ADC: int = 3796 const MINIMUM_CODE_AD: int = 2660 const TEMP: float = 115.0 / (MAXIMUM_CODE_ADC - MINIMUM_CODE_AD) var result: float = MAXIMUM_CODE_ADC - (value - CONST_MIN_TEMP - 3) / TEMP return int(result) static func _convert_power(value: int) -> int: return value static func _safe_convert_to_int(text: String) -> int: text = text.strip_edges().to_lower() if text.is_valid_int(): return int(text) elif text.is_valid_float(): return roundi(float(text)) elif text.begins_with("0x") and text.substr(2).is_valid_hex_number(): return text.hex_to_int() else: return 0 static func _combine_arrays(power_arr: Array, temp_arr: Array)-> Array: return temp_arr + power_arr static func _form_buffers(device: String, ukp_data: Array, number_device: int, dic_yau07: Dictionary): var buffer: PackedByteArray = PackedByteArray() buffer.resize(BUFFER_SIZE) for i in ukp_data.size(): buffer.encode_u16(2 * i, ukp_data[i]) if dic_yau07.has(device): var udp_unit = dic_yau07[device] if number_device == 1: udp_unit.ukp0_data = buffer print("Данные UKP0 устройства %s обновлены" % device) elif number_device == 2: udp_unit.ukp1_data = buffer print("Данные UKP1 устройства %s обновлены" % device) static func _set_bit(bits: int, index: int, val: bool) -> int: return bits | (1 << index) if val else bits & ~(1 << index) ## Новый метод для работы с ISA портами func read_isa_ports(device: String, port_addresses: Array) -> Dictionary: """Чтение ISA портов указанного устройства""" if dictionary_yau07.has(device): return dictionary_yau07[device].read_isa_ports(port_addresses) else: push_error("Устройство %s не найдено" % device) return {} ## Новый метод для записи ISA портов func write_isa_port(device: String, port_address: int, value: int) -> bool: """Запись значения в ISA порт указанного устройства""" if dictionary_yau07.has(device): return dictionary_yau07[device].set_isa_port(port_address, value) else: push_error("Устройство %s не найдено" % device) return false