Files
uarep-ctl/scenes/pribor-prd-k/pribor-prd-k.gd
2025-08-11 14:51:49 +03:00

444 lines
17 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: Dictionary = {
'IN_BLANK_PRD': 1,
'OUT_BLANK_PRD': 13,
'CI_1_OT_FS': 8,
'CI_6_OT_FS': 13,
'CI_7_OT_FS': 14,
'CI_1_B_UF': 3,
'CI_6_B_UF': 4,
'CI_7_B_UF': 5,
'CONST_MIN_TEMP': -25,
'MAXIMUM_CODE_ADC': 3796,
'MINIMUM_CODE_AD': 2660,
'TEMPERATURE_UKP_1': 47,
'TEMPERATURE_UKP_2': 79,
'POWER_UKP_1': 31,
'POWER_UKP_2': 63,
'DKM_BIT_1': 0,
'DKM_BIT_6': 5,
'DKM_BIT_7': 6,
'BASE_ADDR_EMS_G': 0x120,
'ADDR_UG_LITERA_1': 0x106,
'ADDR_UG_LITERA_2': 0x108,
'ADDR_UG_LITERA_3': 0x10A,
'TEMP_THRESHOLD': 40,
'POWER_THRESHOLD': 40,
'TIMER_DELAY': 5.0,
'dou_ray_nuber': 0x6,
'attenutor_um_1': 0x7,
'attenutor_um_2': 0x7,
'attenutor_um_3': 0x0,
'POWER_UM': 75,
}
# Конфигурация параметров для каждого прибора
const PRIBOR_CONFIG := {
'1к': {'angle': 0.0, 'sectors': [0, 20, 24]},
'2к': {'angle': 90.0, 'sectors': [3, 23, 27]},
'3к': {'angle': 180.0, 'sectors': [2, 22, 26]},
'4к': {'angle': 270.0, 'sectors': [1, 21, 25]},
}
# Конфигурация частот и ширин для каждого ФС
const FS_PARAMS := {
1: {'freq': 450.0, 'width': 80.0},
6: {'freq': 2450.0, 'width': 110.0},
7: {'freq': 4750.0, 'width': 110.0}
}
enum STATE_VAL { NONE = 0, GOOD = 1, ERROR = 2 }
enum STATE_MASHINE {
INIT,
FS_TURN_ON,
FS_WORK,
UG_SET,
UM_RUN,
FS_TURN_OFF,
STOP_CONTROL,
AWAIT
}
var block_config_k := {
'maa2000_1': [0, false],
'maa2000_2': [1, false],
'ip9_50_1': [2, false],
'ip9_50_2': [3, false],
'ip12_50_1': [4, false],
'ip9_50_3': [5, false],
'ip12_50_2': [6, false],
}
var fs_mapping_k = {
0: { 'node': 'kasseta_fs_kd/ref_A3', 'condition': pribor == '1к' },
1: { 'node': 'kasseta_fs_kd/ref_A3', 'condition': pribor == '4к' },
2: { 'node': 'kasseta_fs_kd/ref_A3', 'condition': pribor == '3к' },
3: { 'node': 'kasseta_fs_kd/ref_A3', 'condition': pribor == '2к' },
20: { 'node': 'kasseta_fs_kd/ref_A6', 'condition': pribor == '1к' },
21: { 'node': 'kasseta_fs_kd/ref_A6', 'condition': pribor == '4к' },
22: { 'node': 'kasseta_fs_kd/ref_A6', 'condition': pribor == '3к' },
23: { 'node': 'kasseta_fs_kd/ref_A6', 'condition': pribor == '2к' },
24: { 'node': 'kasseta_fs_kd/ref_A5', 'condition': pribor == '1к' },
25: { 'node': 'kasseta_fs_kd/ref_A5', 'condition': pribor == '4к' },
26: { 'node': 'kasseta_fs_kd/ref_A5', 'condition': pribor == '3к' },
27: { 'node': 'kasseta_fs_kd/ref_A5', 'condition': pribor == '2к' },
}
# Основные переменные
var current_fs: int = 1
var state: int = STATE_MASHINE.INIT
var flag_check_dkm: bool = false
var flag_timer_started: bool = false
var count_packet_1:int = 0
var count_packet_6:int = 0
var count_packet_7:int = 0
var power_array_1: Array = []
var power_array_2: Array = []
var ug_work_1: int = 0
var ug_work_2: int = 0
var ug_work_3: int = 0
# Флаги и таймеры
var control_timer: Timer = Timer.new()
var mashine_timer: Timer = Timer.new()
var pribor: String
# Результаты контроля
var _control_results: Dictionary = {
'block_ip': false, # Проверка касет П1 и ИП МА2000
'temperature': true, # Проверка температур УМ
'dkm_1': false, # Проверка ДКМ 1
'dkm_6': false, # Проверка ДКМ 6
'dkm_7': false, # Проверка ДКМ 7
'power_ip': false, # Мощность от УКП
'fs_1': false, # Проверка ФС 1
'fs_6': false, # Проверка ФС 6
'fs_7': false, # Проверка ФС 7
}
static var node_common_func = load('res://scripts/pribor-prd.gd')
func _ready() -> void:
if Engine.is_editor_hint():
return
initialize_connections()
setup_timer()
set_default_state()
func on_state_mashine() -> void:
match state:
STATE_MASHINE.INIT:
if current_fs == 1 or current_fs == 6 or current_fs == 7:
state = STATE_MASHINE.FS_TURN_ON
else:
on_control_result()
state = STATE_MASHINE.AWAIT
STATE_MASHINE.FS_TURN_ON:
node_common_func.manage_fs(true, pribor, PRIBOR_CONFIG, FS_PARAMS, current_fs, Constants.POWER_UM)
control_timer.wait_time = Constants.TIMER_DELAY
control_timer.start()
state = STATE_MASHINE.FS_WORK
STATE_MASHINE.FS_WORK:
if (current_fs == 6 and flag_check_dkm and not flag_timer_started) or \
(current_fs == 7 and flag_check_dkm and not flag_timer_started) or \
(current_fs == 1 and not flag_timer_started):
state = STATE_MASHINE.UM_RUN
STATE_MASHINE.UM_RUN:
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.BASE_ADDR_EMS_G, 6666]])
flag_timer_started = true
state = STATE_MASHINE.UG_SET
STATE_MASHINE.UG_SET:
on_ug_setting()
state = STATE_MASHINE.FS_WORK
STATE_MASHINE.FS_TURN_OFF:
node_common_func.manage_fs(false, pribor, PRIBOR_CONFIG, FS_PARAMS, current_fs, Constants.POWER_UM)
power_control_result()
state = STATE_MASHINE.STOP_CONTROL
STATE_MASHINE.STOP_CONTROL:
flag_timer_started = false
flag_check_dkm = false
match current_fs:
1: current_fs = 6
6: current_fs = 7
7: current_fs = 0
state = STATE_MASHINE.INIT
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)
var current_unit = unit_prd.name
var parts = current_unit.split('-')
pribor = parts[-1]
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(mashine_timer)
mashine_timer.connect('timeout', Callable(self, 'on_state_mashine'))
mashine_timer.wait_time = 0.5
mashine_timer.start()
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 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 _enter_tree() -> void:
if Engine.is_editor_hint():
return
$control_result.text = ''
signaller.connect('режим_работа', Callable(self, 'on_mode_changed').bind(false))
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, Constants.ADDR_UG_LITERA_3, ug_work_3]])
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: PackedByteArray = unit_prd.status
# 1. Обновляем статусы блоков
block_config_k = node_common_func.check_block_ip(status, block_config_k)
# 2. Обновляем ноды power_supply
for power_supply in get_tree().get_nodes_in_group('power_supply'):
var meta_ip = power_supply.get_meta('ip')
if block_config_k.has(meta_ip):
power_supply.status = block_config_k[meta_ip][1]
node_common_func.check_temperature_um(status, get_tree().get_nodes_in_group('power_amplifier'))
# Обработка данных ЭМС
#_process_ems_data(status)
if current_fs == 1 and _control_results.fs_1:
flag_check_dkm = check_dkm(status, Constants.DKM_BIT_1)
elif current_fs == 6 and _control_results.fs_6:
flag_check_dkm = check_dkm(status, Constants.DKM_BIT_6)
elif current_fs == 7 and _control_results.fs_7:
flag_check_dkm = check_dkm(status, Constants.DKM_BIT_7)
if flag_check_dkm:
_process_ukp_power(status)
## Обрабатывает данные ЭМС и обновляет 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_6_OT_FS) & 1
#$Monitoring_panel/in_fs_2.frame = (in_blank >> Constants.CI_7_OT_FS) & 1
#$Monitoring_panel/in_fs_3.frame = (in_blank >> Constants.CI_1_OT_FS) & 1
#
## Обновление фреймов для выходных сигналов ЭМС
#$Monitoring_panel/out_ems_1.frame = (out_blank >> Constants.CI_6_B_UF) & 1
#$Monitoring_panel/out_ems_2.frame = (out_blank >> Constants.CI_7_B_UF) & 1
#$Monitoring_panel/out_ems_3.frame = (out_blank >> Constants.CI_1_B_UF) & 1
## Проверка ДКМ
func check_dkm(status_prd: PackedByteArray, bit_dkm: int) -> bool:
const DKM: int = 28
var status_dkm = status_prd[DKM] >> bit_dkm & 1
print(status_prd[DKM])
if bit_dkm == 5:
$dou6_A7.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
$kasseta_fs_kd/ref_A4.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
_control_results['dkm_6'] = status_dkm
elif bit_dkm == 6:
$dou7_A8.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
$kasseta_fs_kd/ref_A7.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
_control_results['dkm_7'] = status_dkm
elif bit_dkm == 0:
$kasseta_fs_kd/ref_A2.state = STATE_VAL.GOOD if status_dkm else STATE_VAL.ERROR
_control_results['dkm_1'] = status_dkm
return status_dkm
func _process_ukp_power(status: PackedByteArray) -> void:
var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
if current_fs == 1:
## Мощность от УМ (УКП) литеры 1
var arr_power_ukp_1: Array = []
var power_ukp_1: int
power_ukp_1 = status.decode_u16(Constants.POWER_UKP_1 + 2 * 7)
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]
power_amplifier[6].value1 = '%d' % power_array_1[0]
power_amplifier[6].state = STATE_VAL.GOOD if power_array_1[0] > Constants.TEMP_THRESHOLD else STATE_VAL.ERROR
count_packet_1 += 1
elif current_fs == 6:
## Мощность УМ от УКП 1
var arr_power_ukp_1: Array = []
if (status[0] >> 2) & 1:
var power_ukp_1: int
for i_power in range(6):
power_ukp_1 = status.decode_u16(Constants.POWER_UKP_1 + 2 * i_power)
arr_power_ukp_1.append(power_ukp_1)
if count_packet_6 == 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]
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.TEMP_THRESHOLD else STATE_VAL.ERROR
count_packet_6 += 1
elif current_fs == 7:
## Мощность УМ от УКП 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_7 == 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+7].value1 = '%d' % power_array_2[i]
power_amplifier[i+7].state = STATE_VAL.GOOD if power_array_2[i] > Constants.TEMP_THRESHOLD else STATE_VAL.ERROR
count_packet_7 += 1
func power_control_result() -> void:
var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
_control_results['power_ukp'] = true
for amp in power_amplifier:
if amp.state != STATE_VAL.GOOD:
_control_results['power_ukp'] = false
break
func on_stop_control() -> void:
state = STATE_MASHINE.FS_TURN_OFF
func on_fs_update_state(packet_type_7: Dictionary, fs_mapping: Dictionary) -> void:
# Словарь для маппинга: ключ - номер FS, значение - целевая нода и условие прибора
for fs in packet_type_7:
if fs in fs_mapping and fs_mapping[fs]['condition']:
var data = packet_type_7[fs]
if fs < 4 and current_fs == 1:
_control_results['fs_1'] = (data.isg == 1)
var state_fs = STATE_VAL.GOOD if data.isg == 1 else STATE_VAL.ERROR if data.isg == 0 else STATE_VAL.NONE
var node_name = fs_mapping[fs]['node']
var node = get_node(node_name)
node.state = state_fs
elif fs < 24 and current_fs == 6:
_control_results['fs_6'] = (data.isg == 1)
var state_fs = STATE_VAL.GOOD if data.isg == 1 else STATE_VAL.ERROR if data.isg == 0 else STATE_VAL.NONE
var node_name = fs_mapping[fs]['node']
var node = get_node(node_name)
node.state = state_fs
elif fs > 23 and current_fs == 7:
_control_results['fs_7'] = (data.isg == 1)
var state_fs = STATE_VAL.GOOD if data.isg == 1 else STATE_VAL.ERROR if data.isg == 0 else STATE_VAL.NONE
var node_name = fs_mapping[fs]['node']
var node = get_node(node_name)
node.state = state_fs
func on_ug_setting() -> void:
var unit_name = get_meta('unit_name')[0]
var unit_prd = network.units[unit_name]
var result_1 = ((Constants.attenutor_um_1 & 0x07) << 3) | (Constants.dou_ray_nuber & 0x07)
var result_2 = ((Constants.attenutor_um_2 & 0x07) << 3) | (Constants.dou_ray_nuber & 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_1,
Constants.ADDR_UG_LITERA_2, result_2,
Constants.ADDR_UG_LITERA_3, Constants.attenutor_um_3]])
prd_module.cmd_array.append([unit_prd.CmdCode.READ_ISA, [Constants.ADDR_UG_LITERA_1, Constants.ADDR_UG_LITERA_2, Constants.ADDR_UG_LITERA_3]])
func on_mode_changed(in_tree: bool) -> void:
if not in_tree:
queue_free()
func on_control_result() -> void:
#Обновляем _control_results['block_ip'] на основе block_config_k
var all_blocks_ok = true
for block in block_config_k:
if not block_config_k[block][1]: # Если хоть один блок false
all_blocks_ok = false
break
_control_results['block_ip'] = all_blocks_ok
# Словарь соответствия ключей ошибок и нод
var error_nodes := {
'fs_1': $kasseta_fs_kd/ref_A3,
'fs_6': $kasseta_fs_kd/ref_A6,
'fs_7': $kasseta_fs_kd/ref_A5
}
# Проверка результатов и установка состояний
var result: bool = true
for key in _control_results:
if not _control_results[key]:
result = false
if error_nodes.has(key):
error_nodes[key].state = STATE_VAL.ERROR
# Установка текста и цвета результата
var status_text := 'неисправен'
var status_color := Color.CRIMSON
if result:
status_text = 'исправен'
status_color = Color.AQUAMARINE
$control_result.text = 'Прибор ПРД-%s %s' % [pribor, status_text]
$control_result.add_theme_color_override('font_color', status_color)