Files
uarep-ctl/scenes/pribor-prd-v/pribor-prd-v.gd
2025-08-05 15:45:52 +03:00

375 lines
14 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@tool
extends "res://scenes/контроль/прибор.gd"
const Constants = {
'IN_BLANK_PRD': 1,
'OUT_BLANK_PRD': 13,
'CI_4_OT_FS': 11,
'CI_5_OT_FS': 12,
'CI_4_B_UF': 4,
'CI_5_B_UF': 5,
'POWER_UKP_1': 31,
'POWER_UKP_2': 63,
'DKM_BIT_3': 3,
'DKM_BIT_4': 4,
'ADDR_UG_LITERA_1': 0x106,
'ADDR_UG_LITERA_2': 0x108,
'TEMP_THRESHOLD': 70,
'POWER_THRESHOLD': 40,
'TIMER_DELAY': 1.4,
'POWER_UM': 70,
}
enum STATE_VAL { NONE = 0, GOOD = 1, ERROR = 2 }
# Основные переменные
var count_packet_1:int = 0
var count_packet_2:int = 0
var power_array_1: Array = []
var power_array_2: Array = []
var currecnt_unit: String
var ug_work_1: int
var ug_work_2: int
# Флаги и таймеры
var control_timer: Timer = Timer.new()
var flag_timer_started: bool = false
# Результаты контроля
var _control_results: Dictionary = {
'block_ip': false, # Проверка касет П1 и ИП МА2000
'temperature': true, # Проверка температур УМ
'dkm_1': false, # Проверка ДКМ
'dkm_2': false, # Проверка ДКМ
'power_ukp': false, # Мощность от УКП
'fs_1': false, # Проверка ФС
'fs_2': false,
}
func _ready() -> void:
initialize_connections()
setup_timer()
set_default_state()
func initialize_connections() -> void:
signaller.conn(signaller.fs_update_state, Callable(self, 'on_fs_update_state'))
var unit_name = get_meta('unit_name')[0]
var unit_prd = network.get_unit_instance(unit_name)
currecnt_unit = unit_prd.name
unit_prd.connect('data_received', Callable(self, 'on_data_received'))
unit_prd.connect('line_changed', Callable(self, 'on_line_changed'))
func setup_timer() -> void:
add_child(control_timer)
control_timer.connect('timeout', Callable(self, 'on_stop_control'))
control_timer.one_shot = true
control_timer.wait_time = 10.0
control_timer.start()
func _enter_tree() -> void:
$control_result.text = ''
signaller.connect('режим_работа', Callable(self, 'on_mode_changed').bind(false))
signaller.emit_signal('interfer_off_all')
await get_tree().create_timer(2.0).timeout
_on_control_fs(true)
func _exit_tree() -> void:
var unit_name = get_meta('unit_name')[0]
var unit_prd = network.get_unit_instance(unit_name)
var prd_module = prd.prd_dict[unit_prd.name]
prd_module.cmd_array.append([unit_prd.CmdCode.WRITE_ISA, [Constants.ADDR_UG_LITERA_1, ug_work_1, Constants.ADDR_UG_LITERA_2, ug_work_2]])
func set_default_state() -> void:
for group in get_tree().get_nodes_in_group('default_reset'):
group.state = STATE_VAL.NONE
for group in get_tree().get_nodes_in_group('power_amplifier'):
group.state = STATE_VAL.NONE
func on_line_changed(unit_prd: Object) -> void:
if not unit_prd.online:
set_default_state()
# Основной процесс по принятию и обработки пакетов
func on_data_received(unit_prd: Object) -> void:
if not is_inside_tree():
return
var status = unit_prd.status
check_block_ip(status)
check_temperature_um(status)
# Обработка данных ЭМС
_process_ems_data(status)
if flag_timer_started:
check_dkm(status, Constants.DKM_BIT_3)
check_dkm(status, Constants.DKM_BIT_4)
# Обработка мощности от УКП
_process_ukp_power(status)
## Проверка касет П1 и ИП МА2000
func check_block_ip(status_prd: PackedByteArray) -> void:
var ug_online: bool = (status_prd[0] >> 1) & 1
if not ug_online:
for node in [$maa2000_A23, $maa2000_A22, $kasseta_P_1/ref_A19, $kasseta_P_1/ref_A20, $kasseta_P_1/ref_A21]:
node.state = STATE_VAL.NONE
return
const BYTE_DRY_CONTACT: int = 27
const BIT_MAA2000_1: int = 0
const BIT_MAA2000_2: int = 1
const BIT_IP9_50_1: int = 2
const BIT_IP9_50_2: int = 3
const BIT_IP12_50_1: int = 4
var maa2000_1 = status_prd[BYTE_DRY_CONTACT] >> BIT_MAA2000_1 & 1
var maa2000_2 = status_prd[BYTE_DRY_CONTACT] >> BIT_MAA2000_2 & 1
var ip9_50_1 = status_prd[BYTE_DRY_CONTACT] >> BIT_IP9_50_1 & 1
var ip9_50_2 = status_prd[BYTE_DRY_CONTACT] >> BIT_IP9_50_2 & 1
var ip12_50_1 = status_prd[BYTE_DRY_CONTACT] >> BIT_IP12_50_1 & 1
$maa2000_A23.state = STATE_VAL.ERROR if maa2000_1 else STATE_VAL.GOOD
$maa2000_A22.state = STATE_VAL.ERROR if maa2000_2 else STATE_VAL.GOOD
$kasseta_P_1/ref_A19.state = STATE_VAL.ERROR if ip9_50_1 else STATE_VAL.GOOD
$kasseta_P_1/ref_A20.state = STATE_VAL.ERROR if ip9_50_2 else STATE_VAL.GOOD
$kasseta_P_1/ref_A21.state = STATE_VAL.ERROR if ip12_50_1 else STATE_VAL.GOOD
_control_results['block_ip'] = (
$maa2000_A23.state == STATE_VAL.GOOD and
$maa2000_A22.state == STATE_VAL.GOOD and
$kasseta_P_1/ref_A19.state == STATE_VAL.GOOD and
$kasseta_P_1/ref_A20.state == STATE_VAL.GOOD and
$kasseta_P_1/ref_A21.state == STATE_VAL.GOOD
)
## Проверка температур УМ от УКП
func check_temperature_um(status_prd: PackedByteArray) -> void:
const TEMP_CONSTANTS = {
'min_temp': -25,
'max_code': 3796,
'min_code': 2660,
'temp_factor': 115.0 / (3796 - 2660),
'offset': 3 # Корректировка температуры
}
const TEMPERATURE_UKP_1: int = 47
const TEMPERATURE_UKP_2: int = 79
var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
# Сбрас флагов перед проверкой
_control_results['temperature'] = true
var ukp1_online: int = (status_prd[0] >> 2) & 1
if ukp1_online:
for i_temp in range(6):
var temperature_ukp_1: int = status_prd.decode_u16(TEMPERATURE_UKP_1 + 2 * i_temp)
var tmp_1: int = round(TEMP_CONSTANTS['min_temp'] + (TEMP_CONSTANTS['max_code'] - temperature_ukp_1) * TEMP_CONSTANTS['temp_factor'] + TEMP_CONSTANTS['offset'])
power_amplifier[i_temp].value0 = tmp_1
if tmp_1 > Constants.TEMP_THRESHOLD:
_control_results['temperature'] = false
var ukp2_online = (status_prd[0] >> 3) & 1
if ukp2_online:
for i_temp in range(6):
var temperature_ukp_2: int = status_prd.decode_u16(TEMPERATURE_UKP_2 + 2 * i_temp)
var tmp_2: int = round(TEMP_CONSTANTS['min_temp'] + (TEMP_CONSTANTS['max_code'] - temperature_ukp_2) * TEMP_CONSTANTS['temp_factor'] + TEMP_CONSTANTS['offset'])
power_amplifier[i_temp+6].value0 = tmp_2
if tmp_2 > Constants.TEMP_THRESHOLD:
_control_results['temperature'] = false
## Проверка ДКМ
func check_dkm(status_prd: PackedByteArray, bit_dkm: int) -> void:
const DKM: int = 28
var status_dkm = status_prd[DKM] >> bit_dkm & 1
if bit_dkm == Constants.DKM_BIT_3:
$dou5_A6.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
$kasseta_FS_VD/ref_A2.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
_control_results['dkm_1'] = status_dkm
elif bit_dkm == Constants.DKM_BIT_4:
$dou4_A5.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
$kasseta_FS_VD/ref_A6.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
_control_results['dkm_2'] = status_dkm
# Обрабатывает данные ЭМС и обновляет UI панели
func _process_ems_data(status: PackedByteArray) -> void:
## Контроль ЭМС
var in_blank: int = status.decode_u16(Constants.IN_BLANK_PRD)
var out_blank: int = status.decode_u16(Constants.OUT_BLANK_PRD)
# Обновление фреймов для входных сигналов
$Monitoring_panel/in_fs_1.frame = (in_blank >> Constants.CI_4_OT_FS) & 1
$Monitoring_panel/in_fs_2.frame = (in_blank >> Constants.CI_5_OT_FS) & 1
# Обновление фреймов для выходных сигналов ЭМС
$Monitoring_panel/out_ems_1.frame = (out_blank >> Constants.CI_4_B_UF) & 1
$Monitoring_panel/out_ems_2.frame = (out_blank >> Constants.CI_5_B_UF) & 1
func _process_ukp_power(status: PackedByteArray) -> void:
## Мощность УМ от УКП 1
var arr_power_ukp_1: Array = []
if (status[0] >> 2) & 1:
for i_power in range(6):
var power_ukp_1 = status.decode_u16(Constants.POWER_UKP_1 + 2 * i_power)
arr_power_ukp_1.append(power_ukp_1)
if count_packet_1 == 0:
power_array_1 = arr_power_ukp_1
else:
for i in arr_power_ukp_1.size():
if arr_power_ukp_1[i] > power_array_1[i]:
power_array_1[i] = arr_power_ukp_1[i]
var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
for i in 6:
power_amplifier[i].value1 = '%d' % power_array_1[i]
power_amplifier[i].state = STATE_VAL.GOOD if power_array_1[i] > Constants.POWER_THRESHOLD else STATE_VAL.ERROR
count_packet_1 += 1
## Мощность УМ от УКП 2
var arr_power_ukp_2: Array = []
if (status[0] >> 2) & 1:
for i_power in range(6):
var power_ukp_2 = status.decode_u16(Constants.POWER_UKP_2 + 2 * i_power)
arr_power_ukp_2.append(power_ukp_2)
if count_packet_2 == 0:
power_array_2 = arr_power_ukp_2
else:
for i in arr_power_ukp_2.size():
if arr_power_ukp_2[i] > power_array_2[i]:
power_array_2[i] = arr_power_ukp_2[i]
for i in 6:
power_amplifier[i+6].value1 = '%d' % power_array_2[i]
power_amplifier[i+6].state = STATE_VAL.GOOD if power_array_2[i] > Constants.POWER_THRESHOLD else STATE_VAL.ERROR
count_packet_2 += 1
_control_results['power_ukp'] = true
for amp in power_amplifier:
if amp.state != STATE_VAL.GOOD:
_control_results['power_ukp'] = false
break
func _on_control_fs(mode: bool) -> void:
var parts = currecnt_unit.split('-')
var last_part = parts[-1]
var angle: float = 0.0 # -> ПРД-В1; 90.0 -> ПРД-В2; 180.0 -> ПРД-В3; 270.0 -> ПРД-В4
var sector_1: float = 12 # -> ПРД-В1; 15 -> ПРД-В2; 14 -> ПРД-В3; 13 -> ПРД-В4;
var sector_2: float = 16 # -> ПРД-В1; 19 -> ПРД-В2; 18 -> ПРД-В3; 17 -> ПРД-В4;
if last_part == '2в':
angle = 90.0
sector_1 = 15
sector_2 = 19
elif last_part == '3в':
angle = 180.0
sector_1 = 14
sector_2 = 18
elif last_part == '4в':
angle = 270.0
sector_1 = 13
sector_2 = 17
var interfer_name: String = 'k1' if mode else 'off'
var freq_1: float = 1227.0 # ФС_1
var freq_2: float = 1575.0 # ФС_2
var hz_1: float = 340.0 # ФС_1
var hz_2: float = 510.0 # ФС_2
var fs_arr: Array = [[angle, freq_1, hz_1, sector_1], [angle, freq_2, hz_2, sector_2]]
signaller.emit_signal('interfer_init', interfer_name, fs_arr, Constants.POWER_UM)
func on_stop_control() -> void:
print_debug('Остановка контроля ПРД')
_on_control_fs(false)
on_control_result()
func on_fs_update_state(packet_type_7: Dictionary) -> void:
var parts = currecnt_unit.split('-')
var last_part = parts[-1] # Прибор
# Словарь для маппинга: ключ - номер FS, значение - целевая нода и условие прибора
var fs_mapping = {
12: { 'node': $kasseta_FS_VD/ref_A3, 'condition': last_part == '1в' },
13: { 'node': $kasseta_FS_VD/ref_A3, 'condition': last_part == '4в' },
14: { 'node': $kasseta_FS_VD/ref_A3, 'condition': last_part == '3в' },
15: { 'node': $kasseta_FS_VD/ref_A3, 'condition': last_part == '2в' },
16: { 'node': $kasseta_FS_VD/ref_A4, 'condition': last_part == '1в' },
17: { 'node': $kasseta_FS_VD/ref_A4, 'condition': last_part == '4в' },
18: { 'node': $kasseta_FS_VD/ref_A4, 'condition': last_part == '3в' },
19: { 'node': $kasseta_FS_VD/ref_A4, 'condition': last_part == '2в' }
}
for fs in packet_type_7:
if fs in fs_mapping and fs_mapping[fs]['condition']:
var data = packet_type_7[fs]
var state = STATE_VAL.GOOD if data.isg == 1 else STATE_VAL.ERROR if data.isg == 0 else STATE_VAL.NONE
fs_mapping[fs]['node'].state = state
if fs < 16:
_control_results['fs_1'] = (data.isg == 1)
else:
_control_results['fs_2'] = (data.isg == 1)
if _control_results['fs_1'] and _control_results['fs_2'] and not flag_timer_started:
on_ug_setting()
control_timer.wait_time = Constants.TIMER_DELAY
control_timer.start()
flag_timer_started = true
func on_ug_setting() -> void:
var unit_name = get_meta('unit_name')[0]
var unit_prd = network.units[unit_name]
if unit_prd.isa_ports.has(Constants.ADDR_UG_LITERA_1):
ug_work_1 = unit_prd.isa_ports[Constants.ADDR_UG_LITERA_1]
if unit_prd.isa_ports.has(Constants.ADDR_UG_LITERA_2):
ug_work_2 = unit_prd.isa_ports[Constants.ADDR_UG_LITERA_2]
const dou = 0x3
const att = 0x7
var result = ((att & 0x07) << 3) | (dou & 0x07)
var prd_module = prd.prd_dict[unit_prd.name]
prd_module.cmd_array.append([unit_prd.CmdCode.WRITE_ISA, [Constants.ADDR_UG_LITERA_1, result, Constants.ADDR_UG_LITERA_2, result, 0x120, 6666]])
func on_mode_changed(in_tree: bool) -> void:
if not in_tree:
queue_free()
func on_control_result() -> void:
var result: bool = true
for key in _control_results:
if not _control_results[key]:
if key == 'fs_1':
$kasseta_FS_VD/ref_A3.state = STATE_VAL.ERROR
if key == 'fs_2':
$kasseta_FS_VD/ref_A4.state = STATE_VAL.ERROR
result = false
print_debug('%s false' % key)
var parts = currecnt_unit.split('-')
var last_part = parts[-1] # Прибор
if result:
$control_result.text = 'Прибор ПРД-%s исправен' % last_part
$control_result.add_theme_color_override("font_color", Color.AQUAMARINE)
else:
$control_result.text = 'Прибор ПРД-%s неисправен' % last_part
$control_result.add_theme_color_override("font_color", Color.CRIMSON)
await get_tree().create_timer(Constants.TIMER_DELAY).timeout
flag_timer_started = false