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: