Compare commits

...

2 Commits

Author SHA1 Message Date
TotMaxim
c74d5ccdad Отладка интегрального контроля УФ 2025-12-07 20:14:51 +03:00
TotMaxim
a7c816e6ca Доработка интегрального контроля УФ 2025-12-07 18:49:03 +03:00
7 changed files with 278 additions and 147 deletions

View File

@@ -1,113 +1,103 @@
@tool
class_name pribor_uf extends 'res://scenes/контроль/прибор.gd'
signal control_is_over(device_name: String) # Когда контроль завершен
enum STATE_VAL {NONE = 0, GOOD = 1, ERROR = 2}
const DEV_LIST: Array = ['00:1f.6', '07:00.0', '08:00.0', '0b:00.0']
const USB_TRACKERBALL: String = '13ba:0018'
const REVFF: String = '(rev ff)'
var unit_uf: Object
var uf_control: Object
var ctrl_pos = 100
func _ready() -> void:
if Engine.is_editor_hint(): return
signaller.conn(signaller.start_contol_device, Callable(self, '_on_start_contol_device'))
unit_uf = network.get_unit_instance('уарэп-эмс')
unit_uf.connect('line_changed', on_line_changed)
on_line_changed()
#control_vk()
control_ems(unit_uf.status)
status_uf()
uf_control = get_parent().uf_control
uf_control.connect('update_uf_serviceability', on_update_uf_serviceability)
var uf_status = uf_control.get_current_status()
control_ems(uf_status)
find_labels(self)
func _on_start_contol_device():
on_line_changed()
control_ems(unit_uf.status) # проверка ЭМС ячеек
status_uf() # отслеживание состояния прибора
func on_update_uf_serviceability(_state: int):
control_ems(uf_control.get_current_status())
func on_line_changed():
if unit_uf.online: # проверка ЯУ, внутреннего коммутатора и ИП-5Б
#func control_vk() -> void:
#var out_usb_str = ''
#var out_pci_str = ''
#var out_usb = []
#var out_pci = []
#
#OS.execute('lsusb', [], out_usb) # TODO: Не переносимое, платформозависимое
#for element in out_usb:
#out_usb_str += element
#
#OS.execute('lspci', [], out_pci) # TODO: Не переносимое, платформозависимое
#for element in out_pci:
#out_pci_str += element
#
#out_usb_str = out_usb_str.split('\n')
#out_pci_str = out_pci_str.split('\n')
#
#var i: int = 0
#
#for string in out_usb_str:
#if USB_TRACKERBALL in string:
#i += 1
#break
#for string in out_pci_str:
#for item in DEV_LIST:
#if item in string:
#i += 1
#if REVFF in string:
#i -= 1
#break
#
#if i == (DEV_LIST.size() + 1):
#$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD
#else:
#$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.ERROR
func control_ems(status: Dictionary) -> void:
if status['УФ-онлайн']:
$ref_uf/ref_kassetav13/ref_A7_YAU07.state = STATE_VAL.GOOD
$ref_uf/ref_kassetav13/ref_A3_IP5B.state = STATE_VAL.GOOD
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD
$ref_uf/ref_kassetav13/ref_A9_ESW.state = STATE_VAL.GOOD
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD ## заглушка для зеленения ВК-110
$ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.GOOD if status['КЭМС-Б1'] else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A5_EMS.state = STATE_VAL.GOOD if status['ЭМС-Б1'] else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A6_EMS.state = STATE_VAL.GOOD if status['ЭМС-Б2'] else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A12_IP27B.state = STATE_VAL.GOOD if status['ИП220-27Б'] else STATE_VAL.ERROR
else:
$ref_uf/ref_kassetav13/ref_A7_YAU07.state = STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A3_IP5B.state = STATE_VAL.NONE
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A9_ESW.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A5_EMS.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A6_EMS.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A3_IP5B.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A9_ESW.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A12_IP27B.state = STATE_VAL.NONE
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.NONE
status_uf(status)
func control_vk() -> void:
var out_usb_str = ''
var out_pci_str = ''
var out_usb = []
var out_pci = []
OS.execute('lsusb', [], out_usb) # TODO: Не переносимое, платформозависимое
for element in out_usb:
out_usb_str += element
OS.execute('lspci', [], out_pci) # TODO: Не переносимое, платформозависимое
for element in out_pci:
out_pci_str += element
out_usb_str = out_usb_str.split('\n')
out_pci_str = out_pci_str.split('\n')
var i: int = 0
for string in out_usb_str:
if USB_TRACKERBALL in string:
i += 1
break
for string in out_pci_str:
for item in DEV_LIST:
if item in string:
i += 1
if REVFF in string:
i -= 1
break
if i == (DEV_LIST.size() + 1):
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD
else:
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.ERROR
func control_ems(status: Array) -> void:
if status:
$ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.GOOD if ((status[0] >> 0) & 1) and ((status[0] >> 3) & 1) else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A5_EMS.state = STATE_VAL.GOOD if ((status[0] >> 1) & 1) and ((status[0] >> 4) & 1) else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A6_EMS.state = STATE_VAL.GOOD if ((status[0] >> 2) & 1) and ((status[0] >> 5) & 1) else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A12_IP27B.state = STATE_VAL.GOOD if ((status[2] >> 6) & 1) else STATE_VAL.ERROR
func status_uf() -> void:
var status_bu: int = $ref_uf/ref_bu1/ref_A8_BU.state
var status_yau: int = $ref_uf/ref_kassetav13/ref_A7_YAU07.state
var status_kyems: int = $ref_uf/ref_kassetav13/ref_A4_KEMS.state
var status_yems0: int = $ref_uf/ref_kassetav13/ref_A5_EMS.state
var status_yems1: int = $ref_uf/ref_kassetav13/ref_A6_EMS.state
var status_ip5: int = $ref_uf/ref_kassetav13/ref_A3_IP5B.state
var status_ip27: int = $ref_uf/ref_kassetav13/ref_A12_IP27B.state
if (status_yau == 1) and (status_bu == 1) and (status_kyems == 1) \
and (status_yems0 == 1) and (status_yems1 == 1) and (status_ip5 == 1) and (status_ip27 == 1):
$lbl_header2.text = 'Прибор исправен'
$lbl_header2.modulate = Color.GREEN
else:
$lbl_header2.text = 'Прибор неисправен'
$lbl_header2.modulate = Color.RED
func status_uf(status_uf_dic: Dictionary) -> void:
var is_ok: bool = true
if not status_uf_dic['УФ-онлайн']:
$lbl_header2.text = 'Ожидание связи с ЯУ-07Б'
$lbl_header2.modulate = Color.WHITE
elif status_uf_dic['УФ-онлайн']:
for socket in status_uf_dic:
if not status_uf_dic[socket]:
is_ok = false
if is_ok:
$lbl_header2.text = 'Прибор исправен'
$lbl_header2.modulate = Color.GREEN
elif not is_ok:
$lbl_header2.text = 'Прибор неисправен'
$lbl_header2.modulate = Color.RED
$lbl_header2.visible = true
emit_signal('control_is_over', unit_uf.name)
func find_labels(node1: Node):

View File

@@ -0,0 +1,93 @@
class_name UFControl extends Node
signal update_uf_serviceability(status: int)
#region Константы и переменные
enum StatusIndex {SOCKETS = 0, IP_220_27B = 2}
enum STATE_VAL {NONE = 0, GOOD = 1, ERROR = 2}
var unit_uf: Object
var uf_status: Dictionary = {'УФ-онлайн': false, 'КЭМС-Б1': false, 'ЭМС-Б1': false, 'ЭМС-Б2': false, 'ИП220-27Б': false}
var _self_name: String
var _serviceability: int = STATE_VAL.NONE
var serviceability: int:
get:
return _serviceability
set(value):
if value != _serviceability:
_serviceability = value
signaller.emit_signal('update_uf_serviceability', value)
#endregion
#region Инициализация
func _init(name_uf: String) -> void:
_self_name = name_uf
unit_uf = network.get_unit_instance(_self_name)
unit_uf.connect('line_changed', on_line_changed)
unit_uf.connect('data_received', on_data_received)
#endregion
#region Обработчики сигналов
func on_line_changed(status: Object) -> void:
'''Обработка изменения состояния линии связи'''
uf_status['УФ-онлайн'] = status.online
update_serviceability()
func on_data_received(yau: Object) -> void:
'''Обработка полученных данных от УФ'''
var new_ems_status = control_ems(yau.status)
var status_changed = false
# Обновляем только ключи КЭМС/ЭМС, сохраняя 'УФ-онлайн'
for key in ['КЭМС-Б1', 'ЭМС-Б1', 'ЭМС-Б2', 'ИП220-27Б']:
var old_value = uf_status.get(key, false)
var new_value = new_ems_status.get(key, false)
if old_value != new_value:
uf_status[key] = new_value
status_changed = true
if status_changed:
update_serviceability()
#endregion
#region Статус и сервисабельность
func get_current_status() -> Dictionary:
'''Получение текущего статуса (только для чтения)'''
return uf_status.duplicate(true)
func is_operational() -> bool:
'''Проверка, все ли системы работают нормально'''
return serviceability and uf_status.get('УФ-онлайн', false)
func update_serviceability() -> void:
'''Обновление общего статуса сервисабельности'''
var new_serviceability: int = STATE_VAL.GOOD
# Проверяем онлайн-статус
if uf_status.get('УФ-онлайн', false) == false:
new_serviceability = STATE_VAL.NONE
else:
# Проверяем все статусы КЭМС/ЭМС
for key in ['КЭМС-Б1', 'ЭМС-Б1', 'ЭМС-Б2', 'ИП220-27Б']:
if uf_status.get(key, true) == false:
new_serviceability = STATE_VAL.ERROR
break
# Новое значение через setter
self.serviceability = new_serviceability
#endregion
#region Вспомогательные методы
static func control_ems(status: Array) -> Dictionary:
'''Анализ статусов КЭМС/ЭМС'''
var status_dic: Dictionary = {}
if status.is_empty() or status.size() < 3:
return status_dic
status_dic['КЭМС-Б1'] = bool((status[StatusIndex.SOCKETS] >> 0) & 1) and bool((status[StatusIndex.SOCKETS] >> 3) & 1)
status_dic['ЭМС-Б1'] = bool((status[StatusIndex.SOCKETS] >> 1) & 1) and bool((status[StatusIndex.SOCKETS] >> 4) & 1)
status_dic['ЭМС-Б2'] = bool((status[StatusIndex.SOCKETS] >> 2) & 1) and bool((status[StatusIndex.SOCKETS] >> 5) & 1)
status_dic['ИП220-27Б'] = bool((status[StatusIndex.IP_220_27B] >> 6) & 1)
return status_dic
#endregion

View File

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

View File

@@ -1,6 +1,6 @@
extends Label
enum PRD_STATE {
enum DEVICE_STATE {
NONE, # Нет связи
GOOD, # Исправно
ERR # Отказ
@@ -13,16 +13,15 @@ enum DEVICE_STATUS {
}
const STATUS_CONFIG := {
PRD_STATE.NONE: {"text": "Нет связи", "color": Color.WHITE, "font_color": Color.BLACK},
PRD_STATE.GOOD: {"text": "Исправно", "color": Color.GREEN, "font_color": Color.BLACK},
PRD_STATE.ERR: {"text": "Отказ", "color": Color.RED, "font_color": Color.WHITE}
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 = {}
var status_uf: bool = false
func update_online_state(online: bool) -> bool:
if status[DEVICE_STATUS.ONLINE] != online:
@@ -59,8 +58,8 @@ class DeviceObserver:
return changed
var device_observers: Dictionary = {}
var overall_prd_state: PRD_STATE = PRD_STATE.NONE
var status_uf: bool = false # Статус УФ (УАРЭП-ЭМС)
var overall_prd_state: DEVICE_STATE = DEVICE_STATE.NONE
var status_uf: int = DEVICE_STATE.NONE # Статус УФ (УАРЭП-ЭМС)
func _ready() -> void:
tooltip_text = 'Нет связи с приборами комплекса'
@@ -79,10 +78,8 @@ func _ready() -> void:
prd_module.unit_yau07.connect('line_changed', Callable(self, '_on_prd_online_changed').bind(prd_module))
# Подписка на УФ
var unit_uf = network.get_unit_instance('уарэп-эмс')
if unit_uf:
unit_uf.data_received.connect(Callable(self, '_on_uf_status_receive'))
signaller.connect('update_uf_serviceability', _on_uf_status_receive)
# Инициализация начального состояния
_recalculate_overall_state()
@@ -113,48 +110,52 @@ func _on_prd_control_results(results: Dictionary, prd_module: Object) -> void:
_recalculate_overall_state()
func _on_uf_status_receive(unit_uf: Object) -> void:
if unit_uf:
var KEMS_B = ((unit_uf.status[0] >> 0) & 1) and ((unit_uf.status[0] >> 3) & 1)
var EMS_B_1 = ((unit_uf.status[0] >> 1) & 1) and ((unit_uf.status[0] >> 4) & 1)
var EMS_B_2 = ((unit_uf.status[0] >> 2) & 1) and ((unit_uf.status[0] >> 5) & 1)
var IP27B = ((unit_uf.status[2] >> 6) & 1)
var new_uf_status = KEMS_B and EMS_B_1 and EMS_B_2 and IP27B
if status_uf != new_uf_status:
status_uf = new_uf_status
_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 := PRD_STATE.NONE
var has_online_devices := false
var all_operational := true
# Проверяем только если есть онлайн устройства
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_devices = true
has_online_prd = true
if observer.status[DEVICE_STATUS.CONTROL]:
# Если контроль завершен - строгая проверка
if not observer.status[DEVICE_STATUS.STATUS]:
all_operational = false
all_prd_operational = false
break
else:
# Если контроль в процессе - мягкая проверка
if not observer.status[DEVICE_STATUS.STATUS]:
all_operational = false
# Не прерываем, чтобы проверить все устройства
if has_online_devices:
if all_operational and status_uf:
new_state = PRD_STATE.GOOD
all_prd_operational = false
if has_online_prd:
if all_prd_operational:
prd_state = DEVICE_STATE.GOOD
else:
new_state = PRD_STATE.ERR
prd_state = DEVICE_STATE.ERR
else:
new_state = PRD_STATE.NONE
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()
@@ -171,39 +172,82 @@ func _update_display() -> void:
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:
PRD_STATE.NONE:
tooltip = "Нет связи с приборами комплекса"
PRD_STATE.GOOD:
tooltip = "Все приборы комплекса исправны"
PRD_STATE.ERR:
DEVICE_STATE.NONE:
tooltip = "Нет исправных систем в комплексе"
DEVICE_STATE.GOOD:
tooltip = "Комплекс исправен"
DEVICE_STATE.ERR:
tooltip = "Обнаружены неисправности в комплексе"
_:
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
# Добавляем информацию о статусе УФ, если есть онлайн устройства
if overall_prd_state != PRD_STATE.NONE:
tooltip += "\n\n"
tooltip += "Статус УФ (УАРЭП-ЭМС): "
tooltip += "Исправен" if status_uf else "Неисправен"
# Добавляем детальную информацию о ПРД устройствах
tooltip += "\n\nДетальный статус ПРД:"
func _get_prd_summary() -> String:
var online_count := 0
var operational_count := 0
for device_name in device_observers:
var observer = device_observers[device_name]
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]
tooltip += "\nПРД онлайн: %d/%d" % [online_count, device_observers.size()]
tooltip += "\nПРД исправны: %d/%d" % [operational_count, online_count]
return tooltip
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
# Публичные методы для получения информации

View File

@@ -54,6 +54,7 @@ const PRIBORS_RES = \\
'pribor_uf': ['res://scenes/pribor-uf/pribor-uf.tscn', 'Контроль исправности прибора УФ'],
'pribor_uyep': ['res://scenes/pribor-uyep/pribor-uyep.tscn', 'Контроль исправности устройства У-ЭП'],
}
var uf_control: UFControl
var ctl_btn_state := false
var cur_pribor_node = null
var check_ready_control: Dictionary = {}
@@ -106,6 +107,7 @@ func _ready():
prd_module.unit_control.connect('update_max_value_progress', Callable(self, 'on_update_max_value_progress').bind(pribor_node))
prd_module.unit_control.connect('control_is_over', Callable(self, 'on_control_is_over'))
if item == 'уарэп-эмс':
uf_control = UFControl.new('уарэп-эмс')
signaller.connect('update_uf_serviceability', Callable(self, 'on_update_uf_serviceability').bind(pribor_node))
# Пиктограммы приборов, которые отображают состояние подключения только
@@ -114,7 +116,9 @@ func _ready():
var unit_instance: = network.get_unit_instance(unit_name)
var conn_node: = pribor_node.get_node('connect_pribor')
unit_instance.connect('line_changed', on_line_changed.bind(conn_node, unit_name))
signaller.conn(signaller.режим_работа, on_mode_changed)
signaller.conn(signaller.режим_журнал, on_mode_changed)
signaller.conn(signaller.режим_настройки, on_mode_changed)
@@ -169,8 +173,8 @@ func on_serviceability_changed(state: int, prd_pribor_node: Node)-> void:
prd_pribor_node.state = state
func on_update_uf_serviceability(uf_serviceaability: bool, uf_pribor: Node)-> void:
uf_pribor.state = 1 if uf_serviceaability else 2
func on_update_uf_serviceability(uf_serviceaability: int, uf_pribor: Node)-> void:
uf_pribor.state = uf_serviceaability
func _on_chk_show_functional_toggled(toggled_on: bool) -> void:

View File

@@ -420,7 +420,6 @@ func find_fs_index(aoa: float, freq: int, fs_index_arr: Array):
## Обновление состояния модулей формирователя сигналов
func update_fs_state(ecms, trenaz_mode: bool):
var time_now = Time.get_ticks_msec()
for fs in fs_dict.values(): ## Запрет модуляции для всех ФС
fs.set_modulation(false)
for ecm in ecms.values(): ## Выставление состояния помехи в ФС

View File

@@ -204,7 +204,7 @@ signal update_coordinates_map(new_coordinates)
## Вызывается при изменении исправности прибора УФ.[br]
## [param uf_serviceaability] - обновленное значение состояния исправности ([b]true[/b]
signal update_uf_serviceability(uf_serviceaability: bool)
signal update_uf_serviceability(uf_serviceaability: int)
signal tool_tip(new_ctrl_pos)