Доработка работы с ecms в контроле + форматирование пробелов

This commit is contained in:
TotMaxim
2025-11-25 12:31:45 +03:00
parent 5eb44fd20a
commit bfb9d3a4e8
11 changed files with 234 additions and 207 deletions

View File

@@ -119,9 +119,13 @@ func on_interfer_new(ecm, table_index):
$table.set_row_editable(i_row, false) $table.set_row_editable(i_row, false)
$table.set_node_user_data(0, i_row, ecm) $table.set_node_user_data(0, i_row, ecm)
table_index[ecm.ispp] = i_row table_index[ecm.ispp] = i_row
$table.cleanup_invalid_selectors()
# Будем надеяться, что отложенные вызовы производятся в том же порядке # Будем надеяться, что отложенные вызовы производятся в том же порядке
$table.call_deferred('clear_rows_selected') var selected_rows = []
$table.call_deferred('set_row_selected', i_row, true) $table.get_selected_rows(selected_rows)
for old_row in selected_rows:
$table.set_row_selected(old_row, false)
$table.set_row_selected(i_row, true)
if not interfer.auto_enabled: if not interfer.auto_enabled:
signaller.emit_signal('interfer_selected', ecm) signaller.emit_signal('interfer_selected', ecm)

View File

@@ -75,7 +75,7 @@ func on_threat_update(th, table_index: Dictionary):
elif th.emit_state == 2: elif th.emit_state == 2:
emit_txr.visible = true emit_txr.visible = true
emit_txr.self_modulate = Color.RED emit_txr.self_modulate = Color.RED
## Обрабатывает сигнал [b]threat_lost[/b]. ## Обрабатывает сигнал [b]threat_lost[/b].

View File

@@ -44,6 +44,7 @@ func _on_start_control() -> void:
set_default_state(get_tree().get_nodes_in_group('default_reset')) set_default_state(get_tree().get_nodes_in_group('default_reset'))
set_default_state(get_tree().get_nodes_in_group('power_amplifier')) set_default_state(get_tree().get_nodes_in_group('power_amplifier'))
find_labels(self) find_labels(self)
await get_tree().create_timer(1.0).timeout
on_press_device(unit_prd_k.self_name) on_press_device(unit_prd_k.self_name)
@@ -98,7 +99,7 @@ static func power_fill(pow_dic: Dictionary, fs_result: Dictionary, power_amplifi
if i_p >= 1: if i_p >= 1:
all_below_one = false all_below_one = false
break break
if all_below_one: if all_below_one:
status = STATE_VAL.NONE status = STATE_VAL.NONE
else: else:
@@ -164,7 +165,7 @@ static func on_control_result(for_result_dic: Dictionary) -> void:
if power_supply.state == STATE_VAL.ERROR: if power_supply.state == STATE_VAL.ERROR:
all_y5_good = false all_y5_good = false
if not for_result_dic.control_is_over: if not for_result_dic.control_is_over:
set_default_state(for_result_dic.default_reset_array_node) set_default_state(for_result_dic.default_reset_array_node)
set_default_state(for_result_dic.power_amplifier) set_default_state(for_result_dic.power_amplifier)
return return
@@ -185,7 +186,7 @@ static func on_control_result(for_result_dic: Dictionary) -> void:
if result_dic.fs_7 == 1 and block_kasseta_y5_prd_config_k['yau07']: if result_dic.fs_7 == 1 and block_kasseta_y5_prd_config_k['yau07']:
for_result_dic.module_fs_7.state = STATE_VAL.GOOD if result_dic.dkm_7 else STATE_VAL.ERROR for_result_dic.module_fs_7.state = STATE_VAL.GOOD if result_dic.dkm_7 else STATE_VAL.ERROR
for_result_dic.dou_7.state = STATE_VAL.GOOD if result_dic.dou_7 else STATE_VAL.ERROR for_result_dic.dou_7.state = STATE_VAL.GOOD if result_dic.dou_7 else STATE_VAL.ERROR
if block_kasseta_y5_prd_config_k['yau07']: if block_kasseta_y5_prd_config_k['yau07']:
power_fill(for_result_dic.power_dic, for_result_dic.result_dic, for_result_dic.power_amplifier, for_result_dic.POWER_THRESHOLD) power_fill(for_result_dic.power_dic, for_result_dic.result_dic, for_result_dic.power_amplifier, for_result_dic.POWER_THRESHOLD)

View File

@@ -44,6 +44,7 @@ func _on_start_control() -> void:
for um in get_tree().get_nodes_in_group('power_amplifier'): for um in get_tree().get_nodes_in_group('power_amplifier'):
um.value0 = [0, 0, 0, 0, 0, 0] um.value0 = [0, 0, 0, 0, 0, 0]
find_labels(self) find_labels(self)
await get_tree().create_timer(1.0).timeout
on_press_device(unit_prd_n.self_name) on_press_device(unit_prd_n.self_name)
@@ -87,16 +88,16 @@ static func power_fill(pow_dic: Dictionary, fs_result: Dictionary, power_amplifi
if i_p >= 1: if i_p >= 1:
all_below_one = false all_below_one = false
break break
if all_below_one: if all_below_one:
i_node_powapm.state = STATE_VAL.NONE i_node_powapm.state = STATE_VAL.NONE
continue continue
var count_above_threshold = 0 var count_above_threshold = 0
for i_p in pow_dic[powamp_meta]: for i_p in pow_dic[powamp_meta]:
if i_p >= POWER_THRESHOLD: if i_p >= POWER_THRESHOLD:
count_above_threshold += 1 count_above_threshold += 1
status = STATE_VAL.GOOD if count_above_threshold >= 3 else STATE_VAL.ERROR status = STATE_VAL.GOOD if count_above_threshold >= 3 else STATE_VAL.ERROR
i_node_powapm.state = status i_node_powapm.state = status
@@ -142,7 +143,7 @@ static func on_control_result(for_result_dic: Dictionary) -> void:
# Проверяем состояние после установки # Проверяем состояние после установки
if node_y5.state == STATE_VAL.ERROR: if node_y5.state == STATE_VAL.ERROR:
all_y5_good = false all_y5_good = false
var block_ip_config_n: Dictionary = for_result_dic.block_ip_config var block_ip_config_n: Dictionary = for_result_dic.block_ip_config
for power_supply in for_result_dic.node_ip_power_arr: for power_supply in for_result_dic.node_ip_power_arr:
var meta_ip = power_supply.get_meta('ip') var meta_ip = power_supply.get_meta('ip')
@@ -153,8 +154,8 @@ static func on_control_result(for_result_dic: Dictionary) -> void:
# Проверяем состояние после установки # Проверяем состояние после установки
if power_supply.state == STATE_VAL.ERROR: if power_supply.state == STATE_VAL.ERROR:
all_y5_good = false all_y5_good = false
if not for_result_dic.control_is_over: if not for_result_dic.control_is_over:
set_default_state(for_result_dic.default_reset_array_node) set_default_state(for_result_dic.default_reset_array_node)
set_default_state(for_result_dic.power_amplifier) set_default_state(for_result_dic.power_amplifier)
return return
@@ -172,7 +173,7 @@ static func on_control_result(for_result_dic: Dictionary) -> void:
if result_dic.fs_3 == 1 and block_kasseta_y5_prd_config_n['yau07']: if result_dic.fs_3 == 1 and block_kasseta_y5_prd_config_n['yau07']:
for_result_dic.module_fs_3.state = STATE_VAL.GOOD if result_dic.dkm_3 else STATE_VAL.ERROR for_result_dic.module_fs_3.state = STATE_VAL.GOOD if result_dic.dkm_3 else STATE_VAL.ERROR
for_result_dic.dou_3.state = STATE_VAL.GOOD if result_dic.dou_3 else STATE_VAL.ERROR for_result_dic.dou_3.state = STATE_VAL.GOOD if result_dic.dou_3 else STATE_VAL.ERROR
if block_kasseta_y5_prd_config_n['yau07']: if block_kasseta_y5_prd_config_n['yau07']:
power_fill(for_result_dic.power_dic, for_result_dic.result_dic, for_result_dic.power_amplifier, for_result_dic.POWER_THRESHOLD) power_fill(for_result_dic.power_dic, for_result_dic.result_dic, for_result_dic.power_amplifier, for_result_dic.POWER_THRESHOLD)

View File

@@ -44,6 +44,7 @@ func _on_start_control() -> void:
for um in get_tree().get_nodes_in_group('power_amplifier'): for um in get_tree().get_nodes_in_group('power_amplifier'):
um.value0 = [0, 0, 0, 0, 0, 0] um.value0 = [0, 0, 0, 0, 0, 0]
find_labels(self) find_labels(self)
await get_tree().create_timer(1.0).timeout
on_press_device(unit_prd_v.self_name) on_press_device(unit_prd_v.self_name)
@@ -87,7 +88,7 @@ static func power_fill(pow_dic: Dictionary, fs_result: Dictionary, power_amplifi
if i_p >= 1: if i_p >= 1:
all_below_one = false all_below_one = false
break break
if all_below_one: if all_below_one:
i_node_powapm.state = STATE_VAL.NONE i_node_powapm.state = STATE_VAL.NONE
continue continue
@@ -95,7 +96,7 @@ static func power_fill(pow_dic: Dictionary, fs_result: Dictionary, power_amplifi
for i_p in pow_dic[powamp_meta]: for i_p in pow_dic[powamp_meta]:
if i_p >= POWER_THRESHOLD: if i_p >= POWER_THRESHOLD:
count_above_threshold += 1 count_above_threshold += 1
status = STATE_VAL.GOOD if count_above_threshold >= 3 else STATE_VAL.ERROR status = STATE_VAL.GOOD if count_above_threshold >= 3 else STATE_VAL.ERROR
i_node_powapm.state = status i_node_powapm.state = status
@@ -153,7 +154,7 @@ static func on_control_result(for_result_dic: Dictionary) -> void:
if power_supply.state == STATE_VAL.ERROR: if power_supply.state == STATE_VAL.ERROR:
all_y5_good = false all_y5_good = false
if not for_result_dic.control_is_over: if not for_result_dic.control_is_over:
set_default_state(for_result_dic.default_reset_array_node) set_default_state(for_result_dic.default_reset_array_node)
set_default_state(for_result_dic.power_amplifier) set_default_state(for_result_dic.power_amplifier)
return return
@@ -167,11 +168,11 @@ static func on_control_result(for_result_dic: Dictionary) -> void:
if result_dic.fs_5 == 1 and block_kasseta_y5_prd_config_v['yau07']: if result_dic.fs_5 == 1 and block_kasseta_y5_prd_config_v['yau07']:
for_result_dic.module_fs_5.state = STATE_VAL.GOOD if result_dic.dkm_5 else STATE_VAL.ERROR for_result_dic.module_fs_5.state = STATE_VAL.GOOD if result_dic.dkm_5 else STATE_VAL.ERROR
for_result_dic.dou_5.state = STATE_VAL.GOOD if result_dic.dou_5 else STATE_VAL.ERROR for_result_dic.dou_5.state = STATE_VAL.GOOD if result_dic.dou_5 else STATE_VAL.ERROR
if result_dic.fs_4 == 1 and block_kasseta_y5_prd_config_v['yau07']: if result_dic.fs_4 == 1 and block_kasseta_y5_prd_config_v['yau07']:
for_result_dic.module_fs_4.state = STATE_VAL.GOOD if result_dic.dkm_4 else STATE_VAL.ERROR for_result_dic.module_fs_4.state = STATE_VAL.GOOD if result_dic.dkm_4 else STATE_VAL.ERROR
for_result_dic.dou_4.state = STATE_VAL.GOOD if result_dic.dou_4 else STATE_VAL.ERROR for_result_dic.dou_4.state = STATE_VAL.GOOD if result_dic.dou_4 else STATE_VAL.ERROR
if block_kasseta_y5_prd_config_v['yau07']: if block_kasseta_y5_prd_config_v['yau07']:
power_fill(for_result_dic.power_dic, for_result_dic.result_dic, for_result_dic.power_amplifier, for_result_dic.POWER_THRESHOLD) power_fill(for_result_dic.power_dic, for_result_dic.result_dic, for_result_dic.power_amplifier, for_result_dic.POWER_THRESHOLD)

View File

@@ -20,9 +20,9 @@ func _ready() -> void:
func on_timer(unit_name: StringName): func on_timer(unit_name: StringName):
var unit_uf = network.get_unit_instance(unit_name) var unit_uf = network.get_unit_instance(unit_name)
status_uf() # отслеживание состояния прибора
if unit_uf.online: # проверка ЯУ, внутреннего коммутатора и ИП-5Б if unit_uf.online: # проверка ЯУ, внутреннего коммутатора и ИП-5Б
control_ems(unit_uf.status) # проверка ЭМС ячеек control_ems(unit_uf.status) # проверка ЭМС ячеек
status_uf() # отслеживание состояния прибора
func on_line_changed(unit_uf): func on_line_changed(unit_uf):

View File

@@ -171,11 +171,11 @@ func on_serviceability_changed(prd_module: Object, prd_pribor:Node)-> void:
prd_pribor.state = STATE_DEVICE.NONE prd_pribor.state = STATE_DEVICE.NONE
return return
print([prd_pribor.get_meta('unit_name'), prd_module.unit_control.current_status]) print([prd_pribor.get_meta('unit_name'), prd_module.unit_control.current_status])
if prd_module.unit_control.flag_control_is_over: if prd_module.unit_control.control_is_over:
var control_results = prd_module.unit_control.get_control_results() var control_results = prd_module.unit_control.get_control_results()
var result_dic = control_results.result_dic var result_dic = control_results.result_dic
# Проверяем только основные устройства # Проверяем только основные устройства
var critical_devices = ['fs_1', 'fs_2', 'fs_3', 'fs_4', 'fs_5', 'fs_6', 'fs_7', var critical_devices = ['fs_1', 'fs_2', 'fs_3', 'fs_4', 'fs_5', 'fs_6', 'fs_7',
'dkm_1', 'dkm_2', 'dkm_3', 'dkm_4', 'dkm_5', 'dkm_6', 'dkm_7', 'dkm_1', 'dkm_2', 'dkm_3', 'dkm_4', 'dkm_5', 'dkm_6', 'dkm_7',
'block_ip', 'dou_2', 'dou_3', 'dou_4', 'dou_5', 'dou_6', 'dou_7'] 'block_ip', 'dou_2', 'dou_3', 'dou_4', 'dou_5', 'dou_6', 'dou_7']
# Проверяем результаты контроля напрямую # Проверяем результаты контроля напрямую
@@ -185,7 +185,7 @@ func on_serviceability_changed(prd_module: Object, prd_pribor:Node)-> void:
if not result_dic[device_key]: if not result_dic[device_key]:
all_ok = false all_ok = false
break break
prd_pribor.state = STATE_DEVICE.GOOD if all_ok else STATE_DEVICE.ERROR prd_pribor.state = STATE_DEVICE.GOOD if all_ok else STATE_DEVICE.ERROR
elif not prd_module.serviceability: elif not prd_module.serviceability:
prd_pribor.state = STATE_DEVICE.ERROR prd_pribor.state = STATE_DEVICE.ERROR

View File

@@ -78,15 +78,15 @@ func get_data_index(key: String) -> int:
#region PRIVATE_METHODS #region PRIVATE_METHODS
## Загружает конфигурацию из JSON файла ## Загружает конфигурацию из JSON файла
func _load_configuration() -> void: func _load_configuration() -> void:
if not _ensure_config_exists(): if not _ensure_config_exists():
_is_loaded = false _is_loaded = false
return return
var config_file = FileAccess.open(CONFIG_PATH, FileAccess.READ) var config_file = FileAccess.open(CONFIG_PATH, FileAccess.READ)
if config_file: if config_file:
var json_text = config_file.get_as_text() var json_text = config_file.get_as_text()
config_file.close() config_file.close()
var json = JSON.new() var json = JSON.new()
var parse_result = json.parse(json_text) var parse_result = json.parse(json_text)
if parse_result == OK: if parse_result == OK:
@@ -139,21 +139,21 @@ static func _convert_numbers(value):
func _ensure_config_exists() -> bool: func _ensure_config_exists() -> bool:
# Создаем папку конфигурации если не существует # Создаем папку конфигурации если не существует
DirAccess.make_dir_recursive_absolute("user://config") DirAccess.make_dir_recursive_absolute("user://config")
# Если файл уже существует - все ок # Если файл уже существует - все ок
if FileAccess.file_exists(CONFIG_PATH): if FileAccess.file_exists(CONFIG_PATH):
return true return true
# Если дефолтного файла нет - ошибка # Если дефолтного файла нет - ошибка
if not FileAccess.file_exists(DEFAULT_CONFIG_PATH): if not FileAccess.file_exists(DEFAULT_CONFIG_PATH):
return false return false
# Копируем дефолтный конфиг в user директорию # Копируем дефолтный конфиг в user директорию
var src := FileAccess.open(DEFAULT_CONFIG_PATH, FileAccess.READ) var src := FileAccess.open(DEFAULT_CONFIG_PATH, FileAccess.READ)
var dst := FileAccess.open(CONFIG_PATH, FileAccess.WRITE) var dst := FileAccess.open(CONFIG_PATH, FileAccess.WRITE)
if src == null or dst == null: if src == null or dst == null:
return false return false
dst.store_string(src.get_as_text()) dst.store_string(src.get_as_text())
src.close() src.close()
dst.close() dst.close()

View File

@@ -231,7 +231,7 @@ class PRD:
var ukp_1_online = (unit_yau07.status[0] >> 2) & 1 var ukp_1_online = (unit_yau07.status[0] >> 2) & 1
var ukp_2_online = (unit_yau07.status[0] >> 3) & 1 var ukp_2_online = (unit_yau07.status[0] >> 3) & 1
var ems_g_online = (unit_yau07.status[0] & 1) & 1 var ems_g_online = (unit_yau07.status[0] & 1) & 1
var bit_ip_config: Array = [0, 1, 2, 3, 4, 5, 6, 7] var bit_ip_config: Array = [0, 1, 2, 3, 4, 5, 6, 7]
var ip_online: bool = true var ip_online: bool = true
var is_k_type: bool = prd_name in ['уарэп-яу07-1к', 'уарэп-яу07-2к', 'уарэп-яу07-3к', 'уарэп-яу07-4к'] var is_k_type: bool = prd_name in ['уарэп-яу07-1к', 'уарэп-яу07-2к', 'уарэп-яу07-3к', 'уарэп-яу07-4к']
for bit in bit_ip_config: for bit in bit_ip_config:
@@ -242,7 +242,7 @@ class PRD:
if status: if status:
ip_online = false ip_online = false
break break
var check_serviceability = ug_online and ukp_1_online and ukp_2_online and ems_g_online and ip_online var check_serviceability = ug_online and ukp_1_online and ukp_2_online and ems_g_online and ip_online
if serviceability != check_serviceability: if serviceability != check_serviceability:
serviceability = check_serviceability serviceability = check_serviceability
@@ -289,7 +289,7 @@ class PRD:
func set_um(data_arr): func set_um(data_arr):
cmd_array.append([unit_yau07.CmdCode.WRITE_ISA, data_arr]) cmd_array.append([unit_yau07.CmdCode.WRITE_ISA, data_arr])
func _on_control_completed(_unit_control_name: String)->void: func _on_control_completed(_unit_control_name: String)->void:
emit_signal('update_serviceability') emit_signal('update_serviceability')
@@ -310,7 +310,7 @@ func _ready() -> void:
if prd_dict.has(fs.prd_name): if prd_dict.has(fs.prd_name):
prd_dict[fs.prd_name].fs_dic[key] = fs prd_dict[fs.prd_name].fs_dic[key] = fs
fs.connect('update_modulation', prd_dict[fs.prd_name].on_update_modulation.bind(fs.index)) fs.connect('update_modulation', prd_dict[fs.prd_name].on_update_modulation.bind(fs.index))
for key in FS_PRD.keys(): for key in FS_PRD.keys():
fs_caps_id[FS_PRD[key][1]] = key fs_caps_id[FS_PRD[key][1]] = key
var unit_caps = network.get_unit_instance('уарэп-капсрпб') var unit_caps = network.get_unit_instance('уарэп-капсрпб')

View File

@@ -17,7 +17,7 @@ const PROGRESS_COMPLETE: float = 100.0
const RAY_MASK = 0x07 const RAY_MASK = 0x07
const SPECIAL_LITERAS = [3, 5, 7] const SPECIAL_LITERAS = [3, 5, 7]
const RAY_m5: String = 'RAY_m5' const RAY_m5: String = 'RAY_m5'
const RAY_5: String = 'RAY_5' const RAY_5: String = 'RAY_5'
const RAY_15: String = 'RAY_15' const RAY_15: String = 'RAY_15'
const RAY_25: String = 'RAY_25' const RAY_25: String = 'RAY_25'
const RAY_35: String = 'RAY_35' const RAY_35: String = 'RAY_35'
@@ -33,7 +33,21 @@ const RAY_CONFIG = {
5: { 'state': 'UG_SET_RAY_5', 'name': '45°'}, 5: { 'state': 'UG_SET_RAY_5', 'name': '45°'},
6: { 'state': 'UG_SET_RAY_0', 'name': 'Контроль'} # ДКМ 6: { 'state': 'UG_SET_RAY_0', 'name': 'Контроль'} # ДКМ
} }
# Таблица соответствий: device_name -> (current_lit -> nmfs в ecms)
const LITER_TO_NMFS: Dictionary = {
'': {1: 11, 6: 16, 7: 17},
'': {1: 21, 6: 26, 7: 27},
'': {1: 31, 6: 36, 7: 37},
'': {1: 41, 6: 46, 7: 47},
'': {2: 12, 3: 13},
'': {2: 22, 3: 23},
'': {2: 32, 3: 33},
'': {2: 42, 3: 43},
'': {4: 14, 5: 15},
'': {4: 24, 5: 25},
'': {4: 34, 5: 35},
'': {4: 44, 5: 45}
}
const RAY_TYPES := [RAY_m5, RAY_5, RAY_15, RAY_25, RAY_35, RAY_45] const RAY_TYPES := [RAY_m5, RAY_5, RAY_15, RAY_25, RAY_35, RAY_45]
const DATA_EXIT_CONTOL_ISA: int = 0 const DATA_EXIT_CONTOL_ISA: int = 0
@@ -105,17 +119,21 @@ var self_name: String
var state: int = STATE_MACHINE.INIT var state: int = STATE_MACHINE.INIT
var current_litera: int var current_litera: int
var count_packets_power: int = 0 var count_packets_power: int = 0
var current_ecm_key: int
## Флаги состояния системы ## Флаги состояния системы
var flag_write_isa: bool = false var flags: Dictionary = {
var flag_fs_status_ok: bool = false 'write_isa': false,
var flag_si_fs_input: bool = false 'fs_status_ok': false,
var flag_si_fs_output: bool = false 'si_fs_input': false,
var flag_in_control: bool = false 'si_fs_output': false,
var flag_control_is_over: bool = false 'in_control': false,
var flag_no_trust_yau07: bool = false 'control_is_over': false,
var flag_only_fs: bool = false 'no_trust_yau07': false,
var flag_temperature_ok: bool = true 'only_fs': false,
'ecm_is_comming': false,
'temperature_ok': true,
}
## Таймеры контроля ## Таймеры контроля
var control_timer: Timer = Timer.new() var control_timer: Timer = Timer.new()
@@ -163,42 +181,36 @@ func _init(init_data: Dictionary, cmd_array_from_prd: Array) -> void:
func _initialize_default_states() -> void: func _initialize_default_states() -> void:
_default_states = { _default_states = {
# Флаги состояния системы # Флаги состояния системы
'flag_write_isa': flag_write_isa, 'flags': flags.duplicate(true),
'flag_fs_status_ok': flag_fs_status_ok,
'flag_si_fs_input': flag_si_fs_input,
'flag_si_fs_output': flag_si_fs_output,
'flag_control_is_over': flag_control_is_over,
'flag_no_trust_yau07': flag_no_trust_yau07,
'flag_only_fs': flag_only_fs,
# Состояние машины и литеры # Состояние машины и литеры
'state': state, 'state': state,
'current_litera': current_litera, 'current_litera': current_litera,
# Переменные прогресса # Переменные прогресса
'progress_value': progress_value, 'progress_value': progress_value,
'current_status': current_status, 'current_status': current_status,
'total_fs_to_check': total_fs_to_check, 'total_fs_to_check': total_fs_to_check,
'completed_fs_count': completed_fs_count, 'completed_fs_count': completed_fs_count,
'current_fs_progress': current_fs_progress, 'current_fs_progress': current_fs_progress,
# Счетчики # Счетчики
'cc': cc, 'cc': cc,
# Сокеты ЭМС-Г # Сокеты ЭМС-Г
'ems_g_sock_dic': ems_g_sock_dic.duplicate(true), 'ems_g_sock_dic': ems_g_sock_dic.duplicate(true),
# Структуры данных (глубокое копирование) # Структуры данных (глубокое копирование)
'power_for_litera': _deep_copy_power_structure(), 'power_for_litera': _deep_copy_power_structure(),
'control_results': control_results.duplicate(true), 'control_results': control_results.duplicate(true),
'power_result': power_result.duplicate(true), 'power_result': power_result.duplicate(true),
'temperature_um': temperature_um.duplicate(true), 'temperature_um': temperature_um.duplicate(true),
'ecms': ecms.duplicate(true), 'ecms': ecms.duplicate(true),
# Конфигурации блоков # Конфигурации блоков
'block_ip_config': block_ip_config.duplicate(true), 'block_ip_config': block_ip_config.duplicate(true),
'block_kasseta_y5_config': block_kasseta_y5_config.duplicate(true), 'block_kasseta_y5_config': block_kasseta_y5_config.duplicate(true),
# Конфигурация устройства # Конфигурация устройства
'self_name': self_name, 'self_name': self_name,
'constants': constants.duplicate(true), 'constants': constants.duplicate(true),
@@ -212,7 +224,7 @@ func _initialize_config_from_manager() -> void:
if not config_manager.is_loaded(): if not config_manager.is_loaded():
push_error('ConfigManager не загружен!') push_error('ConfigManager не загружен!')
return return
_device_constants = config_manager.get_device_constants() _device_constants = config_manager.get_device_constants()
_base_configs = config_manager.get_base_configs() _base_configs = config_manager.get_base_configs()
_device_configs = config_manager.get_device_configs() _device_configs = config_manager.get_device_configs()
@@ -244,13 +256,13 @@ func _ready() -> void:
## Инициализация маппинга состояний лучей ## Инициализация маппинга состояний лучей
func _initialize_ray_mapping() -> void: func _initialize_ray_mapping() -> void:
_ray_state_mapping = { _ray_state_mapping = {
STATE_MACHINE.UG_SET_RAY_0: 'RAY_m5', STATE_MACHINE.UG_SET_RAY_0: 'RAY_CTRL',
STATE_MACHINE.UG_SET_RAY_1: 'RAY_5', STATE_MACHINE.UG_SET_RAY_1: 'RAY_m5',
STATE_MACHINE.UG_SET_RAY_2: 'RAY_15', STATE_MACHINE.UG_SET_RAY_2: 'RAY_5',
STATE_MACHINE.UG_SET_RAY_3: 'RAY_25', STATE_MACHINE.UG_SET_RAY_3: 'RAY_15',
STATE_MACHINE.UG_SET_RAY_4: 'RAY_35', STATE_MACHINE.UG_SET_RAY_4: 'RAY_25',
STATE_MACHINE.UG_SET_RAY_5: 'RAY_45', STATE_MACHINE.UG_SET_RAY_5: 'RAY_35',
STATE_MACHINE.UG_SET_RAY_CTRL: 'RAY_CTRL', STATE_MACHINE.UG_SET_RAY_CTRL: 'RAY_45',
} }
@@ -270,25 +282,23 @@ func _process(_delta: float) -> void:
## Обработка данных от ЯУ-07 ## Обработка данных от ЯУ-07
func on_data_received(unit_pribor: Object) -> void: func on_data_received(unit_pribor: Object) -> void:
if not flag_in_control: if not flags.in_control:
return return
var status: PackedByteArray = unit_pribor.status var status: PackedByteArray = unit_pribor.status
block_kasseta_y5_config = check_block_kasseta_y5(status, block_kasseta_y5_config, flag_no_trust_yau07) block_kasseta_y5_config = check_block_kasseta_y5(status, block_kasseta_y5_config, flags.no_trust_yau07)
if flags.no_trust_yau07:
if flag_no_trust_yau07:
return return
socket_status_ems_g(status) socket_status_ems_g(status)
block_ip_config = check_block_ip(status, block_ip_config) block_ip_config = check_block_ip(status, block_ip_config)
temperature_um = check_temperature_um(status) temperature_um = check_temperature_um(status)
flag_temperature_ok = check_overheating(temperature_um) flags.temperature_ok = check_overheating(temperature_um)
if machine_timer.is_stopped(): if machine_timer.is_stopped():
return return
_process_dkm_status(status) _process_dkm_status(status)
# Формирование мощностей в литерах # Формирование мощностей в литерах
if current_litera != 0: if current_litera != 0:
var tek_litera: Dictionary = power_for_litera[current_litera] var tek_litera: Dictionary = power_for_litera[current_litera]
@@ -314,20 +324,20 @@ func socket_status_ems_g(packet_form_yau_07: PackedByteArray) -> void:
if self_name in ['', '', '', '']: if self_name in ['', '', '', '']:
ems_g_sock_dic.ems_input_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 9)) != 0 ems_g_sock_dic.ems_input_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 9)) != 0
ems_g_sock_dic.ems_input_2 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 10)) != 0 ems_g_sock_dic.ems_input_2 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 10)) != 0
if self_name in ['', '', '', '']: if self_name in ['', '', '', '']:
ems_g_sock_dic.ems_input_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 11)) != 0 ems_g_sock_dic.ems_input_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 11)) != 0
ems_g_sock_dic.ems_input_2 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 12)) != 0 ems_g_sock_dic.ems_input_2 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 12)) != 0
if self_name in ['', '', '', '']: if self_name in ['', '', '', '']:
ems_g_sock_dic.ems_input_lit_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 8)) != 0 ems_g_sock_dic.ems_input_lit_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 8)) != 0
ems_g_sock_dic.ems_input_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 13)) != 0 ems_g_sock_dic.ems_input_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 13)) != 0
ems_g_sock_dic.ems_input_2 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 14)) != 0 ems_g_sock_dic.ems_input_2 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) & (1 << 14)) != 0
# Обработка выходных сокетов # Обработка выходных сокетов
ems_g_sock_dic.ems_output_lit_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('OUT_BLANK_PRD')) & (1 << 3)) != 0
ems_g_sock_dic.ems_output_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('OUT_BLANK_PRD')) & (1 << 4)) != 0 ems_g_sock_dic.ems_output_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('OUT_BLANK_PRD')) & (1 << 4)) != 0
ems_g_sock_dic.ems_output_2 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('OUT_BLANK_PRD')) & (1 << 5)) != 0 ems_g_sock_dic.ems_output_2 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('OUT_BLANK_PRD')) & (1 << 5)) != 0
ems_g_sock_dic.ems_output_lit_1 = (packet_form_yau_07.decode_u16(config_manager.get_data_index('OUT_BLANK_PRD')) & (1 << 3)) != 0
# Определение флагов СИ ФС входа # Определение флагов СИ ФС входа
var number_socket_input: int var number_socket_input: int
@@ -335,14 +345,14 @@ func socket_status_ems_g(packet_form_yau_07: PackedByteArray) -> void:
number_socket_input = current_litera + 7 number_socket_input = current_litera + 7
var in_blank: int = packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD')) var in_blank: int = packet_form_yau_07.decode_u16(config_manager.get_data_index('IN_BLANK_PRD'))
flag_si_fs_input = (in_blank & (1 << number_socket_input)) != 0 flags.si_fs_input = (in_blank & (1 << number_socket_input)) != 0
# Определение флагов СИ ФС выхода # Определение флагов СИ ФС выхода
var number_socket_output: int var number_socket_output: int
number_socket_output = 4 if current_litera in [2, 4, 6] else 3 if current_litera == 1 else 5 number_socket_output = 4 if current_litera in [2, 4, 6] else 3 if current_litera == 1 else 5
var out_blank: int = packet_form_yau_07.decode_u16(config_manager.get_data_index('OUT_BLANK_PRD')) var out_blank: int = packet_form_yau_07.decode_u16(config_manager.get_data_index('OUT_BLANK_PRD'))
flag_si_fs_output = (out_blank & (1 << number_socket_output)) != 0 flags.si_fs_output = (out_blank & (1 << number_socket_output)) != 0
#endregion #endregion
@@ -368,37 +378,28 @@ func state_control_machine() -> void:
STATE_MACHINE.FS_TURN_OFF: _handle_fs_turn_off_state() STATE_MACHINE.FS_TURN_OFF: _handle_fs_turn_off_state()
STATE_MACHINE.STOP_CONTROL: _handle_stop_control_state() STATE_MACHINE.STOP_CONTROL: _handle_stop_control_state()
# Обновление прогресс-бара после обработки состояния # Обновление прогресс-бара после обработки состояния
if block_kasseta_y5_config['yau07'] or flag_no_trust_yau07: if block_kasseta_y5_config['yau07'] or flags.no_trust_yau07:
progressbar_status() progressbar_status()
## Обработка состояния INIT - инициализация ФС ## Обработка состояния INIT - инициализация ФС
func _handle_init_state() -> void: func _handle_init_state() -> void:
if current_litera in [1, 2, 3, 4, 5, 6, 7]: if current_litera in [1, 2, 3, 4, 5, 6, 7]:
_set_status('Инициализация ФС-%s' % current_litera) _set_status('Инициализация ФС-%s' % current_litera)
var flag_ecm: bool = false if _get_current_ecm(): return
state = STATE_MACHINE.FS_TURN_ON
# Проверка доступности ЭМС для текущей литеры
for key in ecms:
var params = ecms[key].params.freq
if fs_parameters[current_litera].freq == params:
var kni = ecms[key].kni
if pribor_config[self_name].angle == kni:
flag_ecm = true
if not flag_ecm:
state = STATE_MACHINE.FS_TURN_ON
else: else:
if _get_current_ecm(): return
# Завершение контроля если литеры закончились # Завершение контроля если литеры закончились
flag_control_is_over = true flags.control_is_over = true
control_results = on_control_result(block_ip_config, control_results) control_results = on_control_result(block_ip_config, control_results)
power_result = prep_power(power_for_litera, self_name) power_result = prep_power(power_for_litera, self_name)
machine_timer.stop() machine_timer.stop()
var result: bool = true var result: bool = true
for device in control_results.values(): for device in control_results.values():
if not device: if not device:
result = false result = false
_set_status('Прибор ПРД-%s: %s' % [self_name, ['неисправен', 'исправен'][int(result)]]) _set_status('Прибор ПРД-%s: %s' % [self_name, ['неисправен', 'исправен'][int(result)]])
emit_signal('control_is_over', self_name) emit_signal('control_is_over', self_name)
@@ -406,25 +407,31 @@ func _handle_init_state() -> void:
## Обработка состояния FS_TURN_ON - включение ФС ## Обработка состояния FS_TURN_ON - включение ФС
func _handle_fs_turn_on_state() -> void: func _handle_fs_turn_on_state() -> void:
_set_status('Включение ФС-%s' % current_litera) _set_status('Включение ФС-%s' % current_litera)
manage_fs(true, self_name, pribor_config, fs_parameters, current_litera, constants.POWER_UM) manage_fs(self_name, pribor_config, fs_parameters, current_litera, constants.POWER_UM)
control_timer.wait_time = constants.TIMER_DELAY control_timer.wait_time = constants.TIMER_DELAY
control_timer.start() control_timer.start()
state = STATE_MACHINE.FS_WORK state = STATE_MACHINE.FS_WORK
static func take_ecm_id(ecm_dic: Dictionary, device_name: String, current_lit: int) -> int:
# Получаем целевой nmfs из таблицы
var target_nmfs: int = LITER_TO_NMFS.get(device_name, {}).get(current_lit, -1)
if target_nmfs == -1:
return 0
# Ищем ECM с соответствующим nmfs
for ecm_id in ecm_dic:
if ecm_dic[ecm_id].nmfs == target_nmfs:
return ecm_id
return 0
## Обработка состояния FS_WORK - проверка работы ФС ## Обработка состояния FS_WORK - проверка работы ФС
func _handle_fs_work_state() -> void: func _handle_fs_work_state() -> void:
var flag_ecm: bool = false
_set_status('Проверка связи сервиса КАПС РПБ') _set_status('Проверка связи сервиса КАПС РПБ')
for key in ecms: if not flags.ecm_is_comming: return
var params = ecms[key].params.freq #print([self_name, current_ecm_key , ecms[current_ecm_key]])
if fs_parameters[current_litera].freq == params:
var kni = ecms[key].kni
if pribor_config[self_name].angle == kni:
flag_ecm = true
# Если ЭМС доступна и ФС в порядке - запускаем таймер ЭМС # Если ЭМС доступна и ФС в порядке - запускаем таймер ЭМС
if flag_ecm and flag_fs_status_ok: if current_ecm_key != 0 and flags.fs_status_ok:
_set_status('Проверка ФС-%s' % current_litera) _set_status('Проверка ФС-%s' % current_litera)
# Проверка завершения работы ФС # Проверка завершения работы ФС
if (current_litera == 2 and control_results.fs_2) or \ if (current_litera == 2 and control_results.fs_2) or \
@@ -434,6 +441,10 @@ func _handle_fs_work_state() -> void:
(current_litera == 6 and control_results.fs_6) or \ (current_litera == 6 and control_results.fs_6) or \
(current_litera == 7 and control_results.fs_7) or \ (current_litera == 7 and control_results.fs_7) or \
(current_litera == 1 and control_results.fs_1): (current_litera == 1 and control_results.fs_1):
if not block_kasseta_y5_config['yau07']:
_set_status('Ожидание данных от ЯУ-07...')
return # НЕ переходим дальше пока нет данных
state = STATE_MACHINE.CHEK_KASSETA_Y5 state = STATE_MACHINE.CHEK_KASSETA_Y5
@@ -445,14 +456,15 @@ func _handle_check_kasseta_state() -> void:
if not block_kasseta_y5_config[case]: if not block_kasseta_y5_config[case]:
block_kasseta_y5 = false block_kasseta_y5 = false
if block_kasseta_y5: if block_kasseta_y5:
if flag_temperature_ok: if flags.temperature_ok:
ems_6666_timer.start() ems_6666_timer.start()
state = STATE_MACHINE.CHEK_BLOCK_IP state = STATE_MACHINE.CHEK_BLOCK_IP
else: else:
_set_status('Перегрев УМ') _set_status('Перегрев УМ')
state = STATE_MACHINE.IN_EMS_STOP state = STATE_MACHINE.IN_EMS_STOP
else: else:
flag_only_fs = true #flag_only_fs = true
_set_status('Касета У5: ERROR')
state = STATE_MACHINE.IN_EMS_STOP state = STATE_MACHINE.IN_EMS_STOP
@@ -468,7 +480,7 @@ func _handle_check_block_ip_state() -> void:
state = STATE_MACHINE.UG_SET_RAY_5 state = STATE_MACHINE.UG_SET_RAY_5
else: else:
state = STATE_MACHINE.UG_SET_RAY_CTRL state = STATE_MACHINE.UG_SET_RAY_CTRL
elif flag_only_fs: elif flags.only_fs:
state = STATE_MACHINE.IN_EMS_STOP state = STATE_MACHINE.IN_EMS_STOP
@@ -476,7 +488,7 @@ func _handle_check_block_ip_state() -> void:
func _handle_read_isa_state() -> void: func _handle_read_isa_state() -> void:
if (unit_prd.cmd_state == unit_prd.CmdState.DONE) or (unit_prd.cmd_state == unit_prd.CmdState.FAIL): if (unit_prd.cmd_state == unit_prd.CmdState.DONE) or (unit_prd.cmd_state == unit_prd.CmdState.FAIL):
_handle_read_isa(unit_prd, [constants.ADDR_UG_LITERA_1, constants.ADDR_UG_LITERA_2, constants.ADDR_UG_LITERA_3], cmd_array) _handle_read_isa(unit_prd, [constants.ADDR_UG_LITERA_1, constants.ADDR_UG_LITERA_2, constants.ADDR_UG_LITERA_3], cmd_array)
flag_write_isa = false flags.write_isa = false
state = STATE_MACHINE.UG_SET_RAY state = STATE_MACHINE.UG_SET_RAY
@@ -488,10 +500,11 @@ func _handle_ems_stop_state() -> void:
## Обработка состояния FS_TURN_OFF - выключение ФС ## Обработка состояния FS_TURN_OFF - выключение ФС
func _handle_fs_turn_off_state() -> void: func _handle_fs_turn_off_state() -> void:
_set_status('Отключение ФС-%s' % current_litera)
flag_fs_status_ok = false
manage_fs(false, self_name, pribor_config, fs_parameters, current_litera, constants.POWER_UM)
state = STATE_MACHINE.STOP_CONTROL state = STATE_MACHINE.STOP_CONTROL
if not _get_current_ecm(): return
_set_status('Отключение ФС-%s' % current_litera)
flags.fs_status_ok = false
signaller.emit_signal('interfer_off', ecms[current_ecm_key])
## Обработка состояния STOP_CONTROL - завершение контроля ## Обработка состояния STOP_CONTROL - завершение контроля
@@ -499,9 +512,10 @@ func _handle_stop_control_state() -> void:
_set_status('Завершение контроля ФС-%s' % current_litera) _set_status('Завершение контроля ФС-%s' % current_litera)
completed_fs_count += 1 completed_fs_count += 1
_advance_to_next_fs() _advance_to_next_fs()
flags.ecm_is_comming = false
state = STATE_MACHINE.INIT state = STATE_MACHINE.INIT
if flag_no_trust_yau07: if flags.no_trust_yau07:
state = STATE_MACHINE.STOP_CONTROL state = STATE_MACHINE.STOP_CONTROL
@@ -515,7 +529,6 @@ func _advance_to_next_fs() -> void:
5: current_litera = 0 5: current_litera = 0
6: current_litera = 7 6: current_litera = 7
7: current_litera = 0 7: current_litera = 0
#endregion #endregion
@@ -535,7 +548,7 @@ func _handle_ray_read_mode() -> void:
var addr: int = _get_ug_address() var addr: int = _get_ug_address()
if not _can_process_ray_state(addr): if not _can_process_ray_state(addr):
return return
var ray_value = unit_prd.isa_ports[addr] & RAY_MASK var ray_value = unit_prd.isa_ports[addr] & RAY_MASK
_process_ray_value(ray_value) _process_ray_value(ray_value)
@@ -549,10 +562,13 @@ func _handle_ray_write_mode(ray_num: int) -> void:
if ray_num == 0: if ray_num == 0:
control_timer.stop() control_timer.stop()
# Ожидание пяти пакетов от ЯУ-07 # Ожидание пяти пакетов от ЯУ-07
if count_packets_power < 5: return if ray_num == 6:
if count_packets_power < 20: return
elif count_packets_power < 10: return
# Установка луча # Установка луча
_handle_ug_set_state(ray_num) _handle_ug_set_state(ray_num)
flag_write_isa = true flags.write_isa = true
state = STATE_MACHINE.READ_ISA state = STATE_MACHINE.READ_ISA
@@ -578,10 +594,10 @@ func _can_process_ray_state(addr: int) -> bool:
## Проверка возможности записи луча ## Проверка возможности записи луча
func _can_write_ray() -> bool: func _can_write_ray() -> bool:
if flag_write_isa: if flags.write_isa:
return false return false
if not flag_si_fs_input: if not flags.si_fs_input:
_set_status('Ожидание сигнала излучения от ФС-%s' % current_litera ) _set_status('Ожидание сигнала излучения от ФС-%s' % current_litera )
return false return false
else: else:
@@ -607,7 +623,7 @@ func _handle_ug_set_state(RAY_DOU_NUM: int) -> void:
'ATT_UM_3': def_att, 'ATT_UM_3': def_att,
'BASE_EMS_G': constants.BASE_ADDR_EMS_G 'BASE_EMS_G': constants.BASE_ADDR_EMS_G
} }
# Конфигурация аттенюаторов для разных типов приборов # Конфигурация аттенюаторов для разных типов приборов
if self_name == '' or self_name == '' or self_name == '' or self_name == '': if self_name == '' or self_name == '' or self_name == '' or self_name == '':
dic_att['ATT_UM_1'] = constants.ATT_UM_6 dic_att['ATT_UM_1'] = constants.ATT_UM_6
@@ -619,7 +635,7 @@ func _handle_ug_set_state(RAY_DOU_NUM: int) -> void:
elif self_name == '' or self_name == '' or self_name == '' or self_name == '': elif self_name == '' or self_name == '' or self_name == '' or self_name == '':
dic_att['ATT_UM_1'] = constants.ATT_UM_2 dic_att['ATT_UM_1'] = constants.ATT_UM_2
dic_att['ATT_UM_2'] = constants.ATT_UM_3 dic_att['ATT_UM_2'] = constants.ATT_UM_3
flag_write_isa = on_ug_setting(unit_prd, dic_att, cmd_array) flags.write_isa = on_ug_setting(unit_prd, dic_att, cmd_array)
count_packets_power = 0 count_packets_power = 0
@@ -637,9 +653,9 @@ func progressbar_status() -> void:
await get_tree().create_timer(0.5).timeout await get_tree().create_timer(0.5).timeout
progress_value = 0 progress_value = 0
return return
var base_progress: float = 0.0 var base_progress: float = 0.0
# Базовый прогресс в зависимости от состояния # Базовый прогресс в зависимости от состояния
match state: match state:
STATE_MACHINE.INIT: base_progress = PROGRESS_INIT STATE_MACHINE.INIT: base_progress = PROGRESS_INIT
@@ -653,14 +669,14 @@ func progressbar_status() -> void:
STATE_MACHINE.UG_SET_RAY_4: base_progress = PROGRESS_RAY_STATES + 20 STATE_MACHINE.UG_SET_RAY_4: base_progress = PROGRESS_RAY_STATES + 20
STATE_MACHINE.UG_SET_RAY_5: base_progress = PROGRESS_RAY_STATES + 25 STATE_MACHINE.UG_SET_RAY_5: base_progress = PROGRESS_RAY_STATES + 25
STATE_MACHINE.IN_EMS_STOP: base_progress = PROGRESS_COMPLETE STATE_MACHINE.IN_EMS_STOP: base_progress = PROGRESS_COMPLETE
STATE_MACHINE.FS_TURN_OFF: base_progress = PROGRESS_COMPLETE STATE_MACHINE.FS_TURN_OFF: base_progress = PROGRESS_COMPLETE + 5
STATE_MACHINE.STOP_CONTROL: base_progress = PROGRESS_COMPLETE STATE_MACHINE.STOP_CONTROL: base_progress = PROGRESS_COMPLETE + 10
# Плавное заполнение во время ожидания таймера # Плавное заполнение во время ожидания таймера
if control_timer.time_left > 0 and state != STATE_MACHINE.STOP_CONTROL: if control_timer.time_left > 0 and state != STATE_MACHINE.STOP_CONTROL:
var timer_progress = (control_timer.wait_time - control_timer.time_left) / control_timer.wait_time var timer_progress = (control_timer.wait_time - control_timer.time_left) / control_timer.wait_time
base_progress = lerp(base_progress - 5.0, base_progress, timer_progress) base_progress = lerp(base_progress - 5.0, base_progress, timer_progress)
# Учитываем прогресс по лучам внутри UG_SET_RAY состояния # Учитываем прогресс по лучам внутри UG_SET_RAY состояния
if state == STATE_MACHINE.UG_SET_RAY: if state == STATE_MACHINE.UG_SET_RAY:
var addr: int = _get_ug_address() var addr: int = _get_ug_address()
@@ -669,7 +685,7 @@ func progressbar_status() -> void:
var max_ray_value = 5.0 # максимальное значение луча для прогресса var max_ray_value = 5.0 # максимальное значение луча для прогресса
var ray_progress = float(ray_value) / max_ray_value * 40.0 var ray_progress = float(ray_value) / max_ray_value * 40.0
base_progress += ray_progress base_progress += ray_progress
# Распределяем прогресс по ФС # Распределяем прогресс по ФС
if total_fs_to_check > 0: if total_fs_to_check > 0:
var progress_per_fs = (PROGRESS_COMPLETE - PROGRESS_INIT) / total_fs_to_check var progress_per_fs = (PROGRESS_COMPLETE - PROGRESS_INIT) / total_fs_to_check
@@ -677,7 +693,7 @@ func progressbar_status() -> void:
prog_back = fs_base_progress + (base_progress * progress_per_fs / PROGRESS_COMPLETE) prog_back = fs_base_progress + (base_progress * progress_per_fs / PROGRESS_COMPLETE)
else: else:
prog_back = base_progress prog_back = base_progress
if control_timer.time_left > 0 and not control_timer.is_stopped(): if control_timer.time_left > 0 and not control_timer.is_stopped():
prog_back += (control_timer.wait_time - control_timer.time_left) + 10 prog_back += (control_timer.wait_time - control_timer.time_left) + 10
@@ -725,9 +741,9 @@ func on_state_mashine():
## Обработка таймаута контроля ## Обработка таймаута контроля
func on_stop_control() -> void: func on_stop_control() -> void:
_handle_fs_turn_off_state() _handle_fs_turn_off_state()
if state == STATE_MACHINE.UG_SET_RAY: if state == STATE_MACHINE.UG_SET_RAY:
flag_no_trust_yau07 = true flags.no_trust_yau07 = true
state = STATE_MACHINE.IN_EMS_STOP state = STATE_MACHINE.IN_EMS_STOP
#endregion #endregion
@@ -735,37 +751,37 @@ func on_stop_control() -> void:
#region DEVICE_CONFIGURATION #region DEVICE_CONFIGURATION
## Определение имени и конфигурации устройства ## Определение имени и конфигурации устройства
func _determine_self_name() -> void: func _determine_self_name() -> void:
flag_no_trust_yau07 = false flags.no_trust_yau07 = false
flag_only_fs = false flags.only_fs = false
cc = 0 cc = 0
state = STATE_MACHINE.get('INIT', 0) state = STATE_MACHINE.get('INIT', 0)
var current_unit = unit_prd.name var current_unit = unit_prd.name
var parts = current_unit.split('-') var parts = current_unit.split('-')
self_name = parts[-1] self_name = parts[-1]
var device_type: String = _get_device_type() var device_type: String = _get_device_type()
if device_type.is_empty(): if device_type.is_empty():
return return
# Загрузка конфигурации устройства # Загрузка конфигурации устройства
var device_config = _device_constants.get(device_type, {}) var device_config = _device_constants.get(device_type, {})
var device_data_config = _device_configs.get(device_type, {}) var device_data_config = _device_configs.get(device_type, {})
constants = device_config.get('constants', {}) constants = device_config.get('constants', {})
pribor_config = device_config.get('pribor_config', {}) pribor_config = device_config.get('pribor_config', {})
# Конвертация fs_params ключей в int # Конвертация fs_params ключей в int
var raw_fs_params = device_config.get('fs_params', {}) var raw_fs_params = device_config.get('fs_params', {})
fs_parameters = {} fs_parameters = {}
for key in raw_fs_params: for key in raw_fs_params:
fs_parameters[int(key)] = raw_fs_params[key] fs_parameters[int(key)] = raw_fs_params[key]
# Загрузка конфигураций блоков # Загрузка конфигураций блоков
block_ip_config = _load_block_config(device_data_config.get('block_ip', {}), 'block_ip') block_ip_config = _load_block_config(device_data_config.get('block_ip', {}), 'block_ip')
block_kasseta_y5_config = _load_block_config(device_data_config.get('block_kasseta', {}), 'block_kasseta') block_kasseta_y5_config = _load_block_config(device_data_config.get('block_kasseta', {}), 'block_kasseta')
control_results = device_data_config.get('control_results', {}) control_results = device_data_config.get('control_results', {})
current_litera = device_config.get('start_litera', 0) current_litera = device_config.get('start_litera', 0)
# Определение общего количества ФС для контроля # Определение общего количества ФС для контроля
match self_name: match self_name:
'', '', '', '': '', '', '', '':
@@ -774,7 +790,7 @@ func _determine_self_name() -> void:
total_fs_to_check = 2 # Литеры 2, 3 total_fs_to_check = 2 # Литеры 2, 3
'', '', '', '': '', '', '', '':
total_fs_to_check = 2 # Литеры 4, 5 total_fs_to_check = 2 # Литеры 4, 5
progress_value = 0 progress_value = 0
completed_fs_count = 0 completed_fs_count = 0
current_fs_progress = 0.0 current_fs_progress = 0.0
@@ -793,11 +809,11 @@ func _load_block_config(config, config_type: String) -> Dictionary:
## Определение типа устройства по имени ## Определение типа устройства по имени
func _get_device_type() -> String: func _get_device_type() -> String:
if self_name.ends_with('н'): if self_name.ends_with('н'):
return 'PRD_N' return 'PRD_N'
elif self_name.ends_with('в'): elif self_name.ends_with('в'):
return 'PRD_V' return 'PRD_V'
elif self_name.ends_with('к'): elif self_name.ends_with('к'):
return 'PRD_K' return 'PRD_K'
return '' return ''
#endregion #endregion
@@ -812,7 +828,7 @@ func initialize_connections() -> void:
interfer.connect('interfer_resized', Callable(self, 'on_interfer_resized')) interfer.connect('interfer_resized', Callable(self, 'on_interfer_resized'))
unit_prd.connect('data_received', Callable(self, 'on_data_received')) unit_prd.connect('data_received', Callable(self, 'on_data_received'))
unit_prd.connect('line_changed', Callable(self, 'on_line_changed_yau07')) unit_prd.connect('line_changed', Callable(self, 'on_line_changed_yau07'))
# Подключение сигналов режимов работы # Подключение сигналов режимов работы
var mode_signals = ['режим_работа', 'режим_журнал', 'режим_эмс', 'режим_настройки'] var mode_signals = ['режим_работа', 'режим_журнал', 'режим_эмс', 'режим_настройки']
for signal_name in mode_signals: for signal_name in mode_signals:
@@ -829,34 +845,38 @@ func on_fs_update_state(packet_type_7: Dictionary, fs_mapping: Dictionary) -> vo
var fs_result := {fs_key: 0} var fs_result := {fs_key: 0}
fs_result = on_fs_state(packet_type_7, fs_mapping, fs_result, _fs_rules) fs_result = on_fs_state(packet_type_7, fs_mapping, fs_result, _fs_rules)
control_results[fs_key] = fs_result[fs_key] control_results[fs_key] = fs_result[fs_key]
flag_fs_status_ok = control_results[fs_key] == 1 flags.fs_status_ok = control_results[fs_key] == 1
## Обработка изменения размера интерферометра ## Обработка изменения размера интерферометра
func on_interfer_resized(ecms_dic: Dictionary) -> void: func on_interfer_resized(ecms_dic: Dictionary) -> void:
ecms = ecms_dic ecms = ecms_dic
current_ecm_key = take_ecm_id(ecms, self_name, current_litera)
flags.ecm_is_comming = (current_ecm_key != 0) # Явное установление состояния
## Обработка запуска контроля устройства ## Обработка запуска контроля устройства
func _on_start_contol_device()-> void: func _on_start_contol_device()-> void:
_set_status('Подготовка к контролю') _set_status('Подготовка к контролю')
restore_default_states() restore_default_states()
flags.in_control = true
machine_timer.wait_time = constants.STATE_MASHINE_TIMER machine_timer.wait_time = constants.STATE_MASHINE_TIMER
machine_timer.start() machine_timer.start()
## Обработка изменения режима работы ## Обработка изменения режима работы
func on_mode_changed(in_tree: bool) -> void: func on_mode_changed(in_tree: bool) -> void:
flag_in_control = in_tree flags.in_control = in_tree
if not in_tree: ## При нажатии выхода из режима контроль if not in_tree: ## При нажатии выхода из режима контроль
_set_status('Ожидание запуска контроля') _set_status('Ожидание запуска контроля')
cmd_array.append([unit_prd.CmdCode.WRITE_ISA,[ cmd_array.append([unit_prd.CmdCode.WRITE_ISA,[
constants.ADDR_UG_LITERA_1, DATA_EXIT_CONTOL_ISA, constants.ADDR_UG_LITERA_1, DATA_EXIT_CONTOL_ISA,
constants.ADDR_UG_LITERA_2, DATA_EXIT_CONTOL_ISA, constants.ADDR_UG_LITERA_2, DATA_EXIT_CONTOL_ISA,
constants.ADDR_UG_LITERA_3, DATA_EXIT_CONTOL_ISA]]) constants.ADDR_UG_LITERA_3, DATA_EXIT_CONTOL_ISA]])
flag_control_is_over = false flags.control_is_over = false
flag_no_trust_yau07 = false flags.no_trust_yau07 = false
flag_only_fs = false flags.only_fs = false
flags.ecm_is_comming = false
progress_value = 0 progress_value = 0
machine_timer.stop() machine_timer.stop()
state = STATE_MACHINE.INIT state = STATE_MACHINE.INIT
@@ -869,30 +889,39 @@ func on_mode_changed(in_tree: bool) -> void:
# Вызывается при смене связи я ячейков ЯУ-07Б # Вызывается при смене связи я ячейков ЯУ-07Б
func on_line_changed_yau07(_status: Object)->void: func on_line_changed_yau07(_status: Object)->void:
_set_status('Ожидание запуска контроля') _set_status('Ожидание запуска контроля')
flag_control_is_over = false flags.control_is_over = false
flag_no_trust_yau07 = false flags.no_trust_yau07 = false
flag_only_fs = false flags.only_fs = false
restore_default_states() restore_default_states()
#endregion #endregion
#region ECMS
## Универсальная проверка доступа к ecms:
func _get_current_ecm() -> Variant:
if current_ecm_key != 0 and ecms.has(current_ecm_key):
return ecms[current_ecm_key]
return null
#endregion
#region DKM_PROCESSING #region DKM_PROCESSING
## Обработка статуса ДКМ из пакета ЯУ-07 ## Обработка статуса ДКМ из пакета ЯУ-07
func _process_dkm_status(status: PackedByteArray) -> void: func _process_dkm_status(status: PackedByteArray) -> void:
if not control_results.has(_get_current_fs_key(current_litera, _fs_keys)): if not control_results.has(_get_current_fs_key(current_litera, _fs_keys)):
return return
var dkm_bit = _get_dkm_bit_for_current_fs(current_litera, constants) var dkm_bit = _get_dkm_bit_for_current_fs(current_litera, constants)
if dkm_bit == 0: if dkm_bit == 0:
control_results['dkm_1'] = check_dkm(status, dkm_bit) control_results['dkm_1'] = check_dkm(status, dkm_bit)
var addr: int = constants.ADDR_UG_LITERA_1 var addr: int = constants.ADDR_UG_LITERA_1
if current_litera == 3 or current_litera == 5 or current_litera == 7: if current_litera == 3 or current_litera == 5 or current_litera == 7:
addr = constants.ADDR_UG_LITERA_2 addr = constants.ADDR_UG_LITERA_2
if not unit_prd.isa_ports.has(addr) or not (unit_prd.cmd_state == unit_prd.CmdState.DONE): if not unit_prd.isa_ports.has(addr) or not (unit_prd.cmd_state == unit_prd.CmdState.DONE):
return return
if not unit_prd.isa_ports[addr] & 0x07 == 6: if not unit_prd.isa_ports[addr] & 0x07 == 6:
return return
@@ -939,7 +968,7 @@ func get_current_status() -> String:
## Геттер для результатов контроля ## Геттер для результатов контроля
func get_control_results() -> Dictionary: func get_control_results() -> Dictionary:
return { return {
'control_is_over': flag_control_is_over, 'control_is_over': flags.control_is_over,
'result_dic': control_results, 'result_dic': control_results,
'power_dic': power_result, 'power_dic': power_result,
'block_kasseta_y5_config': block_kasseta_y5_config, 'block_kasseta_y5_config': block_kasseta_y5_config,
@@ -980,12 +1009,11 @@ static func _handle_read_isa(prd_unit: Object, read_isa_ports: Array, prd_cmd_ar
## Управление модулем ФС (включить/отключить излучение) ## Управление модулем ФС (включить/отключить излучение)
static func manage_fs(mode: bool, pribor: String, p_conf: Dictionary, fs_params: Dictionary, litera: int, power_um: int) -> void: static func manage_fs(pribor: String, p_conf: Dictionary, fs_params: Dictionary, litera: int, power_um: int) -> void:
var config: Dictionary = p_conf[pribor] var config: Dictionary = p_conf[pribor]
var angle: float = config.angle var angle: float = config.angle
var sectors: Array = config.sectors var sectors: Array = config.sectors
var interfer_name: String = 'k1'
var interfer_name: String = 'k1' if mode else 'off'
var fs_arr: Array = [] var fs_arr: Array = []
if litera in fs_params: if litera in fs_params:
@@ -996,8 +1024,7 @@ static func manage_fs(mode: bool, pribor: String, p_conf: Dictionary, fs_params:
params.width, params.width,
sectors[litera - 1] if litera == 1 else sectors[litera - 5] if litera > 5 else sectors[litera - 4] if litera > 3 else sectors[litera - 2] sectors[litera - 1] if litera == 1 else sectors[litera - 5] if litera > 5 else sectors[litera - 4] if litera > 3 else sectors[litera - 2]
]) ])
signaller.emit_signal('interfer_init', interfer_name, fs_arr, power_um)
signaller.emit_signal('interfer_init', interfer_name, fs_arr, power_um)
## Проверка кассет П1 и ИП МА2000 ## Проверка кассет П1 и ИП МА2000
@@ -1037,7 +1064,7 @@ static func check_temperature_um(status_prd: PackedByteArray) -> Dictionary:
var return_dic_temp: Dictionary var return_dic_temp: Dictionary
var ukp1_online: int = (status_prd[0] >> 2) & 1 var ukp1_online: int = (status_prd[0] >> 2) & 1
var ukp2_online = (status_prd[0] >> 3) & 1 var ukp2_online = (status_prd[0] >> 3) & 1
if ukp1_online: if ukp1_online:
var tmp_1: int var tmp_1: int
var temperature_ukp_1: int var temperature_ukp_1: int
@@ -1045,28 +1072,28 @@ static func check_temperature_um(status_prd: PackedByteArray) -> Dictionary:
temperature_ukp_1 = status_prd.decode_u16(Constants.TEMPERATURE_UKP_1 + 2 * i_temp) temperature_ukp_1 = status_prd.decode_u16(Constants.TEMPERATURE_UKP_1 + 2 * i_temp)
tmp_1 = round(Constants.CONST_MIN_TEMP + (Constants.MAXIMUM_CODE_ADC - temperature_ukp_1) * TEMP + 3) tmp_1 = round(Constants.CONST_MIN_TEMP + (Constants.MAXIMUM_CODE_ADC - temperature_ukp_1) * TEMP + 3)
return_dic_temp[arr_um[i_temp]] = tmp_1 return_dic_temp[arr_um[i_temp]] = tmp_1
if ukp2_online: if ukp2_online:
for i_temp in 8: for i_temp in 8:
var temperature_ukp_2: int = status_prd.decode_u16(Constants.TEMPERATURE_UKP_2 + 2 * i_temp) var temperature_ukp_2: int = status_prd.decode_u16(Constants.TEMPERATURE_UKP_2 + 2 * i_temp)
var tmp_2: int = round(Constants.CONST_MIN_TEMP + (Constants.MAXIMUM_CODE_ADC - temperature_ukp_2) * TEMP + 3) var tmp_2: int = round(Constants.CONST_MIN_TEMP + (Constants.MAXIMUM_CODE_ADC - temperature_ukp_2) * TEMP + 3)
return_dic_temp[arr_um[i_temp+8]] = tmp_2 return_dic_temp[arr_um[i_temp+8]] = tmp_2
return return_dic_temp return return_dic_temp
static func check_overheating(temperature_data: Dictionary) -> bool: static func check_overheating(temperature_data: Dictionary) -> bool:
const MAX_TEMP: int = 55 const MAX_TEMP: int = 55
const MIN_VALID_TEMP: int = -1500 const MIN_VALID_TEMP: int = -1500
const MAX_VALID_TEMP: int = 150 const MAX_VALID_TEMP: int = 130
for key in temperature_data: for key in temperature_data:
var temp = temperature_data[key] var temp = temperature_data[key]
# Пропускаем невалидные значения # Пропускаем невалидные значения
if temp < MIN_VALID_TEMP or temp > MAX_VALID_TEMP: if temp < MIN_VALID_TEMP or temp > MAX_VALID_TEMP:
continue continue
# Проверяем превышение температуры # Проверяем превышение температуры
if temp > MAX_TEMP: if temp > MAX_TEMP:
return false return false
@@ -1083,13 +1110,13 @@ static func check_dkm(status_prd: PackedByteArray, bit_dkm: int) -> bool:
## Распределение номеров ФС по приборам ## Распределение номеров ФС по приборам
static func _create_fs_mapping(s_name: String) -> Dictionary: static func _create_fs_mapping(s_name: String) -> Dictionary:
var suffixes: Dictionary = { var suffixes: Dictionary = {
0: '', 1: '', 2: '', 3: '', 0: '', 1: '', 2: '', 3: '',
4: '', 5: '', 6: '', 7: '', 4: '', 5: '', 6: '', 7: '',
8: '', 9: '', 10: '', 11: '', 8: '', 9: '', 10: '', 11: '',
12: '', 13: '', 14: '', 15: '', 12: '', 13: '', 14: '', 15: '',
16: '', 17: '', 18: '', 19: '', 16: '', 17: '', 18: '', 19: '',
20: '', 21: '', 22: '', 23: '', 20: '', 21: '', 22: '', 23: '',
24: '', 25: '', 26: '', 27: '', 24: '', 25: '', 26: '', 27: '',
} }
var mapping: Dictionary = {} var mapping: Dictionary = {}
@@ -1256,7 +1283,7 @@ static func check_dou_result(control_dic: Dictionary, power_dic: Dictionary, pri
ray_dic[RAY_45].size() == 0: ray_dic[RAY_45].size() == 0:
control_dic[dou] = false control_dic[dou] = false
return control_dic return control_dic
# Подсчет значений ниже порога по позициям # Подсчет значений ниже порога по позициям
var low_power_by_position: Array = [0, 0, 0, 0, 0, 0] # Счетчики для 6 позиций var low_power_by_position: Array = [0, 0, 0, 0, 0, 0] # Счетчики для 6 позиций
for ray_key in [RAY_m5, RAY_5, RAY_15, RAY_25, RAY_35, RAY_45]: for ray_key in [RAY_m5, RAY_5, RAY_15, RAY_25, RAY_35, RAY_45]:
@@ -1264,7 +1291,7 @@ static func check_dou_result(control_dic: Dictionary, power_dic: Dictionary, pri
for i in range(power_array.size()): for i in range(power_array.size()):
if power_array[i] < cnst.POWER_THRESHOLD: if power_array[i] < cnst.POWER_THRESHOLD:
low_power_by_position[i] += 1 low_power_by_position[i] += 1
# Проверяем, нет ли позиции где много низких значений # Проверяем, нет ли позиции где много низких значений
var limit_power_um: int = 2 var limit_power_um: int = 2
var good_positions: int = 0 var good_positions: int = 0
@@ -1289,27 +1316,20 @@ func _deep_copy_power_structure() -> Dictionary:
func restore_default_states() -> void: func restore_default_states() -> void:
if _default_states.is_empty(): if _default_states.is_empty():
_initialize_default_states() _initialize_default_states()
# Восстановление простых переменных # Восстановление простых переменных
flag_write_isa = _default_states['flag_write_isa'] flags = _default_states['flags'].duplicate(true)
flag_fs_status_ok = _default_states['flag_fs_status_ok']
flag_si_fs_input = _default_states['flag_si_fs_input']
flag_si_fs_output = _default_states['flag_si_fs_output']
flag_control_is_over = _default_states['flag_control_is_over']
flag_no_trust_yau07 = _default_states['flag_no_trust_yau07']
flag_only_fs = _default_states['flag_only_fs']
state = _default_states['state'] state = _default_states['state']
current_litera = _default_states['current_litera'] current_litera = _default_states['current_litera']
progress_value = _default_states['progress_value'] progress_value = _default_states['progress_value']
current_status = _default_states['current_status'] current_status = _default_states['current_status']
total_fs_to_check = _default_states['total_fs_to_check'] total_fs_to_check = _default_states['total_fs_to_check']
completed_fs_count = _default_states['completed_fs_count'] completed_fs_count = _default_states['completed_fs_count']
current_fs_progress = _default_states['current_fs_progress'] current_fs_progress = _default_states['current_fs_progress']
cc = _default_states['cc'] cc = _default_states['cc']
# Восстановление словарей (глубокое копирование) # Восстановление словарей (глубокое копирование)
ems_g_sock_dic = _default_states['ems_g_sock_dic'].duplicate(true) ems_g_sock_dic = _default_states['ems_g_sock_dic'].duplicate(true)
power_for_litera = _default_states['power_for_litera'].duplicate(true) power_for_litera = _default_states['power_for_litera'].duplicate(true)
@@ -1318,28 +1338,18 @@ func restore_default_states() -> void:
temperature_um = _default_states['temperature_um'].duplicate(true) temperature_um = _default_states['temperature_um'].duplicate(true)
ecms = _default_states['ecms'].duplicate(true) ecms = _default_states['ecms'].duplicate(true)
block_ip_config = _default_states['block_ip_config'].duplicate(true) block_ip_config = _default_states['block_ip_config'].duplicate(true)
block_kasseta_y5_config = _default_states['block_kasseta_y5_config'].duplicate(true)
# Остановка таймеров # Остановка таймеров
control_timer.stop() control_timer.stop()
ems_6666_timer.stop() ems_6666_timer.stop()
machine_timer.stop() machine_timer.stop()
_set_status('Состояния сброшены к значениям по умолчанию') _set_status('Состояния сброшены к значениям по умолчанию')
## Получение текущих состояний для отладки ## Получение текущих состояний для отладки
func get_current_states() -> Dictionary: func get_current_states() -> Dictionary:
return { return {
'flags': { 'flags': flags.duplicate(true),
'write_isa': flag_write_isa,
'fs_status_ok': flag_fs_status_ok,
'si_fs_input': flag_si_fs_input,
'si_fs_output': flag_si_fs_output,
'in_control': flag_in_control,
'control_is_over': flag_control_is_over,
'no_trust_yau07': flag_no_trust_yau07,
'only_fs': flag_only_fs
},
'state_machine': { 'state_machine': {
'state': state, 'state': state,
'current_litera': current_litera 'current_litera': current_litera

View File

@@ -301,6 +301,16 @@ func default_selector_size_proc(i_row: int, rect: Array) -> void:
rect[3] += node_gap.y rect[3] += node_gap.y
## Очищает в словаре nodes от невалидных ссылок
func cleanup_invalid_selectors():
var keys_to_remove = []
for key in nodes:
if key.begins_with(SLCT_PREFIX) and not is_instance_valid(nodes[key]):
keys_to_remove.append(key)
for key in keys_to_remove:
nodes.erase(key)
print("Удален невалидный селектор: ", key)
## ##
func clear_rows_selected(): func clear_rows_selected():
var rows_count: = get_rows_count() var rows_count: = get_rows_count()
@@ -323,7 +333,6 @@ func _set_row_selected(i_row: int, selected: bool = true) -> void:
return return
if nodes.has(selector_key) and (not selected): if nodes.has(selector_key) and (not selected):
var selector = nodes[selector_key] var selector = nodes[selector_key]
nodes.erase(selector_key)
if is_instance_valid(selector): if is_instance_valid(selector):
var prnt = selector.get_parent_control() var prnt = selector.get_parent_control()
if prnt: if prnt:
@@ -331,6 +340,7 @@ func _set_row_selected(i_row: int, selected: bool = true) -> void:
selector.queue_free() selector.queue_free()
else: else:
push_warning('обращение к удалённому элементу \"%s\"' % selector_key) push_warning('обращение к удалённому элементу \"%s\"' % selector_key)
nodes.erase(selector_key)
elif (not nodes.has(selector_key)) and selected: elif (not nodes.has(selector_key)) and selected:
var selector = ScnSelector.instantiate() var selector = ScnSelector.instantiate()
var rect: = [0, 0, 0, 0] var rect: = [0, 0, 0, 0]