Доработка Логики конфигураций
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user