From 2ffb35dd47fe614745abc7384ce009fa259f2674 Mon Sep 17 00:00:00 2001 From: Maxim Date: Thu, 15 Jan 2026 16:01:11 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=20=D1=81=D1=86=D0=B5=D0=BD=D1=83=20?= =?UTF-8?q?tab-switch=20uid=3D"uid://b5ykwyk5vpi6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scenes/tabs-switch/lbl_ready.gd | 285 ++++++++++++++++++++++++++++ scenes/tabs-switch/lbl_ready.gd.uid | 1 + scenes/tabs-switch/tab-switch.tscn | 2 +- 3 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 scenes/tabs-switch/lbl_ready.gd create mode 100644 scenes/tabs-switch/lbl_ready.gd.uid diff --git a/scenes/tabs-switch/lbl_ready.gd b/scenes/tabs-switch/lbl_ready.gd new file mode 100644 index 00000000..f74b12d2 --- /dev/null +++ b/scenes/tabs-switch/lbl_ready.gd @@ -0,0 +1,285 @@ +extends Label + +enum DEVICE_STATE { + NONE, # Нет связи + GOOD, # Исправно + ERR # Отказ +} + +enum DEVICE_STATUS { + ONLINE, # Связь есть + STATUS, # Статус исправности + CONTROL # Контроль завершен +} + +const STATUS_CONFIG := { + DEVICE_STATE.NONE: {'text': 'Нет связи', 'color': Color.WHITE, 'font_color': Color.BLACK}, + DEVICE_STATE.GOOD: {'text': 'Исправно', 'color': Color.GREEN, 'font_color': Color.BLACK}, + DEVICE_STATE.ERR: {'text': 'Отказ', 'color': Color.RED, 'font_color': Color.WHITE} +} + +class DeviceObserver: + var device_name: String + var status: Array = [false, false, false] # [online, operational, control_complete] + var last_results: Dictionary = {} + + func update_online_state(online: bool) -> bool: + if status[DEVICE_STATUS.ONLINE] != online: + status[DEVICE_STATUS.ONLINE] = online + return true + return false + + func update_control_results(results: Dictionary) -> bool: + var changed := false + + if results.get('is_over_control', false): + # Контроль завершен - проверяем все результаты + var all_ok := true + for key in results: + if key != 'is_over_control' and not results[key]: + all_ok = false + break + + if status[DEVICE_STATUS.STATUS] != all_ok or status[DEVICE_STATUS.CONTROL] != true: + status[DEVICE_STATUS.STATUS] = all_ok + status[DEVICE_STATUS.CONTROL] = true + changed = true + else: + # Контроль в процессе - проверяем базовые параметры + var basic_ok: bool = results.get('block_kasseta', false) and \ + results.get('block_ip', false) and \ + results.get('temperature', true) + + if status[DEVICE_STATUS.STATUS] != basic_ok or status[DEVICE_STATUS.CONTROL] != false: + status[DEVICE_STATUS.STATUS] = basic_ok + status[DEVICE_STATUS.CONTROL] = false + changed = true + return changed + +var device_observers: Dictionary = {} +var overall_prd_state: DEVICE_STATE = DEVICE_STATE.NONE +var status_uf: int = DEVICE_STATE.NONE # Статус УФ (УАРЭП-ЭМС) + +func _ready() -> void: + tooltip_text = 'Нет связи с приборами комплекса' + add_theme_color_override('font_color', Color.BLACK) + + # Инициализация наблюдателей + _initialize_observers() + + # Подписка на сигналы ПРД модулей + for prd_module in prd.prd_dict.values(): + # Подключаемся к контролю ПРД + if prd_module.unit_control: + prd_module.unit_control.connect('control_results_updated', Callable(self, '_on_prd_control_results').bind(prd_module)) + # Подключаемся к онлайн-статусу ЯУ-07 + if prd_module.unit_yau07: + prd_module.unit_yau07.connect('line_changed', Callable(self, '_on_prd_online_changed').bind(prd_module)) + + # Подписка на УФ + signaller.connect('update_uf_serviceability', _on_uf_status_receive) + + # Инициализация начального состояния + _recalculate_overall_state() + + +func _initialize_observers() -> void: + var device_names := [ + 'уарэп-яу07-1н', 'уарэп-яу07-1в', 'уарэп-яу07-1к', + 'уарэп-яу07-2н', 'уарэп-яу07-2в', 'уарэп-яу07-2к', + 'уарэп-яу07-3н', 'уарэп-яу07-3в', 'уарэп-яу07-3к', + 'уарэп-яу07-4н', 'уарэп-яу07-4в', 'уарэп-яу07-4к' + ] + + for device_name in device_names: + device_observers[device_name] = DeviceObserver.new() + device_observers[device_name].device_name = device_name + + +func _on_prd_online_changed(line_status: Object, prd_module: Object) -> void: + var online: bool = line_status.online + var observer: DeviceObserver = device_observers.get(prd_module.prd_name) + if observer and observer.update_online_state(online): + _recalculate_overall_state() + + +func _on_prd_control_results(results: Dictionary, prd_module: Object) -> void: + var observer: DeviceObserver = device_observers.get(prd_module.prd_name) + if observer and observer.update_control_results(results): + _recalculate_overall_state() + + +func _on_uf_status_receive(unit_uf_status: int) -> void: + if status_uf != unit_uf_status: + status_uf = unit_uf_status + _recalculate_overall_state() + + +func _recalculate_overall_state() -> void: + var new_state := DEVICE_STATE.NONE + + # Проверяем статус ПРД + var prd_state := DEVICE_STATE.NONE + var has_online_prd := false + var all_prd_operational := true + + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE]: + has_online_prd = true + + if observer.status[DEVICE_STATUS.CONTROL]: + if not observer.status[DEVICE_STATUS.STATUS]: + all_prd_operational = false + break + else: + if not observer.status[DEVICE_STATUS.STATUS]: + all_prd_operational = false + + if has_online_prd: + if all_prd_operational: + prd_state = DEVICE_STATE.GOOD + else: + prd_state = DEVICE_STATE.ERR + else: + prd_state = DEVICE_STATE.NONE + + # Комбинируем статусы по правилу: + # 1. Если хоть один ERROR → ERROR + # 2. Если нет ERROR и хоть один GOOD → GOOD + # 3. Иначе → NONE + + if prd_state == DEVICE_STATE.ERR or status_uf == DEVICE_STATE.ERR: + new_state = DEVICE_STATE.ERR + elif prd_state == DEVICE_STATE.GOOD or status_uf == DEVICE_STATE.GOOD: + new_state = DEVICE_STATE.GOOD + else: + new_state = DEVICE_STATE.NONE + + if overall_prd_state != new_state: + overall_prd_state = new_state + _update_display() + + +func _update_display() -> void: + var config: Dictionary = STATUS_CONFIG[overall_prd_state].duplicate() + text = config.text + modulate = config.color + add_theme_color_override('font_color', config.font_color) + tooltip_text = _get_tooltip_text() + + +func _get_tooltip_text() -> String: + var tooltip := '' + + # Получаем статистику по ПРД + var prd_summary = _get_prd_summary() + var uf_status_str = _get_uf_status_text() + + match overall_prd_state: + DEVICE_STATE.NONE: + tooltip = 'Нет исправных систем в комплексе' + DEVICE_STATE.GOOD: + tooltip = 'Комплекс исправен' + DEVICE_STATE.ERR: + tooltip = 'Обнаружены неисправности в комплексе' + + tooltip += '\n\nСтатус ПРД систем: ' + prd_summary + tooltip += '\nСтатус УФ: ' + uf_status_str + + # Детализация по источникам статуса + tooltip += '\n\nСостояние систем:' + + # ПРД системы + var prd_ok_count = 0 + var prd_total = 0 + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE]: + prd_total += 1 + if observer.status[DEVICE_STATUS.STATUS]: + prd_ok_count += 1 + + tooltip += '\nПРД: %d/%d исправно' % [prd_ok_count, prd_total] + + # УФ система + tooltip += '\nУФ: ' + _get_uf_status_text() + + return tooltip + + +func _get_prd_summary() -> String: + var online_count := 0 + var operational_count := 0 + + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE]: + online_count += 1 + if observer.status[DEVICE_STATUS.STATUS]: + operational_count += 1 + + if online_count == 0: + return 'Нет связи' + else: + return '%d/%d исправно' % [operational_count, online_count] + + +func _get_uf_status_text() -> String: + match status_uf: + DEVICE_STATE.NONE: + return 'Нет данных' + DEVICE_STATE.GOOD: + return 'Исправен' + DEVICE_STATE.ERR: + return 'Неисправен' + _: + return 'Неизвестно' + + +func _has_prd_errors() -> bool: + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE] and not observer.status[DEVICE_STATUS.STATUS]: + return true + return false + + +func _has_operational_prd() -> bool: + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE] and observer.status[DEVICE_STATUS.STATUS]: + return true + return false + + +# Публичные методы для получения информации +func get_device_status(device_name: String) -> Dictionary: + var observer: DeviceObserver = device_observers.get(device_name) + if observer: + return { + 'online': observer.status[DEVICE_STATUS.ONLINE], + 'operational': observer.status[DEVICE_STATUS.STATUS], + 'control_complete': observer.status[DEVICE_STATUS.CONTROL], + 'last_results': observer.last_results.duplicate(), + 'status_uf': status_uf + } + return {} + + +func get_overall_status() -> Dictionary: + var online_count := 0 + var operational_count := 0 + var control_complete_count := 0 + + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE]: + online_count += 1 + if observer.status[DEVICE_STATUS.STATUS]: + operational_count += 1 + if observer.status[DEVICE_STATUS.CONTROL]: + control_complete_count += 1 + + return { + 'overall_state': overall_prd_state, + 'online_devices': online_count, + 'operational_devices': operational_count, + 'total_devices': device_observers.size(), + 'control_complete_devices': control_complete_count, + 'uf_status': status_uf + } diff --git a/scenes/tabs-switch/lbl_ready.gd.uid b/scenes/tabs-switch/lbl_ready.gd.uid new file mode 100644 index 00000000..355c525f --- /dev/null +++ b/scenes/tabs-switch/lbl_ready.gd.uid @@ -0,0 +1 @@ +uid://q7k2yihg057j diff --git a/scenes/tabs-switch/tab-switch.tscn b/scenes/tabs-switch/tab-switch.tscn index 01780db4..addc892f 100644 --- a/scenes/tabs-switch/tab-switch.tscn +++ b/scenes/tabs-switch/tab-switch.tscn @@ -7,7 +7,7 @@ [ext_resource type="PackedScene" uid="uid://dab6loryocc73" path="res://scenes/эмс/эмс.tscn" id="5_u71bh"] [ext_resource type="PackedScene" uid="uid://musb21x2u0xs" path="res://scenes/эмс2/эмс2.tscn" id="6_41d34"] [ext_resource type="PackedScene" uid="uid://bnptm4rlp60dq" path="res://scenes/настройки/настройки.tscn" id="6_i8iv3"] -[ext_resource type="Script" uid="uid://b5ykwyk5vpi6" path="res://scenes/tabs-switch/lbl-ready.gd" id="8_tidwt"] +[ext_resource type="Script" path="res://scenes/tabs-switch/lbl_ready.gd" id="8_tidwt"] [ext_resource type="Script" uid="uid://roajn6c6wvc1" path="res://scenes/tabs-switch/тренаж_режим.gd" id="9_41d34"] [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_tidwt"]