Добавление в сцену tab-switch uid="uid://b5ykwyk5vpi6"

This commit is contained in:
Maxim
2026-01-15 16:01:11 +03:00
parent 83549ec2a3
commit 2ffb35dd47
3 changed files with 287 additions and 1 deletions

View File

@@ -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
}

View File

@@ -0,0 +1 @@
uid://q7k2yihg057j

View File

@@ -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"]