From ed82e5b67d74646df04669eb8f2276ff1132f9b9 Mon Sep 17 00:00:00 2001 From: TotMaxim Date: Sun, 30 Nov 2025 19:27:08 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=9B=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D1=83=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/setting_prd_control.json | 13 ++--- scenes/pribor-prd-k/pribor-prd-k.gd | 13 +++-- scenes/pribor-prd-n/pribor-prd-n.gd | 8 +-- scenes/pribor-prd-v/pribor-prd-v.gd | 8 +-- scenes/контроль/блок-в.tscn | 6 +-- scenes/контроль/блок-к.tscn | 8 +-- scripts/prd-ctl-config.gd | 79 +++++++++++++++++++++++++++++ scripts/pribor-prd.gd | 50 ++++++++++-------- table/table.gd | 8 +-- 9 files changed, 144 insertions(+), 49 deletions(-) diff --git a/config/setting_prd_control.json b/config/setting_prd_control.json index 68b2d301..78a08e67 100644 --- a/config/setting_prd_control.json +++ b/config/setting_prd_control.json @@ -1,4 +1,5 @@ { + "config_version": "1.0.0", "device_constants": { "PRD_N": { "constants": { @@ -29,7 +30,7 @@ "2": {"freq": 932.0, "width": 100.0}, "3": {"freq": 1157.0, "width": 100.0} }, - "start_litera": 2, + "start_litera": 2 }, "PRD_V": { "constants": { @@ -60,7 +61,7 @@ "4": {"freq": 1227.0, "width": 100.0}, "5": {"freq": 1575.0, "width": 110.0} }, - "start_litera": 4, + "start_litera": 4 }, "PRD_K": { "constants": { @@ -94,7 +95,7 @@ "6": {"freq": 2450.0, "width": 110.0}, "7": {"freq": 4750.0, "width": 110.0} }, - "start_litera": 1, + "start_litera": 1 } }, "base_configs": { @@ -128,7 +129,7 @@ "dou_3": false, "fs_2": false, "fs_3": false, - "is_over_control": false, + "is_over_control": false } }, "PRD_V": { @@ -144,7 +145,7 @@ "dou_5": false, "fs_4": false, "fs_5": false, - "is_over_control": false, + "is_over_control": false } }, "PRD_K": { @@ -171,7 +172,7 @@ "fs_1": false, "fs_6": false, "fs_7": false, - "is_over_control": false, + "is_over_control": false } } }, diff --git a/scenes/pribor-prd-k/pribor-prd-k.gd b/scenes/pribor-prd-k/pribor-prd-k.gd index fb6aae9f..01546878 100644 --- a/scenes/pribor-prd-k/pribor-prd-k.gd +++ b/scenes/pribor-prd-k/pribor-prd-k.gd @@ -176,14 +176,17 @@ static func on_control_result(for_result_dic: Dictionary) -> void: f.state = result_dic[fs_meta] if not all_y5_good: return - if result_dic.fs_1 == 1 and block_kasseta_y5_prd_config_k['yau07']: + var fs_1 = true if int(result_dic.fs_1) == 1 else false + if fs_1 and block_kasseta_y5_prd_config_k['yau07']: for_result_dic.module_fs_1.state = STATE_VAL.GOOD if result_dic.dkm_1 else STATE_VAL.ERROR - - if result_dic.fs_6 == 1 and block_kasseta_y5_prd_config_k['yau07']: + + var fs_6 = true if int(result_dic.fs_6) == 1 else false + if fs_6 and block_kasseta_y5_prd_config_k['yau07']: for_result_dic.module_fs_6.state = STATE_VAL.GOOD if result_dic.dkm_6 else STATE_VAL.ERROR for_result_dic.dou_6.state = STATE_VAL.GOOD if result_dic.dou_6 else STATE_VAL.ERROR - - if result_dic.fs_7 == 1 and block_kasseta_y5_prd_config_k['yau07']: + + var fs_7 = true if int(result_dic.fs_7) == 1 else false + if fs_7 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.dou_7.state = STATE_VAL.GOOD if result_dic.dou_7 else STATE_VAL.ERROR diff --git a/scenes/pribor-prd-n/pribor-prd-n.gd b/scenes/pribor-prd-n/pribor-prd-n.gd index a8617c1e..b246c83e 100644 --- a/scenes/pribor-prd-n/pribor-prd-n.gd +++ b/scenes/pribor-prd-n/pribor-prd-n.gd @@ -166,11 +166,13 @@ static func on_control_result(for_result_dic: Dictionary) -> void: f.state = result_dic[fs_meta] if not all_y5_good: return - if result_dic.fs_2 == 1 and block_kasseta_y5_prd_config_n['yau07']: + var fs_2 = true if int(result_dic.fs_2) == 1 else false + if fs_2 and block_kasseta_y5_prd_config_n['yau07']: for_result_dic.module_fs_2.state = STATE_VAL.GOOD if result_dic.dkm_2 else STATE_VAL.ERROR for_result_dic.dou_2.state = STATE_VAL.GOOD if result_dic.dou_2 else STATE_VAL.ERROR - - if result_dic.fs_3 == 1 and block_kasseta_y5_prd_config_n['yau07']: + + var fs_3 = true if int(result_dic.fs_3) == 1 else false + if fs_3 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.dou_3.state = STATE_VAL.GOOD if result_dic.dou_3 else STATE_VAL.ERROR diff --git a/scenes/pribor-prd-v/pribor-prd-v.gd b/scenes/pribor-prd-v/pribor-prd-v.gd index 500fb19e..0509a549 100644 --- a/scenes/pribor-prd-v/pribor-prd-v.gd +++ b/scenes/pribor-prd-v/pribor-prd-v.gd @@ -162,11 +162,13 @@ static func on_control_result(for_result_dic: Dictionary) -> void: f.state = result_dic[fs_meta] if not all_y5_good: return - if result_dic.fs_5 == 1 and block_kasseta_y5_prd_config_v['yau07']: + var fs_5 = true if int(result_dic.fs_5) == 1 else false + if fs_5 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.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']: + + var fs_4 = true if int(result_dic.fs_4) == 1 else false + if fs_4 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.dou_4.state = STATE_VAL.GOOD if result_dic.dou_4 else STATE_VAL.ERROR diff --git a/scenes/контроль/блок-в.tscn b/scenes/контроль/блок-в.tscn index 87f8b08e..5275bec3 100644 --- a/scenes/контроль/блок-в.tscn +++ b/scenes/контроль/блок-в.tscn @@ -36,6 +36,7 @@ signal pressed(control: PanelContainer) return $margin/vbox/grid1/level7.value = v $margin/vbox/grid1/level7.tint_progress = Color.RED if v >= 50 else Color.GOLD if v >= 40 else Color.WHITE + on_level_changed(v, $margin/vbox/grid1/level7, value1_info) @export var min_value0: float: @@ -150,12 +151,11 @@ func _ready(): item.connect('value_changed', on_level_changed.bind(item, value0_info)) on_level_changed(item.value, item, value0_info) var level7: = $margin/vbox/grid1/level7 - level7.connect('value_changed', on_level_changed.bind(level7, value1_info)) on_level_changed(level7.value, level7, value1_info) -func on_level_changed(_val: float, item: TextureProgressBar, info: String): - item.tooltip_text = '%s\\nТекущее: %0.2f\\nДиапазон: %0.2f…%0.2f' % [info, item.value, item.min_value, item.max_value] +func on_level_changed(val: float, item: TextureProgressBar, info: String): + item.tooltip_text = '%s\\nТекущее: %0.2f\\nДиапазон: %0.2f…%0.2f' % [info, val, item.min_value, item.max_value] func set_group_param(items: Array, param: StringName, v) -> void: diff --git a/scenes/контроль/блок-к.tscn b/scenes/контроль/блок-к.tscn index 3ab9579d..6ffeb644 100644 --- a/scenes/контроль/блок-к.tscn +++ b/scenes/контроль/блок-к.tscn @@ -36,6 +36,7 @@ signal pressed(control: PanelContainer) return $margin/vbox/grid1/level7.value = v $margin/vbox/grid1/level7.tint_progress = Color.RED if v >= 50 else Color.GOLD if v >= 40 else Color.WHITE + on_level_changed(v, $margin/vbox/grid1/level7, value1_info) @export var min_value0: float: @@ -150,12 +151,11 @@ func _ready(): item.connect('value_changed', on_level_changed.bind(item, value0_info)) on_level_changed(item.value, item, value0_info) var level7: = $margin/vbox/grid1/level7 - level7.connect('value_changed', on_level_changed.bind(level7, value1_info)) on_level_changed(level7.value, level7, value1_info) -func on_level_changed(_val: float, item: TextureProgressBar, info: String): - item.tooltip_text = '%s\\nТекущее: %0.2f\\nДиапазон: %0.2f…%0.2f' % [info, item.value, item.min_value, item.max_value] +func on_level_changed(val: float, item: TextureProgressBar, info: String): + item.tooltip_text = '%s\\nТекущее: %0.2f\\nДиапазон: %0.2f…%0.2f' % [info, val, item.min_value, item.max_value] func set_group_param(items: Array, param: StringName, v) -> void: @@ -366,7 +366,7 @@ size_flags_horizontal = 3 size_flags_vertical = 3 tooltip_text = " Текущее: -40.00 -Диапазон: -40.00…60.00" +Диапазон: -40.00…55.00" mouse_filter = 0 min_value = -40.0 max_value = 55.0 diff --git a/scripts/prd-ctl-config.gd b/scripts/prd-ctl-config.gd index d6f8462a..b5851062 100644 --- a/scripts/prd-ctl-config.gd +++ b/scripts/prd-ctl-config.gd @@ -7,6 +7,7 @@ extends RefCounted #region CONSTANTS const CONFIG_PATH = "user://config/setting_prd_control.json" const DEFAULT_CONFIG_PATH = "res://config/setting_prd_control.json" +const CONFIG_VERSION = "1.0.0" # Версия конфигурации - увеличивать при изменениях #endregion #region PRIVATE_VARIABLES @@ -21,6 +22,7 @@ var _ems_input_bits_config: Dictionary # Конфигурация бито var _fs_rules: Array # Правила ФС var _is_loaded: bool = false # Флаг успешной загрузки +var _current_version: String = "" # Текущая версия загруженной конфигурации #endregion #region INITIALIZATION @@ -34,6 +36,14 @@ func _init() -> void: func is_loaded() -> bool: return _is_loaded +## Возвращает текущую версию загруженной конфигурации +func get_config_version() -> String: + return _current_version + +## Проверяет, актуальна ли конфигурация +func is_config_up_to_date() -> bool: + return _current_version == CONFIG_VERSION + ## Возвращает все данные конфигурации func get_config_data() -> Dictionary: return _config_data.duplicate(true) @@ -91,6 +101,7 @@ func _load_configuration() -> void: var parse_result = json.parse(json_text) if parse_result == OK: _config_data = json.data + _current_version = _config_data.get("config_version", "0.0.0") _parse_config_data() _is_loaded = true else: @@ -140,6 +151,10 @@ func _ensure_config_exists() -> bool: # Создаем папку конфигурации если не существует DirAccess.make_dir_recursive_absolute("user://config") + # Проверяем, нужно ли обновить конфигурацию + if _should_update_config(): + return _update_config() + # Если файл уже существует - все ок if FileAccess.file_exists(CONFIG_PATH): return true @@ -149,9 +164,73 @@ func _ensure_config_exists() -> bool: return false # Копируем дефолтный конфиг в user директорию + return _copy_default_config() + + +## Проверяет, нужно ли обновить конфигурацию +func _should_update_config() -> bool: + # Если файла конфигурации нет - нужно создать + if not FileAccess.file_exists(CONFIG_PATH): + return true + + # Проверяем версию существующей конфигурации + var config_file = FileAccess.open(CONFIG_PATH, FileAccess.READ) + if config_file: + var json_text = config_file.get_as_text() + config_file.close() + + var json = JSON.new() + if json.parse(json_text) == OK: + var existing_version = json.data.get("config_version", "0.0.0") + # Сравниваем версии + return _compare_versions(existing_version, CONFIG_VERSION) < 0 + else: + # Если ошибка парсинга - нужно обновить + return true + + return false + + +## Сравнивает две версии (semantic versioning) +## Возвращает -1 если version1 < version2, 0 если равны, 1 если version1 > version2 +static func _compare_versions(version1: String, version2: String) -> int: + var v1_parts = version1.split(".") + var v2_parts = version2.split(".") + + for i in range(max(v1_parts.size(), v2_parts.size())): + var v1_part = int(v1_parts[i]) if i < v1_parts.size() else 0 + var v2_part = int(v2_parts[i]) if i < v2_parts.size() else 0 + + if v1_part < v2_part: + return -1 + elif v1_part > v2_part: + return 1 + + return 0 + + +## Обновляет конфигурацию до актуальной версии +func _update_config() -> bool: + # Создаем резервную копию старой конфигурации + if FileAccess.file_exists(CONFIG_PATH): + var backup_path = CONFIG_PATH + ".backup_v" + _current_version + DirAccess.copy_absolute(CONFIG_PATH, backup_path) + print("Создана резервная копия: ", backup_path) + + # Копируем актуальную конфигурацию + return _copy_default_config() + + +## Копирует дефолтную конфигурацию в user директорию +func _copy_default_config() -> bool: + if not FileAccess.file_exists(DEFAULT_CONFIG_PATH): + push_error("Дефолтный файл конфигурации не найден: " + DEFAULT_CONFIG_PATH) + return false + var src := FileAccess.open(DEFAULT_CONFIG_PATH, FileAccess.READ) var dst := FileAccess.open(CONFIG_PATH, FileAccess.WRITE) if src == null or dst == null: + push_error("Ошибка копирования конфигурации") return false dst.store_string(src.get_as_text()) diff --git a/scripts/pribor-prd.gd b/scripts/pribor-prd.gd index f777c8fd..58ca196c 100644 --- a/scripts/pribor-prd.gd +++ b/scripts/pribor-prd.gd @@ -34,6 +34,11 @@ const RAY_CONFIG = { 5: { 'state': 'UG_SET_RAY_5', 'name': '45°'}, 6: { 'state': 'UG_SET_RAY_0', 'name': 'Контроль'} # ДКМ } +const ATT_MAPPING = { + 1: 'ATT_UM_3', + 2: 'ATT_UM_1', 4: 'ATT_UM_1', 6: 'ATT_UM_1', + 3: 'ATT_UM_2', 5: 'ATT_UM_2', 7: 'ATT_UM_2' +} # Таблица соответствий: device_name -> (current_lit -> nmfs в ecms) const LITER_TO_NMFS: Dictionary = { '1к': {1: 11, 6: 16, 7: 17}, @@ -427,7 +432,10 @@ func _handle_fs_work_state() -> void: _set_status('Проверка связи сервиса КАПС РПБ') if not flags.ecm_is_comming: return if current_ecm_key != 0 and flags.fs_status_ok: - _set_status('Проверка ФС-%s' % current_litera) + if not flags.si_fs_input: + _set_status('Ожидание сигнала излучения от ФС-%s' % current_litera) + else: + _set_status('Проверка ФС-%s' % current_litera) # Если ФС в порядке if (current_litera == 2 and control_results.fs_2) or \ (current_litera == 3 and control_results.fs_3) or \ @@ -508,9 +516,6 @@ func _handle_stop_control_state() -> void: flags.ecm_is_comming = false state = STATE_MACHINE.INIT - if flags.no_trust_yau07: - state = STATE_MACHINE.STOP_CONTROL - ## Переход к следующей литере контроля func _advance_to_next_fs() -> void: @@ -550,12 +555,9 @@ func _handle_ray_read_mode() -> void: func _handle_ray_write_mode(ray_num: int) -> void: if not _can_write_ray(): return - - # Особые условия для луча 0 и 5 на 1 литере + if ray_num == 0 and current_litera != 1 and not control_timer.is_stopped(): control_timer.stop() - elif ray_num == 5 and not control_timer.is_stopped(): - control_timer.stop() # Установка луча if not flags.write_isa: _handle_ug_set_state(ray_num) @@ -589,7 +591,7 @@ func _can_process_ray_state(addr: int) -> bool: ## Проверка возможности записи луча func _can_write_ray() -> bool: if not flags.si_fs_input: - _set_status('Ожидание сигнала излучения от ФС-%s' % current_litera ) + _set_status('Ожидание сигнала излучения от ФС-%s' % current_litera) return false else: return true @@ -605,7 +607,6 @@ func _get_ug_address() -> int: ## Подготовка к настройке и записи в УГ func _handle_ug_set_state(RAY_DOU_NUM: int) -> void: var def_att: int = 0x00 - _set_status('Настройка угла %s' % _get_ray_name(RAY_DOU_NUM)) var dic_att := { 'RAY_DOU_NUM': RAY_DOU_NUM, 'ADDR_UG_LITERA_1': constants.ADDR_UG_LITERA_1, @@ -626,7 +627,10 @@ func _handle_ug_set_state(RAY_DOU_NUM: int) -> void: elif self_name == '1н' or self_name == '2н' or self_name == '3н' or self_name == '4н': dic_att['ATT_UM_1'] = constants.ATT_UM_2 dic_att['ATT_UM_2'] = constants.ATT_UM_3 - flags.write_isa = on_ug_setting(unit_prd, dic_att, cmd_array) + + var att_key = ATT_MAPPING[current_litera] + _set_status('Литера-%s: Настройка угла %s, АТТ %s' % [current_litera, _get_ray_name(RAY_DOU_NUM), dic_att[att_key]]) + flags.write_isa = on_ug_setting(unit_prd, dic_att, cmd_array, current_litera) count_packets_power = 0 @@ -731,8 +735,6 @@ func on_state_mashine(): ## Обработка таймаута контроля func on_stop_control() -> void: - _handle_fs_turn_off_state() - if state == STATE_MACHINE.UG_SET_RAY: flags.no_trust_yau07 = true state = STATE_MACHINE.IN_EMS_STOP @@ -835,8 +837,9 @@ func on_fs_update_state(packet_type_7: Dictionary, fs_mapping: Dictionary) -> vo var fs_result := {fs_key: 0} fs_result = on_fs_state(packet_type_7, fs_mapping, fs_result, _fs_rules) + flags.fs_status_ok = true if fs_result[fs_key] == 1 else false + if not flags.si_fs_input: return control_results[fs_key] = fs_result[fs_key] - flags.fs_status_ok = control_results[fs_key] == 1 ## Обработка изменения размера интерферометра @@ -991,14 +994,17 @@ static func on_y5_control_result(block_kasseta: Dictionary) -> bool: ## Установка угла и аттенюации для УМ -static func on_ug_setting(prd_unit: Object, settings_ug: Dictionary, prd_cmd_array: Array) -> bool: - var result_1 = ((settings_ug.ATT_UM_1 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07) - var result_2 = ((settings_ug.ATT_UM_2 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07) - prd_cmd_array.append([prd_unit.CmdCode.WRITE_ISA, [ settings_ug.ADDR_UG_LITERA_1, result_1, - settings_ug.ADDR_UG_LITERA_2, result_2, - settings_ug.ADDR_UG_LITERA_3, settings_ug.ATT_UM_3, - ] - ]) +static func on_ug_setting(prd_unit: Object, settings_ug: Dictionary, prd_cmd_array: Array, cur_litera: int) -> bool: + var result: int + if cur_litera in [2, 4, 6]: + result = ((settings_ug.ATT_UM_1 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07) + prd_cmd_array.append([prd_unit.CmdCode.WRITE_ISA, [settings_ug.ADDR_UG_LITERA_1, result]]) + elif cur_litera in [3, 5, 7]: + result = ((settings_ug.ATT_UM_2 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07) + prd_cmd_array.append([prd_unit.CmdCode.WRITE_ISA, [settings_ug.ADDR_UG_LITERA_2, result]]) + elif cur_litera == 1: + result = ((settings_ug.ATT_UM_2 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07) + prd_cmd_array.append([prd_unit.CmdCode.WRITE_ISA, [settings_ug.ADDR_UG_LITERA_3, settings_ug.ATT_UM_3]]) return true diff --git a/table/table.gd b/table/table.gd index 80839cff..f17dbfe2 100644 --- a/table/table.gd +++ b/table/table.gd @@ -449,9 +449,11 @@ func remove_row(i_row: int): if nodes.has(sel_key): var selector = nodes[sel_key] - var prnt = selector.get_parent() - prnt.remove_child(selector) - selector.queue_free() + if is_instance_valid(selector): + var prnt = selector.get_parent() + if prnt: + prnt.remove_child(selector) + selector.queue_free() nodes.erase(sel_key) for i_col in columns: