diff --git a/README.md b/README.md index 03896213..bdc8ad58 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ +# Разработка + +- После клонирования запустить скрипт `git-hooks-config.sh` + - В среде **Windows** запуск скрипта `git-hooks-config.sh` производить из оболочки `git bash` +- При необходимости обновить `settings.json` +- Использовать выражения вида `ProjectSettings.set_setting('application/config/%s' % key_name` +и `ProjectSettings.get_setting('application/config/%s % key_name)` для доступа к настройкам. + - `key_name` брать из таблицы `res://scenes/настройки/настройки.gd/SETTING_TABLE` +- Следовать [общим правилам](http://gitea.srez.local:3000/sasha80/gitea-tniis). + # Ссылки на составные части - [Исполняемые файлы для шаблонов экспорта и редактора](http://gitea.srez.local:3000/sasha80/godot-bin) @@ -31,9 +41,3 @@ необходимые для этого настройки. - Для доступа к последовательным портам расположенным на другом вычислительном модуле, следует использовать [проброс портов](http://gitea.srez.local:3000/sasha80/uart-forwarder). - -# Разработка - -- После клонирования запустить скрипт `git-hooks-config.sh` -- В среде **Windows** запуск скрипта `git-hooks-config.sh` производить из оболочки `git bash` -- При необходимости обновить `settings.json` diff --git a/data/secondary-font.tres b/data/secondary-font.tres index db9155eb..819c700f 100644 --- a/data/secondary-font.tres +++ b/data/secondary-font.tres @@ -4,19 +4,6 @@ [resource] fallbacks = Array[Font]([ExtResource("1_cxid7")]) -cache/0/17/0/ascent = 0.0 -cache/0/17/0/descent = 0.0 -cache/0/17/0/underline_position = 0.0 -cache/0/17/0/underline_thickness = 0.0 -cache/0/17/0/scale = 1.0 -cache/0/17/0/kerning_overrides/17/0 = Vector2(0, 0) -cache/0/17/0/kerning_overrides/16/0 = Vector2(0, 0) -cache/0/17/0/kerning_overrides/18/0 = Vector2(0, 0) -cache/0/17/0/kerning_overrides/14/0 = Vector2(0, 0) -cache/0/17/0/kerning_overrides/8/0 = Vector2(0, 0) -cache/0/17/0/kerning_overrides/15/0 = Vector2(0, 0) -cache/0/17/0/kerning_overrides/13/0 = Vector2(0, 0) -cache/0/17/0/kerning_overrides/20/0 = Vector2(0, 0) cache/0/16/0/ascent = 0.0 cache/0/16/0/descent = 0.0 cache/0/16/0/underline_position = 0.0 @@ -30,6 +17,24 @@ cache/0/16/0/kerning_overrides/8/0 = Vector2(0, 0) cache/0/16/0/kerning_overrides/15/0 = Vector2(0, 0) cache/0/16/0/kerning_overrides/13/0 = Vector2(0, 0) cache/0/16/0/kerning_overrides/20/0 = Vector2(0, 0) +cache/0/17/0/ascent = 0.0 +cache/0/17/0/descent = 0.0 +cache/0/17/0/underline_position = 0.0 +cache/0/17/0/underline_thickness = 0.0 +cache/0/17/0/scale = 1.0 +cache/0/17/0/kerning_overrides/17/0 = Vector2(0, 0) +cache/0/17/0/kerning_overrides/16/0 = Vector2(0, 0) +cache/0/17/0/kerning_overrides/18/0 = Vector2(0, 0) +cache/0/17/0/kerning_overrides/14/0 = Vector2(0, 0) +cache/0/17/0/kerning_overrides/8/0 = Vector2(0, 0) +cache/0/17/0/kerning_overrides/15/0 = Vector2(0, 0) +cache/0/17/0/kerning_overrides/13/0 = Vector2(0, 0) +cache/0/17/0/kerning_overrides/20/0 = Vector2(0, 0) +cache/0/22/0/ascent = 0.0 +cache/0/22/0/descent = 0.0 +cache/0/22/0/underline_position = 0.0 +cache/0/22/0/underline_thickness = 0.0 +cache/0/22/0/scale = 1.0 cache/0/18/0/ascent = 0.0 cache/0/18/0/descent = 0.0 cache/0/18/0/underline_position = 0.0 @@ -113,8 +118,3 @@ cache/0/19/0/descent = 0.0 cache/0/19/0/underline_position = 0.0 cache/0/19/0/underline_thickness = 0.0 cache/0/19/0/scale = 1.0 -cache/0/22/0/ascent = 0.0 -cache/0/22/0/descent = 0.0 -cache/0/22/0/underline_position = 0.0 -cache/0/22/0/underline_thickness = 0.0 -cache/0/22/0/scale = 1.0 diff --git a/data/Окно частот0.png.import b/data/Окно частот0.png.import index 3b53336a..a345503a 100644 --- a/data/Окно частот0.png.import +++ b/data/Окно частот0.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://b1dw06ahtftq2" +uid="uid://csxruavk0s40l" path="res://.godot/imported/Окно частот0.png-79ada2e7504614b9bdf58bce1aff61fb.ctex" metadata={ "vram_texture": false diff --git a/data/Скруглённый квадрат серый.png.import b/data/Скруглённый квадрат серый.png.import index c348d23a..9d16be2e 100644 --- a/data/Скруглённый квадрат серый.png.import +++ b/data/Скруглённый квадрат серый.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bymxiptkbufvs" +uid="uid://fuhhvsa5um4m" path="res://.godot/imported/Скруглённый квадрат серый.png-2111d7338e52a03a41f05d6ffbbc3eb6.ctex" metadata={ "vram_texture": false diff --git a/export_presets.cfg b/export_presets.cfg index dc12e8f0..23d800df 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -22,7 +22,7 @@ script_export_mode=0 custom_template/debug="" custom_template/release="" -debug/export_console_wrapper=2 +debug/export_console_wrapper=0 binary_format/embed_pck=true texture_format/s3tc_bptc=true texture_format/etc2_astc=false diff --git a/project.godot b/project.godot index 922bfd47..dc2a071e 100644 --- a/project.godot +++ b/project.godot @@ -74,7 +74,6 @@ gdscript/warnings/unassigned_variable_op_assign=2 gdscript/warnings/unused_signal=0 gdscript/warnings/shadowed_variable=2 gdscript/warnings/shadowed_variable_base_class=2 -gdscript/warnings/shadowed_global_identifier=2 gdscript/warnings/unsafe_cast=1 gdscript/warnings/assert_always_true=2 gdscript/warnings/assert_always_false=2 @@ -206,8 +205,6 @@ common/enable_object_picking=false [rendering] -renderer/rendering_method="gl_compatibility" -renderer/rendering_method.mobile="gl_compatibility" shader_compiler/shader_cache/strip_debug=true quality/driver/fallback_to_gles2=true diff --git a/scenes/button-flat/button-flat.tscn b/scenes/button-flat/button-flat.tscn index 607ed5f6..35c9aa87 100644 --- a/scenes/button-flat/button-flat.tscn +++ b/scenes/button-flat/button-flat.tscn @@ -61,8 +61,8 @@ script = ExtResource("1_ui6sg") visible = false z_as_relative = false layout_mode = 2 -border_color = Color(0, 0.549509, 0.921779, 1) -border_width = 5.0 +border_color = Color(0.0941176, 0.0941176, 0.698039, 1) +border_width = 10.0 editor_only = false [node name="back" type="Sprite2D" parent="."] diff --git a/scenes/frame-ecm-list/scroll-ecm-list.gd b/scenes/frame-ecm-list/scroll-ecm-list.gd index 8ad0a9fd..47506b7a 100644 --- a/scenes/frame-ecm-list/scroll-ecm-list.gd +++ b/scenes/frame-ecm-list/scroll-ecm-list.gd @@ -37,7 +37,7 @@ const INTERFER_NAMES = { 'k1': 'K1', 'svm2': 'СВ-М2', 'ozp1': 'ОЗП-1', - 'eprls': 'ЕПРЛС',} + 'eprls': 'ЕПРЛС' } ## Индексы колонок @@ -127,7 +127,10 @@ func on_interfer_new(ecm, table_index): func on_interfer_off(ecm, table_index): - $table.remove_row(table_index[ecm.ispp]) + if not table_index.has(ecm.ispp): + return + var i_row = table_index[ecm.ispp] + $table.remove_row(i_row) rehash(table_index) var sel_rows: Array $table.get_selected_rows(sel_rows) diff --git a/scenes/frame-threats/scroll-threats.gd b/scenes/frame-threats/scroll-threats.gd index be9dc979..c224021b 100644 --- a/scenes/frame-threats/scroll-threats.gd +++ b/scenes/frame-threats/scroll-threats.gd @@ -10,7 +10,7 @@ const EmitLed = preload('res://scenes/frame-threats/emit-led.tscn') ## const TABLE_HEADER = [ TableHeader, TableHeader, TableHeader, TableHeader , TableHeader ] ## Описание ряда заголовка. const TABLE_ROW = [ CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, EmitLed ] ## Описание ряда. const TABLE_COLUMN_PARAM = ['id', 'aoa', 'freq', 'proto', 'emit' ] ## Параметры цели отображаемые в таблице. -const TABLE_HEADERS_TEXT = ['№', 'Пеленг', 'Частота, МГц', 'Протокол', 'Помеха' ] ## Заголовки таблицы. +const TABLE_HEADERS_TEXT = ['Номер', 'Пеленг', 'Частота, МГц', 'Протокол', 'Помеха' ] ## Заголовки таблицы. const TABLE_COLUMN_SIZE = [ 65, 70, 110, 140, 65] ## Ширины колонок. const TABLE_TEXT_ROWS = 4 diff --git a/scenes/pribor-prd-k/pribor-prd-k.gd b/scenes/pribor-prd-k/pribor-prd-k.gd index 04da31fb..14f73714 100644 --- a/scenes/pribor-prd-k/pribor-prd-k.gd +++ b/scenes/pribor-prd-k/pribor-prd-k.gd @@ -16,11 +16,12 @@ func _ready() -> void: unit_prd_k = prd_k_module.unit_control var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier') for temp in power_amplifier: - temp.value1 = -70 + temp.value1 = -100 # Подписываемся на сигналы signaller.conn(signaller.start_contol_device, Callable(self, '_on_start_control')) unit_prd_k.connect('control_is_over', Callable(self, 'on_press_device')) unit_prd_k.connect('status_updated', Callable(self, '_on_status_updated')) + find_labels(self) # Устанавливаем начальный статус _update_status_text(unit_prd_k.get_current_status()) on_press_device(unit_prd_k.self_name) @@ -43,7 +44,6 @@ func set_frame(node_frame: Node, val: int): node_frame.set_frame(val) 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('power_amplifier')) - find_labels(self) await get_tree().create_timer(1.0).timeout on_press_device(unit_prd_k.self_name) @@ -196,16 +196,16 @@ static func on_control_result(for_result_dic: Dictionary) -> void: func find_labels(node1: Node): if node1 is Label: - if node1.name in ["lbl_rname", "rname"]: - if not node1.has_meta("tooltip_set"): + if node1.name in ['lbl_rname', 'rname']: + if not node1.has_meta('tooltip_set'): ctrl_pos += 1 var box_number = ceili(float(ctrl_pos) / 10.0) var position_number = ctrl_pos % 10 if position_number == 0: position_number = 10 - node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number] + node1.tooltip_text = 'Ящик - %d, Позиция - %d' % [box_number, position_number] node1.mouse_filter = Control.MOUSE_FILTER_STOP - node1.set_meta("tooltip_set", true) + node1.set_meta('tooltip_set', true) for child in node1.get_children(): find_labels(child) @@ -217,12 +217,12 @@ func _on_status_updated(status_text: String) -> void: func _update_status_text(text: String) -> void: $control_result.text = text # Можно добавить смену цвета в зависимости от статуса - if "Ошибка" in text or "неисправен" in text: + if 'Ошибка' in text or 'неисправен' in text: $control_result.add_theme_color_override('font_color', Color.RED) log.message(Logger.INFO, 'Прибор ПРД-%s неисправен' % [unit_prd_k.self_name]) - elif "Ограничена" in text or "Предупреждение" in text: + elif 'Ограничена' in text or 'Предупреждение' in text: $control_result.add_theme_color_override('font_color', Color.YELLOW) - elif "исправен" in text or "завершён" in text: + elif 'исправен' in text or 'завершён' in text: $control_result.add_theme_color_override('font_color', Color.GREEN) log.message(Logger.INFO, 'Прибор ПРД-%s исправен' % [unit_prd_k.self_name]) else: diff --git a/scenes/pribor-prd-n/pribor-prd-n.gd b/scenes/pribor-prd-n/pribor-prd-n.gd index 8b16452a..8cb1684d 100644 --- a/scenes/pribor-prd-n/pribor-prd-n.gd +++ b/scenes/pribor-prd-n/pribor-prd-n.gd @@ -16,11 +16,12 @@ func _ready() -> void: unit_prd_n = prd_n_module.unit_control var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier') for temp in power_amplifier: - temp.value1 = -70 + temp.value1 = -100 # Подписываемся на сигналы signaller.conn(signaller.start_contol_device, Callable(self, '_on_start_control')) unit_prd_n.connect('control_is_over', Callable(self, 'on_press_device')) unit_prd_n.connect('status_updated', Callable(self, '_on_status_updated')) + find_labels(self) # Устанавливаем начальный статус _update_status_text(unit_prd_n.get_current_status()) on_press_device(unit_prd_n.self_name) @@ -43,7 +44,6 @@ func _on_start_control() -> void: set_default_state(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] - find_labels(self) await get_tree().create_timer(1.0).timeout on_press_device(unit_prd_n.self_name) @@ -182,16 +182,16 @@ static func on_control_result(for_result_dic: Dictionary) -> void: func find_labels(node1: Node): if node1 is Label: - if node1.name in ["lbl_rname", "rname"]: - if not node1.has_meta("tooltip_set"): + if node1.name in ['lbl_rname', 'rname']: + if not node1.has_meta('tooltip_set'): ctrl_pos += 1 var box_number = ceili(float(ctrl_pos) / 10.0) var position_number = ctrl_pos % 10 if position_number == 0: position_number = 10 - node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number] + node1.tooltip_text = 'Ящик - %d, Позиция - %d' % [box_number, position_number] node1.mouse_filter = Control.MOUSE_FILTER_STOP - node1.set_meta("tooltip_set", true) + node1.set_meta('tooltip_set', true) for child in node1.get_children(): find_labels(child) @@ -203,12 +203,12 @@ func _on_status_updated(status_text: String) -> void: func _update_status_text(text: String) -> void: $control_result.text = text # Можно добавить смену цвета в зависимости от статуса - if "Ошибка" in text or "неисправен" in text: + if 'Ошибка' in text or 'неисправен' in text: $control_result.add_theme_color_override('font_color', Color.RED) log.message(Logger.INFO, 'Прибор ПРД-%s неисправен' % [unit_prd_n.self_name]) - elif "Ограничена" in text or "Предупреждение" in text: + elif 'Ограничена' in text or 'Предупреждение' in text: $control_result.add_theme_color_override('font_color', Color.YELLOW) - elif "исправен" in text or "завершён" in text: + elif 'исправен' in text or 'завершён' in text: $control_result.add_theme_color_override('font_color', Color.GREEN) log.message(Logger.INFO, 'Прибор ПРД-%s исправен' % [unit_prd_n.self_name]) else: diff --git a/scenes/pribor-prd-v/pribor-prd-v.gd b/scenes/pribor-prd-v/pribor-prd-v.gd index 2229c2a2..3b55452f 100644 --- a/scenes/pribor-prd-v/pribor-prd-v.gd +++ b/scenes/pribor-prd-v/pribor-prd-v.gd @@ -16,11 +16,12 @@ func _ready() -> void: unit_prd_v = prd_v_module.unit_control var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier') for temp in power_amplifier: - temp.value1 = -70 + temp.value1 = -100 # Подписываемся на сигналы signaller.conn(signaller.start_contol_device, Callable(self, '_on_start_control')) unit_prd_v.connect('control_is_over', Callable(self, 'on_press_device')) unit_prd_v.connect('status_updated', Callable(self, '_on_status_updated')) + find_labels(self) # Устанавливаем начальный статус _update_status_text(unit_prd_v.get_current_status()) on_press_device(unit_prd_v.self_name) @@ -43,7 +44,6 @@ func _on_start_control() -> void: set_default_state(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] - find_labels(self) await get_tree().create_timer(1.0).timeout on_press_device(unit_prd_v.self_name) @@ -178,16 +178,16 @@ static func on_control_result(for_result_dic: Dictionary) -> void: func find_labels(node1: Node): if node1 is Label: - if node1.name in ["lbl_rname", "rname"]: - if not node1.has_meta("tooltip_set"): + if node1.name in ['lbl_rname', 'rname']: + if not node1.has_meta('tooltip_set'): ctrl_pos += 1 var box_number = ceili(float(ctrl_pos) / 10.0) var position_number = ctrl_pos % 10 if position_number == 0: position_number = 10 - node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number] + node1.tooltip_text = 'Ящик - %d, Позиция - %d' % [box_number, position_number] node1.mouse_filter = Control.MOUSE_FILTER_STOP - node1.set_meta("tooltip_set", true) + node1.set_meta('tooltip_set', true) for child in node1.get_children(): find_labels(child) @@ -199,12 +199,12 @@ func _on_status_updated(status_text: String) -> void: func _update_status_text(text: String) -> void: $control_result.text = text # Можно добавить смену цвета в зависимости от статуса - if "Ошибка" in text or "неисправен" in text: + if 'Ошибка' in text or 'неисправен' in text: $control_result.add_theme_color_override('font_color', Color.RED) log.message(Logger.INFO, 'Прибор ПРД-%s неисправен' % [unit_prd_v.self_name]) - elif "Ограничена" in text or "Предупреждение" in text: + elif 'Ограничена' in text or 'Предупреждение' in text: $control_result.add_theme_color_override('font_color', Color.YELLOW) - elif "исправен" in text or "завершён" in text: + elif 'исправен' in text or 'завершён' in text: $control_result.add_theme_color_override('font_color', Color.GREEN) log.message(Logger.INFO, 'Прибор ПРД-%s исправен' % [unit_prd_v.self_name]) else: diff --git a/scenes/pribor-uf/pribor-uf.gd b/scenes/pribor-uf/pribor-uf.gd index acd59501..989d8f1a 100644 --- a/scenes/pribor-uf/pribor-uf.gd +++ b/scenes/pribor-uf/pribor-uf.gd @@ -1,126 +1,116 @@ @tool class_name pribor_uf extends 'res://scenes/контроль/прибор.gd' -signal control_is_over(device_name: String) # Когда контроль завершен enum STATE_VAL {NONE = 0, GOOD = 1, ERROR = 2} const DEV_LIST: Array = ['00:1f.6', '07:00.0', '08:00.0', '0b:00.0'] const USB_TRACKERBALL: String = '13ba:0018' const REVFF: String = '(rev ff)' -var unit_uf: Object +var uf_control: Object var ctrl_pos = 100 func _ready() -> void: if Engine.is_editor_hint(): return - signaller.conn(signaller.start_contol_device, Callable(self, '_on_start_contol_device')) - unit_uf = network.get_unit_instance('уарэп-эмс') - unit_uf.connect('line_changed', on_line_changed) - on_line_changed() #control_vk() - control_ems(unit_uf.status) - status_uf() + uf_control = get_parent().uf_control + signaller.connect('update_uf_serviceability', on_update_uf_serviceability) + var uf_status = uf_control.get_current_status() + control_ems(uf_status) find_labels(self) -func _on_start_contol_device(): - on_line_changed() - control_ems(unit_uf.status) # проверка ЭМС ячеек - status_uf() # отслеживание состояния прибора +func on_update_uf_serviceability(_state: int): + control_ems(uf_control.get_current_status()) -func on_line_changed(): - if unit_uf.online: # проверка ЯУ, внутреннего коммутатора и ИП-5Б +#func control_vk() -> void: + #var out_usb_str = '' + #var out_pci_str = '' + #var out_usb = [] + #var out_pci = [] +# + #OS.execute('lsusb', [], out_usb) # TODO: Не переносимое, платформозависимое + #for element in out_usb: + #out_usb_str += element +# + #OS.execute('lspci', [], out_pci) # TODO: Не переносимое, платформозависимое + #for element in out_pci: + #out_pci_str += element +# + #out_usb_str = out_usb_str.split('\n') + #out_pci_str = out_pci_str.split('\n') +# + #var i: int = 0 +# + #for string in out_usb_str: + #if USB_TRACKERBALL in string: + #i += 1 + #break + #for string in out_pci_str: + #for item in DEV_LIST: + #if item in string: + #i += 1 + #if REVFF in string: + #i -= 1 + #break +# + #if i == (DEV_LIST.size() + 1): + #$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD + #else: + #$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.ERROR + + +func control_ems(status: Dictionary) -> void: + if status['УФ-онлайн']: $ref_uf/ref_kassetav13/ref_A7_YAU07.state = STATE_VAL.GOOD $ref_uf/ref_kassetav13/ref_A3_IP5B.state = STATE_VAL.GOOD + $ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD $ref_uf/ref_kassetav13/ref_A9_ESW.state = STATE_VAL.GOOD - $ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD ## заглушка для зеленения ВК-110 + $ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.GOOD if status['КЭМС-Б1'] else STATE_VAL.ERROR + $ref_uf/ref_kassetav13/ref_A5_EMS.state = STATE_VAL.GOOD if status['ЭМС-Б1'] else STATE_VAL.ERROR + $ref_uf/ref_kassetav13/ref_A6_EMS.state = STATE_VAL.GOOD if status['ЭМС-Б2'] else STATE_VAL.ERROR + $ref_uf/ref_kassetav13/ref_A12_IP27B.state = STATE_VAL.GOOD if status['ИП220-27Б'] else STATE_VAL.ERROR else: $ref_uf/ref_kassetav13/ref_A7_YAU07.state = STATE_VAL.ERROR + $ref_uf/ref_kassetav13/ref_A3_IP5B.state = STATE_VAL.NONE + $ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.NONE + $ref_uf/ref_kassetav13/ref_A9_ESW.state = STATE_VAL.NONE $ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.NONE $ref_uf/ref_kassetav13/ref_A5_EMS.state = STATE_VAL.NONE $ref_uf/ref_kassetav13/ref_A6_EMS.state = STATE_VAL.NONE - $ref_uf/ref_kassetav13/ref_A3_IP5B.state = STATE_VAL.NONE - $ref_uf/ref_kassetav13/ref_A9_ESW.state = STATE_VAL.NONE $ref_uf/ref_kassetav13/ref_A12_IP27B.state = STATE_VAL.NONE - $ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.NONE + status_uf(status) -func control_vk() -> void: - var out_usb_str = '' - var out_pci_str = '' - var out_usb = [] - var out_pci = [] - - OS.execute('lsusb', [], out_usb) # TODO: Не переносимое, платформозависимое - for element in out_usb: - out_usb_str += element - - OS.execute('lspci', [], out_pci) # TODO: Не переносимое, платформозависимое - for element in out_pci: - out_pci_str += element - - out_usb_str = out_usb_str.split('\n') - out_pci_str = out_pci_str.split('\n') - - var i: int = 0 - - for string in out_usb_str: - if USB_TRACKERBALL in string: - i += 1 - break - for string in out_pci_str: - for item in DEV_LIST: - if item in string: - i += 1 - if REVFF in string: - i -= 1 - break - - if i == (DEV_LIST.size() + 1): - $ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD - else: - $ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.ERROR - - -func control_ems(status: Array) -> void: - if status: - $ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.GOOD if ((status[0] >> 0) & 1) and ((status[0] >> 3) & 1) else STATE_VAL.ERROR - $ref_uf/ref_kassetav13/ref_A5_EMS.state = STATE_VAL.GOOD if ((status[0] >> 1) & 1) and ((status[0] >> 4) & 1) else STATE_VAL.ERROR - $ref_uf/ref_kassetav13/ref_A6_EMS.state = STATE_VAL.GOOD if ((status[0] >> 2) & 1) and ((status[0] >> 5) & 1) else STATE_VAL.ERROR - $ref_uf/ref_kassetav13/ref_A12_IP27B.state = STATE_VAL.GOOD if ((status[2] >> 6) & 1) else STATE_VAL.ERROR - - -func status_uf() -> void: - var status_bu: int = $ref_uf/ref_bu1/ref_A8_BU.state - var status_yau: int = $ref_uf/ref_kassetav13/ref_A7_YAU07.state - var status_kyems: int = $ref_uf/ref_kassetav13/ref_A4_KEMS.state - var status_yems0: int = $ref_uf/ref_kassetav13/ref_A5_EMS.state - var status_yems1: int = $ref_uf/ref_kassetav13/ref_A6_EMS.state - var status_ip5: int = $ref_uf/ref_kassetav13/ref_A3_IP5B.state - var status_ip27: int = $ref_uf/ref_kassetav13/ref_A12_IP27B.state - - if (status_yau == 1) and (status_bu == 1) and (status_kyems == 1) \ - and (status_yems0 == 1) and (status_yems1 == 1) and (status_ip5 == 1) and (status_ip27 == 1): - $lbl_header2.text = 'Прибор исправен' - $lbl_header2.modulate = Color.GREEN - else: - $lbl_header2.text = 'Прибор неисправен' - $lbl_header2.modulate = Color.RED +func status_uf(status_uf_dic: Dictionary) -> void: + var is_ok: bool = true + if not status_uf_dic['УФ-онлайн']: + $lbl_header2.text = 'Ожидание связи с ЯУ-07Б' + $lbl_header2.modulate = Color.WHITE + elif status_uf_dic['УФ-онлайн']: + for socket in status_uf_dic: + if not status_uf_dic[socket]: + is_ok = false + if is_ok: + $lbl_header2.text = 'Прибор исправен' + $lbl_header2.modulate = Color.GREEN + elif not is_ok: + $lbl_header2.text = 'Прибор неисправен' + $lbl_header2.modulate = Color.RED $lbl_header2.visible = true - emit_signal('control_is_over', unit_uf.name) func find_labels(node1: Node): if node1 is Label: - if node1.name in ["lbl_rname", "rname"]: - if not node1.has_meta("tooltip_set"): + if node1.name in ['lbl_rname', 'rname']: + if not node1.has_meta('tooltip_set'): ctrl_pos += 1 var box_number = ceili(float(ctrl_pos) / 10.0) var position_number = ctrl_pos % 10 if position_number == 0: position_number = 10 - node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number] + node1.tooltip_text = 'Ящик - %d, Позиция - %d' % [box_number, position_number] node1.mouse_filter = Control.MOUSE_FILTER_STOP - node1.set_meta("tooltip_set", true) + node1.set_meta('tooltip_set', true) for child in node1.get_children(): find_labels(child) diff --git a/scenes/pribor-uf/uf-ctl.gd b/scenes/pribor-uf/uf-ctl.gd new file mode 100644 index 00000000..c44a0d97 --- /dev/null +++ b/scenes/pribor-uf/uf-ctl.gd @@ -0,0 +1,93 @@ +class_name UFControl extends Node + +signal update_uf_serviceability(status: int) + +#region Константы и переменные +enum StatusIndex {SOCKETS = 0, IP_220_27B = 2} +enum STATE_VAL {NONE = 0, GOOD = 1, ERROR = 2} +var unit_uf: Object +var uf_status: Dictionary = {'УФ-онлайн': false, 'КЭМС-Б1': false, 'ЭМС-Б1': false, 'ЭМС-Б2': false, 'ИП220-27Б': false} + +var _self_name: String +var _serviceability: int = STATE_VAL.NONE +var serviceability_uf: int: + get: + return _serviceability + set(value): + if value != _serviceability: + _serviceability = value + signaller.emit_signal('update_uf_serviceability', value) +#endregion + +#region Инициализация +func _init(name_uf: String) -> void: + _self_name = name_uf + unit_uf = network.get_unit_instance(_self_name) + unit_uf.connect('line_changed', on_line_changed) + unit_uf.connect('data_received', on_data_received) +#endregion + +#region Обработчики сигналов +func on_line_changed(status: Object) -> void: + '''Обработка изменения состояния линии связи''' + uf_status['УФ-онлайн'] = status.online + update_serviceability() + +func on_data_received(yau: Object) -> void: + '''Обработка полученных данных от УФ''' + var new_ems_status = control_ems(yau.status) + var status_changed = false + + # Обновляем только ключи КЭМС/ЭМС, сохраняя 'УФ-онлайн' + for key in ['КЭМС-Б1', 'ЭМС-Б1', 'ЭМС-Б2', 'ИП220-27Б']: + var old_value = uf_status.get(key, false) + var new_value = new_ems_status.get(key, false) + + if old_value != new_value: + uf_status[key] = new_value + status_changed = true + + if status_changed: + update_serviceability() +#endregion + +#region Статус и сервисабельность +func get_current_status() -> Dictionary: + '''Получение текущего статуса (только для чтения)''' + return uf_status.duplicate(true) + +func is_operational() -> bool: + '''Проверка, все ли системы работают нормально''' + return serviceability_uf and uf_status.get('УФ-онлайн', false) + + +func update_serviceability() -> void: + '''Обновление общего статуса сервисабельности''' + var new_serviceability: int = STATE_VAL.GOOD + + # Проверяем онлайн-статус + if uf_status.get('УФ-онлайн', false) == false: + new_serviceability = STATE_VAL.NONE + else: + # Проверяем все статусы КЭМС/ЭМС + for key in ['КЭМС-Б1', 'ЭМС-Б1', 'ЭМС-Б2', 'ИП220-27Б']: + if uf_status.get(key, true) == false: + new_serviceability = STATE_VAL.ERROR + break + # Новое значение через setter + self.serviceability_uf = new_serviceability +#endregion + +#region Вспомогательные методы +static func control_ems(status: Array) -> Dictionary: + '''Анализ статусов КЭМС/ЭМС''' + var status_dic: Dictionary = {} + if status.is_empty() or status.size() < 3: + return status_dic + + status_dic['КЭМС-Б1'] = bool((status[StatusIndex.SOCKETS] >> 0) & 1) and bool((status[StatusIndex.SOCKETS] >> 3) & 1) + status_dic['ЭМС-Б1'] = bool((status[StatusIndex.SOCKETS] >> 1) & 1) and bool((status[StatusIndex.SOCKETS] >> 4) & 1) + status_dic['ЭМС-Б2'] = bool((status[StatusIndex.SOCKETS] >> 2) & 1) and bool((status[StatusIndex.SOCKETS] >> 5) & 1) + status_dic['ИП220-27Б'] = bool((status[StatusIndex.IP_220_27B] >> 6) & 1) + return status_dic +#endregion diff --git a/scenes/pribor-uf/uf-ctl.gd.uid b/scenes/pribor-uf/uf-ctl.gd.uid new file mode 100644 index 00000000..20c27c67 --- /dev/null +++ b/scenes/pribor-uf/uf-ctl.gd.uid @@ -0,0 +1 @@ +uid://b6avo0uvwrxnj diff --git a/scenes/tabs-switch/lbl_ready.gd b/scenes/tabs-switch/lbl_ready.gd index 19ecc2ea..e924e135 100644 --- a/scenes/tabs-switch/lbl_ready.gd +++ b/scenes/tabs-switch/lbl_ready.gd @@ -1,6 +1,6 @@ extends Label -enum PRD_STATE { +enum DEVICE_STATE { NONE, # Нет связи GOOD, # Исправно ERR # Отказ @@ -13,9 +13,9 @@ enum DEVICE_STATUS { } const STATUS_CONFIG := { - PRD_STATE.NONE: {"text": "Нет связи", "color": Color.WHITE, "font_color": Color.BLACK}, - PRD_STATE.GOOD: {"text": "Исправно", "color": Color.GREEN, "font_color": Color.BLACK}, - PRD_STATE.ERR: {"text": "Отказ", "color": Color.RED, "font_color": Color.WHITE} + DEVICE_STATE.NONE: {"text": "Нет связи", "color": Color.WHITE, "font_color": Color.BLACK}, + DEVICE_STATE.GOOD: {"text": "Исправно", "color": Color.GREEN, "font_color": Color.BLACK}, + DEVICE_STATE.ERR: {"text": "Отказ", "color": Color.RED, "font_color": Color.WHITE} } class DeviceObserver: @@ -31,7 +31,6 @@ class DeviceObserver: func update_control_results(results: Dictionary) -> bool: var changed := false - last_results = results.duplicate() if results.get('is_over_control', false): # Контроль завершен - проверяем все результаты @@ -58,7 +57,8 @@ class DeviceObserver: return changed var device_observers: Dictionary = {} -var overall_prd_state: PRD_STATE = PRD_STATE.NONE +var overall_prd_state: DEVICE_STATE = DEVICE_STATE.NONE +var status_uf: int = DEVICE_STATE.NONE # Статус УФ (УАРЭП-ЭМС) func _ready() -> void: tooltip_text = 'Нет связи с приборами комплекса' @@ -77,9 +77,7 @@ func _ready() -> void: prd_module.unit_yau07.connect('line_changed', Callable(self, '_on_prd_online_changed').bind(prd_module)) # Подписка на УФ - var unit_uf = network.get_unit_instance('уарэп-эмс') - if unit_uf: - unit_uf.data_received.connect(Callable(self, '_on_uf_status_receive')) + signaller.connect('update_uf_serviceability', _on_uf_status_receive) # Инициализация начального состояния _recalculate_overall_state() @@ -111,41 +109,51 @@ func _on_prd_control_results(results: Dictionary, prd_module: Object) -> void: _recalculate_overall_state() -func _on_uf_status_receive(_unit_uf: Object) -> void: - # Логика для УФ (раскомментируй если нужно) - # var KEMS_B = ((unit_uf.status[0] >> 0) & 1) and ((unit_uf.status[0] >> 3) & 1) - # var EMS_B_1 = ((unit_uf.status[0] >> 1) & 1) and ((unit_uf.status[0] >> 4) & 1) - # var EMS_B_2 = ((unit_uf.status[0] >> 2) & 1) and ((unit_uf.status[0] >> 5) & 1) - # var IP27B = ((unit_uf.status[2] >> 6) & 1) - # var uf_operational = KEMS_B and EMS_B_1 and EMS_B_2 and IP27B - # signaller.emit_signal('update_uf_serviceability', uf_operational) - pass +func _on_uf_status_receive(unit_uf_status: int) -> void: + if status_uf != unit_uf_status: + status_uf = unit_uf_status + _recalculate_overall_state() func _recalculate_overall_state() -> void: - var new_state := PRD_STATE.NONE - var has_online_devices := false - var all_operational := true + var new_state := DEVICE_STATE.NONE + + # Проверяем статус ПРД + var prd_state := DEVICE_STATE.NONE + var has_online_prd := false + var all_prd_operational := true for observer in device_observers.values(): if observer.status[DEVICE_STATUS.ONLINE]: - has_online_devices = true + has_online_prd = true if observer.status[DEVICE_STATUS.CONTROL]: - # Если контроль завершен - строгая проверка if not observer.status[DEVICE_STATUS.STATUS]: - all_operational = false + all_prd_operational = false break else: - # Если контроль в процессе - мягкая проверка if not observer.status[DEVICE_STATUS.STATUS]: - all_operational = false - # Не прерываем, чтобы проверить все устройства + all_prd_operational = false - if has_online_devices: - new_state = PRD_STATE.GOOD if all_operational else PRD_STATE.ERR + if has_online_prd: + if all_prd_operational: + prd_state = DEVICE_STATE.GOOD + else: + prd_state = DEVICE_STATE.ERR else: - new_state = PRD_STATE.NONE + prd_state = DEVICE_STATE.NONE + + # Комбинируем статусы по правилу: + # 1. Если хоть один ERROR → ERROR + # 2. Если нет ERROR и хоть один GOOD → GOOD + # 3. Иначе → NONE + + if prd_state == DEVICE_STATE.ERR or status_uf == DEVICE_STATE.ERR: + new_state = DEVICE_STATE.ERR + elif prd_state == DEVICE_STATE.GOOD or status_uf == DEVICE_STATE.GOOD: + new_state = DEVICE_STATE.GOOD + else: + new_state = DEVICE_STATE.NONE if overall_prd_state != new_state: overall_prd_state = new_state @@ -153,8 +161,7 @@ func _recalculate_overall_state() -> void: func _update_display() -> void: - var config: Dictionary = STATUS_CONFIG[overall_prd_state].duplicate() - + var config: Dictionary text = config.text modulate = config.color add_theme_color_override("font_color", config.font_color) @@ -162,15 +169,83 @@ func _update_display() -> void: func _get_tooltip_text() -> String: + var tooltip := "" + + # Получаем статистику по ПРД + var prd_summary = _get_prd_summary() + var uf_status_str = _get_uf_status_text() + match overall_prd_state: - PRD_STATE.NONE: - return "Нет связи с приборами комплекса" - PRD_STATE.GOOD: - return "Все приборы комплекса исправны" - PRD_STATE.ERR: - return "Обнаружены неисправности в комплексе" + DEVICE_STATE.NONE: + tooltip = "Нет исправных систем в комплексе" + DEVICE_STATE.GOOD: + tooltip = "Комплекс исправен" + DEVICE_STATE.ERR: + tooltip = "Обнаружены неисправности в комплексе" + + tooltip += "\n\nСтатус ПРД систем: " + prd_summary + tooltip += "\nСтатус УФ: " + uf_status_str + + # Детализация по источникам статуса + tooltip += "\n\nСостояние систем:" + + # ПРД системы + var prd_ok_count = 0 + var prd_total = 0 + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE]: + prd_total += 1 + if observer.status[DEVICE_STATUS.STATUS]: + prd_ok_count += 1 + + tooltip += "\nПРД: %d/%d исправно" % [prd_ok_count, prd_total] + + # УФ система + tooltip += "\nУФ: " + _get_uf_status_text() + + return tooltip + + +func _get_prd_summary() -> String: + var online_count := 0 + var operational_count := 0 + + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE]: + online_count += 1 + if observer.status[DEVICE_STATUS.STATUS]: + operational_count += 1 + + if online_count == 0: + return "Нет связи" + else: + return "%d/%d исправно" % [operational_count, online_count] + + +func _get_uf_status_text() -> String: + match status_uf: + DEVICE_STATE.NONE: + return "Нет данных" + DEVICE_STATE.GOOD: + return "Исправен" + DEVICE_STATE.ERR: + return "Неисправен" _: - return "Неизвестное состояние" + return "Неизвестно" + + +func _has_prd_errors() -> bool: + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE] and not observer.status[DEVICE_STATUS.STATUS]: + return true + return false + + +func _has_operational_prd() -> bool: + for observer in device_observers.values(): + if observer.status[DEVICE_STATUS.ONLINE] and observer.status[DEVICE_STATUS.STATUS]: + return true + return false # Публичные методы для получения информации @@ -181,7 +256,8 @@ func get_device_status(device_name: String) -> Dictionary: "online": observer.status[DEVICE_STATUS.ONLINE], "operational": observer.status[DEVICE_STATUS.STATUS], "control_complete": observer.status[DEVICE_STATUS.CONTROL], - "last_results": observer.last_results.duplicate() + "last_results": observer.last_results, + "status_uf": status_uf } return {} @@ -204,5 +280,6 @@ func get_overall_status() -> Dictionary: "online_devices": online_count, "operational_devices": operational_count, "total_devices": device_observers.size(), - "control_complete_devices": control_complete_count + "control_complete_devices": control_complete_count, + "uf_status": status_uf } diff --git a/scenes/tabs-switch/tab-switch.tscn b/scenes/tabs-switch/tab-switch.tscn index 1c958ecf..618318ed 100644 --- a/scenes/tabs-switch/tab-switch.tscn +++ b/scenes/tabs-switch/tab-switch.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=20 format=3 uid="uid://3slb0i3pvowc"] +[gd_scene load_steps=19 format=3 uid="uid://3slb0i3pvowc"] [ext_resource type="Script" uid="uid://bvo6tcreqyuex" path="res://scenes/tabs-switch/tab-switch.gd" id="1_fg0vd"] [ext_resource type="PackedScene" uid="uid://b276iygic5itk" path="res://scenes/работа/работа.tscn" id="2_u7p16"] @@ -22,16 +22,13 @@ [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o1r22"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nmdfd"] -bg_color = Color(0.061, 100, 0.051, 1) - [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cw2ss"] -bg_color = Color(0.473976, 0.473976, 0.473976, 1) +bg_color = Color(0.47451, 0.47451, 0.47451, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nmdfd"] +bg_color = Color(0, 100, 0, 1) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_41d34"] -bg_color = Color(0.39, 100, 0.327, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_imu1q"] [node name="panel" type="Panel"] offset_right = 1600.0 @@ -102,10 +99,9 @@ focus_mode = 0 theme_override_colors/font_hover_pressed_color = Color(0, 0, 0, 1) theme_override_colors/font_color = Color(0, 0, 0, 1) theme_override_colors/font_pressed_color = Color(0, 0, 0, 1) -theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_nmdfd") theme_override_styles/hover = SubResource("StyleBoxFlat_cw2ss") -theme_override_styles/pressed = SubResource("StyleBoxFlat_41d34") -theme_override_styles/normal = SubResource("StyleBoxFlat_imu1q") +theme_override_styles/pressed = SubResource("StyleBoxFlat_nmdfd") +theme_override_styles/normal = SubResource("StyleBoxFlat_41d34") toggle_mode = true text = "Тренаж" script = ExtResource("9_41d34") diff --git a/scenes/tabs-switch/тренаж_режим.gd b/scenes/tabs-switch/тренаж_режим.gd index ab278048..cbcd599e 100644 --- a/scenes/tabs-switch/тренаж_режим.gd +++ b/scenes/tabs-switch/тренаж_режим.gd @@ -1,11 +1,11 @@ extends Button func _ready(): - connect("toggled", Callable(self, "_on_button_toggled")) + connect('toggled', Callable(self, '_on_button_toggled')) func _on_button_toggled(mode: bool): if mode: - tooltip_text = "Режим \"Тренаж\" задействован\nТекущее состояние: включено" + tooltip_text = 'Режим \"Тренаж\" задействован\nТекущее состояние: включено' else: - tooltip_text = "Задейстовать режим \"Тренаж\"\nТекущее состояние: отключено" + tooltip_text = 'Задейстовать режим \"Тренаж\"\nТекущее состояние: отключено' diff --git a/scenes/контроль/блок-в.tscn b/scenes/контроль/блок-в.tscn index 5275bec3..051eea41 100644 --- a/scenes/контроль/блок-в.tscn +++ b/scenes/контроль/блок-в.tscn @@ -35,7 +35,7 @@ signal pressed(control: PanelContainer) if not is_inside_tree(): 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 + $margin/vbox/grid1/level7.tint_progress = Color.RED if v >= 70 else Color.GOLD if v >= 55 else Color.WHITE on_level_changed(v, $margin/vbox/grid1/level7, value1_info) @@ -273,9 +273,9 @@ theme_override_styles/panel = SubResource("StyleBoxEmpty_3nd2u") script = SubResource("GDScript_oj3k3") textures = [ExtResource("1_n1aqt"), ExtResource("2_rim3u"), ExtResource("3_3w8fg")] value0 = [20.0, 30.0, 40.0, 50.0, 60.0, 70.0] -min_value1 = -40.0 +min_value1 = -60.0 max_value0 = 1400.0 -max_value1 = 55.0 +max_value1 = 75.0 step0 = 1.0 step1 = 1.0 value_name0 = "P,%" @@ -478,8 +478,8 @@ tooltip_text = " Текущее: 0.00 Диапазон: -40.00…55.00" mouse_filter = 0 -min_value = -40.0 -max_value = 55.0 +min_value = -60.0 +max_value = 75.0 fill_mode = 3 nine_patch_stretch = true stretch_margin_left = 8 diff --git a/scenes/контроль/блок-к.tscn b/scenes/контроль/блок-к.tscn index 6ffeb644..1bf682fc 100644 --- a/scenes/контроль/блок-к.tscn +++ b/scenes/контроль/блок-к.tscn @@ -35,7 +35,7 @@ signal pressed(control: PanelContainer) if not is_inside_tree(): 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 + $margin/vbox/grid1/level7.tint_progress = Color.RED if v >= 70 else Color.GOLD if v >= 55 else Color.WHITE on_level_changed(v, $margin/vbox/grid1/level7, value1_info) @@ -259,10 +259,10 @@ theme_override_styles/panel = SubResource("StyleBoxEmpty_3nd2u") script = SubResource("GDScript_oj3k3") textures = [ExtResource("1_uojqc"), ExtResource("2_a8ar3"), ExtResource("3_xwd13")] value0 = [20.0, 30.0, 40.0, 50.0, 60.0, 70.0] -value1 = -40.0 -min_value1 = -40.0 +value1 = -100.0 +min_value1 = -60.0 max_value0 = 1400.0 -max_value1 = 55.0 +max_value1 = 75.0 step0 = 1.0 step1 = 1.0 value_name0 = "P,%" @@ -365,12 +365,12 @@ layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 tooltip_text = " -Текущее: -40.00 -Диапазон: -40.00…55.00" +Текущее: -100.00 +Диапазон: -60.00…75.00" mouse_filter = 0 -min_value = -40.0 -max_value = 55.0 -value = -40.0 +min_value = -60.0 +max_value = 75.0 +value = -60.0 fill_mode = 3 nine_patch_stretch = true stretch_margin_left = 8 diff --git a/scenes/контроль/кнопка-прибора.gd b/scenes/контроль/кнопка-прибора.gd index 157514db..b7cbe142 100644 --- a/scenes/контроль/кнопка-прибора.gd +++ b/scenes/контроль/кнопка-прибора.gd @@ -8,12 +8,12 @@ extends TextureButton func _ready(): toggle_mode = true focus_mode = Control.FOCUS_ALL - connect("focus_entered", _on_focus_entered) - connect("focus_exited", _on_focus_exited) + connect('focus_entered', _on_focus_entered) + connect('focus_exited', _on_focus_exited) func _enter_tree() -> void: - if has_node("label"): + if is_inside_tree(): $label.self_modulate = state_colors[state] @@ -21,11 +21,11 @@ func update_progress_bar(target_value) -> void: if tween: tween.kill() tween = create_tween() - tween.tween_property($control_progress, "value", target_value, 0.3) + tween.tween_property($control_progress, 'value', target_value, 0.3) func _on_toggled(toggled_on): - if has_node("frame"): + if has_node('frame'): $frame.visible = toggled_on @@ -40,23 +40,30 @@ func _on_focus_exited(): func enter_press(): var enter_event = InputEventAction.new() - enter_event.action = "ui_accept" + enter_event.action = 'ui_accept' enter_event.pressed = true Input.parse_input_event(enter_event) +func _on_settings_changed(): + if not is_inside_tree(): return + var white_color = ProjectSettings.get_setting('Схема прибора. Белый цвет', Color.LIGHT_GRAY) + var black_color = ProjectSettings.get_setting('Схема прибора. Чёрный цвет', Color.BLACK) + $pic_functional.material.set('shader_parameter/white', white_color) + $pic_functional.material.set('shader_parameter/black', black_color) + + @export var state: int: set(v): v = 0 if v < 0 else v % state_colors.size() state = v - if is_inside_tree() and has_node("label"): + if is_inside_tree(): $label.self_modulate = state_colors[v] @export var progress_value: float = 0.0: set(v): progress_value = v - if is_inside_tree(): update_progress_bar(v) var max_val = $control_progress.get('max_value') diff --git a/scenes/контроль/контроль.tscn b/scenes/контроль/контроль.tscn index 3663cd08..5f2c8459 100644 --- a/scenes/контроль/контроль.tscn +++ b/scenes/контроль/контроль.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=30 format=3 uid="uid://lwmw4egynmd1"] +[gd_scene load_steps=33 format=3 uid="uid://lwmw4egynmd1"] [ext_resource type="Texture2D" uid="uid://bar8k5qef7kch" path="res://data/УФ.png" id="2_0nvm1"] [ext_resource type="Script" uid="uid://q3gmpsqspjfp" path="res://scenes/контроль/внешний.gd" id="2_8r80x"] @@ -54,6 +54,7 @@ const PRIBORS_RES = \\ 'pribor_uf': ['res://scenes/pribor-uf/pribor-uf.tscn', 'Контроль исправности прибора УФ'], 'pribor_uyep': ['res://scenes/pribor-uyep/pribor-uyep.tscn', 'Контроль исправности устройства У-ЭП'], } +var uf_control: UFControl var ctl_btn_state := false var cur_pribor_node = null var check_ready_control: Dictionary = {} @@ -67,8 +68,8 @@ func on_serv_changed(u, pribor_node, _pribor_meta): pribor_node.state = int(u.se func on_mode_changed(): clean_pribor_items() reset_pribor_buttons() - $chk_show_functional.disabled = true - $chk_show_functional.button_pressed = false + $frame_button/chk_show_functional.disabled = true + $frame_button/chk_show_functional.button_pressed = false func reset_pribor_buttons(): @@ -106,6 +107,7 @@ func _ready(): prd_module.unit_control.connect('update_max_value_progress', Callable(self, 'on_update_max_value_progress').bind(pribor_node)) prd_module.unit_control.connect('control_is_over', Callable(self, 'on_control_is_over')) if item == 'уарэп-эмс': + uf_control = UFControl.new('уарэп-эмс') signaller.connect('update_uf_serviceability', Callable(self, 'on_update_uf_serviceability').bind(pribor_node)) # Пиктограммы приборов, которые отображают состояние подключения только @@ -115,11 +117,12 @@ func _ready(): var conn_node: = pribor_node.get_node('connect_pribor') unit_instance.connect('line_changed', on_line_changed.bind(conn_node, unit_name)) + signaller.conn(signaller.режим_работа, on_mode_changed) signaller.conn(signaller.режим_журнал, on_mode_changed) signaller.conn(signaller.режим_настройки, on_mode_changed) signaller.conn(signaller.режим_эмс, on_mode_changed) - signaller.connect('debag_control_pressed', Callable(self, 'on_control_button_pressed')) + signaller.connect('debag_control_pressed', Callable(self, 'on_debag_button_pressed')) func online_change_arr(_u, conn_node, pribor_meta): @@ -142,8 +145,8 @@ func clean_pribor_items(): func on_pribor_press(pribor_path, header_text, pribor_node): if cur_pribor_node: cur_pribor_node.show_functional = false - $chk_show_functional.disabled = false - $chk_show_functional.button_pressed = false + $frame_button/chk_show_functional.disabled = false + $frame_button/chk_show_functional.button_pressed = false cur_pribor_node = pribor_node clean_pribor_items() var pribor_obj = load(pribor_path) @@ -155,7 +158,7 @@ func on_pribor_press(pribor_path, header_text, pribor_node): push_error('экземпляр не создан: \\\"%s\\\" (%s)' % [pribor_path, header_text]) return $lbl_header.text = header_text - $chk_show_functional.disabled = false + $frame_button/chk_show_functional.disabled = false var meta_list = pribor_node.get_meta_list() if meta_list.find('unit_name') > -1: var unit_name = pribor_node.get_meta('unit_name') @@ -170,8 +173,8 @@ func on_serviceability_changed(state: int, prd_pribor_node: Node)-> void: prd_pribor_node.state = state -func on_update_uf_serviceability(uf_serviceaability: bool, uf_pribor: Node)-> void: - uf_pribor.state = 1 if uf_serviceaability else 2 +func on_update_uf_serviceability(uf_serviceaability: int, uf_pribor: Node)-> void: + uf_pribor.state = uf_serviceaability func _on_chk_show_functional_toggled(toggled_on: bool) -> void: @@ -184,8 +187,36 @@ func _on_control_prd_pressed() -> void: for pribor in get_tree().get_nodes_in_group('pribor_buttons'): pribor.state = 0 # NONE signaller.emit_signal('start_contol_device') + # Показываем прогресс бар + $pribor_uf/control_progress.visible = true + $pribor_uf/control_progress.value = 0 + + # Создаем твин для анимации с плавным началом и концом + var tween = create_tween() + tween.tween_property($pribor_uf/control_progress, \"value\", 100, 2.0)\\ + .set_trans(Tween.TRANS_SINE)\\ + .set_ease(Tween.EASE_IN_OUT) + + tween.tween_callback(func(): + $pribor_uf/control_progress.visible = false + $pribor_uf.state = uf_control.serviceability_uf + ) +func on_debag_button_pressed(state: bool) -> void: + ctl_btn_state = state + update_pribor_items_visibility() + + +func update_pribor_items_visibility(): + var pribor_items = get_tree().get_nodes_in_group('pribor_items') + for pribor in pribor_items: + for child_name in ['input_0', 'output_0', 'input_1', 'output_1', 'input_2', 'output_2']: + if pribor.has_node(child_name): + pribor.get_node(child_name).visible = ctl_btn_state + + +#region Управление прогресс барами в контроле func on_update_progress(value_progress: float, pribor_node: Node) -> void: pribor_node.progress_value = value_progress pribor_node.progress_visible = value_progress > 0 @@ -193,6 +224,7 @@ func on_update_progress(value_progress: float, pribor_node: Node) -> void: func on_update_max_value_progress(max_value_progress: int, pribor_node: Node) -> void: pribor_node.progress_max_value = max_value_progress +#endregion func on_control_is_over(pribor_name: String) -> void: @@ -219,21 +251,8 @@ func _on_gui_input(event: InputEvent) -> void: node.button_pressed = false clean_pribor_items() cur_pribor_node = null - $chk_show_functional.button_pressed = false - $chk_show_functional.disabled = true - - -func on_control_button_pressed(state: bool) -> void: - ctl_btn_state = state - update_pribor_items_visibility() - - -func update_pribor_items_visibility(): - var pribor_items = get_tree().get_nodes_in_group('pribor_items') - for pribor in pribor_items: - for child_name in ['input_0', 'output_0', 'input_1', 'output_1', 'input_2', 'output_2']: - if pribor.has_node(child_name): - pribor.get_node(child_name).visible = ctl_btn_state + $frame_button/chk_show_functional.button_pressed = false + $frame_button/chk_show_functional.disabled = true " [sub_resource type="SpriteFrames" id="SpriteFrames_foasq"] @@ -252,10 +271,33 @@ animations = [{ [sub_resource type="ShaderMaterial" id="ShaderMaterial_71ec4"] shader = ExtResource("9_71ec4") -shader_parameter/white = Vector3(0.14, 0.13, 0.13) -shader_parameter/black = Vector3(0.95, 0.55, 0.05) +shader_parameter/white = Vector3(0, 0, 0) +shader_parameter/black = Vector3(1, 1, 1) shader_parameter/gamma = 2.0 +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_6hcgs"] +bg_color = Color(0.6, 0.6, 0.6, 0) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.6, 0.6, 0.6, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l5wui"] +bg_color = Color(0.47451, 0.47451, 0.47451, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.890196, 0.486275, 0.196078, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_j3xqy"] +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.890196, 0.486275, 0.196078, 1) + [node name="Контроль" type="Panel"] anchors_preset = 15 anchor_right = 1.0 @@ -265,7 +307,7 @@ grow_vertical = 2 script = SubResource("GDScript_iqgf5") metadata/_edit_lock_ = true metadata/_edit_vertical_guides_ = [21.0, 1578.0] -metadata/_edit_horizontal_guides_ = [200.0, 51.0] +metadata/_edit_horizontal_guides_ = [200.0, 51.0, 952.0, 1128.0] [node name="capsrpb" type="TextureRect" parent="." groups=["pribor_pics"]] editor_description = "Кнопка для отображения внешних соединений." @@ -456,7 +498,7 @@ texture_normal = ExtResource("6_i1yfn") stretch_mode = 4 flip_h = true script = ExtResource("3_4pt7j") -state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)] +state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(100, 0, 0, 1)] metadata/online_proc = "on_line_changed" metadata/unit_name = ["уарэп-яу07-1н"] @@ -547,7 +589,6 @@ metadata/unit_name = ["уарэп-эмс"] metadata/online_proc = "on_line_changed" [node name="label" type="Label" parent="pribor_uf"] -self_modulate = Color(0, 1, 0, 1) layout_mode = 0 offset_left = 15.0 offset_top = -44.0 @@ -592,6 +633,29 @@ offset_bottom = 311.0 scale = Vector2(0.789429, 0.789429) texture = ExtResource("11_gjf0t") +[node name="control_progress" type="TextureProgressBar" parent="pribor_uf"] +visible = false +layout_mode = 0 +offset_left = 9.0 +offset_top = 191.0 +offset_right = 102.0 +offset_bottom = 201.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +tooltip_text = " +Текущее: 0.00" +mouse_filter = 0 +max_value = 30.0 +nine_patch_stretch = true +stretch_margin_left = 5 +stretch_margin_top = 5 +stretch_margin_right = 5 +stretch_margin_bottom = 5 +texture_under = ExtResource("9_w6m6a") +texture_progress = ExtResource("10_lbx5w") +tint_under = Color(1, 1, 1, 0.419608) +tint_progress = Color(0.890196, 0.486275, 0.196078, 1) + [node name="pribor_rtr" type="TextureButton" parent="." groups=["pribor_buttons"]] editor_description = "Кнопка для выбора прибора." layout_mode = 0 @@ -1425,7 +1489,7 @@ texture_normal = ExtResource("6_i1yfn") stretch_mode = 4 flip_h = true script = ExtResource("3_4pt7j") -state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)] +state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(100, 0, 0, 1)] metadata/unit_name = ["уарэп-яу07-1в"] metadata/online_proc = "on_line_changed" @@ -1512,7 +1576,7 @@ texture_normal = ExtResource("6_i1yfn") stretch_mode = 4 flip_h = true script = ExtResource("3_4pt7j") -state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)] +state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(100, 0, 0, 1)] metadata/unit_name = ["уарэп-яу07-1к"] metadata/online_proc = "on_line_changed" @@ -1911,15 +1975,26 @@ text = "Контроль исправности прибора" horizontal_alignment = 1 vertical_alignment = 1 -[node name="chk_show_functional" type="CheckButton" parent="."] +[node name="frame_button" type="Panel" parent="."] layout_mode = 0 -offset_left = 1029.0 -offset_top = 15.0 -offset_right = 1408.0 -offset_bottom = 49.0 +offset_left = 1040.0 +offset_top = 16.0 +offset_right = 1416.0 +offset_bottom = 56.0 +theme_override_styles/panel = SubResource("StyleBoxFlat_6hcgs") + +[node name="chk_show_functional" type="CheckButton" parent="frame_button"] +layout_mode = 0 +offset_left = 2.0 +offset_top = 3.0 +offset_right = 374.0 +offset_bottom = 37.0 +focus_mode = 0 theme_override_font_sizes/font_size = 22 -text = "Показть функциональную схему Э2" +disabled = true +text = "Функциональная схема Э2" flat = true +alignment = 1 [node name="connect_legend0" type="AnimatedSprite2D" parent="."] light_mask = 3 @@ -1977,11 +2052,16 @@ default_color = Color(1, 1, 1, 0.352941) [node name="control_prd_button" type="Button" parent="."] layout_mode = 0 -offset_left = 1043.0 +offset_left = 1040.0 offset_top = 64.0 -offset_right = 1390.0 +offset_right = 1416.0 offset_bottom = 104.0 focus_mode = 0 +theme_override_colors/font_hover_color = Color(1, 1, 1, 1) +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_styles/hover = SubResource("StyleBoxFlat_l5wui") +theme_override_styles/pressed = SubResource("StyleBoxFlat_l5wui") +theme_override_styles/normal = SubResource("StyleBoxFlat_j3xqy") text = "Запуск контроля" script = ExtResource("18_lbx5w") metadata/_edit_lock_ = true @@ -2014,5 +2094,5 @@ texture = ExtResource("22_1s34a") [connection signal="toggled" from="pribor_prd_v_4" to="pribor_prd_v_4" method="_on_toggled"] [connection signal="toggled" from="pribor_prd_n_4" to="pribor_prd_n_4" method="_on_toggled"] [connection signal="toggled" from="pribor_prd_k_4" to="pribor_prd_k_4" method="_on_toggled"] -[connection signal="toggled" from="chk_show_functional" to="." method="_on_chk_show_functional_toggled"] +[connection signal="toggled" from="frame_button/chk_show_functional" to="." method="_on_chk_show_functional_toggled"] [connection signal="pressed" from="control_prd_button" to="." method="_on_control_prd_pressed"] diff --git a/scenes/контроль/элемент-я.gd b/scenes/контроль/элемент-я.gd index fd6a9442..bd73ac97 100644 --- a/scenes/контроль/элемент-я.gd +++ b/scenes/контроль/элемент-я.gd @@ -54,7 +54,7 @@ func _on_resized() -> void: func _enter_tree() -> void: if Engine.is_editor_hint(): return - var unit_any = network.get_unit_instance(unit_name) + var unit_any: = network.get_unit_instance(unit_name) unit_any.connect('data_received', Callable(self, 'on_data_received')) unit_any.connect('line_changed', Callable(self, 'on_line_changed')) $margin/vbox.alignment = alignment @@ -65,6 +65,6 @@ func _enter_tree() -> void: func _exit_tree() -> void: if Engine.is_editor_hint(): return - var unit_any = network.get_unit_instance(unit_name) + var unit_any: = network.get_unit_instance(unit_name) unit_any.disconnect('data_received', Callable(self, 'on_data_received')) unit_any.disconnect('line_changed', Callable(self, 'on_line_changed')) diff --git a/scenes/настройки/настройки.gd b/scenes/настройки/настройки.gd new file mode 100644 index 00000000..f01526bd --- /dev/null +++ b/scenes/настройки/настройки.gd @@ -0,0 +1,304 @@ +class_name configure extends Panel + +const TableHeader = preload('res://table/header.tscn') +const TableToggle = preload('res://table/settings-toggle.tscn') +const TableEdit = preload('res://table/ячейка-2.tscn') +const TableColorPick = preload('res://table/ячейка-цвет.tscn') + +const ALIGNMENT = [HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER] +const HEADER_ROW = [TableHeader, TableHeader] +const HEADER_ROW_TEXT = ['Параметр', 'Значение'] +const SETTING_TABLE = [ + ['Ограниченный режим', TableEdit, TableToggle, 'Ограничть возможности по постановке помех'], + ['Кнопка «ПД-М4»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ПД-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ОЗП-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «МЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ОРН-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ОРН-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ЛЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ПД-М4С»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ПД-ЧМ»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «СВ-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «К1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «СВ-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «ОРН»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «JTIDS»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Кнопка «КУПД»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Внешнее управление', TableEdit, TableToggle, 'Передать управление в 5П28'], + ['Внешнее указание Трасса', TableEdit, TableToggle, 'Разрешить постановку помех от Трасса'], + ['Кнопка «Подавление»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], + ['Виртуальная клавиатура', TableEdit, TableToggle, 'Включить отображение экранной клавиатуры'], + ['Скрыть вкладку ЭМС 2', TableEdit, TableToggle, 'Отображать вкладку \"ЭМС-2\"'], + ['Отладка контроля', TableEdit, TableToggle, 'Отображать отладку контроля'], + ['Текущая версия ПО УАРЭП', TableEdit, TableEdit, 'Время сборки, версия и номер фиксации'], + ['уарэп-яу07-частный', TableEdit, TableEdit, 'IP-адрес для получения частных сообщений от ЯУ-07'], + ['уарэп-яу07-общий', TableEdit, TableEdit, 'IP-адрес для получения широковещательных сообщений от ЯУ-07'], + ['уарэп-капсрпб', TableEdit, TableEdit, 'IP-адрес для связи с КАПС-РПБ [<адрес этого узла>, <адрес удалённого узла>, <порт этого узла>, <порт удалённого узла>]'], + ['уарэп-эмс', TableEdit, TableEdit, 'IP-адрес для связи с ЭМС'], + ['уарэп-яу07-2в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 2'], + ['уарэп-яу07-2н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 2'], + ['уарэп-яу07-2к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 2'], + ['уарэп-яу07-4в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 4'], + ['уарэп-яу07-4н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 4'], + ['уарэп-яу07-4к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 4'], + ['уарэп-яу07-1в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 1'], + ['уарэп-яу07-1н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 1'], + ['уарэп-яу07-1к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 1'], + ['уарэп-яу07-3в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 3'], + ['уарэп-яу07-3н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 3'], + ['уарэп-яу07-3к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 3'], + ['уарэп-5п28', TableEdit, TableEdit, 'IP-адрес для связи с 5П28'], + ['навигация', TableEdit, TableEdit, 'Порт назначения для получения данных от АКНГ'], + ['уарэп-щ3', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором Щ3'], + ['уарэп-спт25-1', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором СПТ-25 1'], + ['уарэп-спт25-2', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором СПТ-25 2'], + ['Шаблон адреса сервера карт', TableEdit, TableEdit, 'Шаблон URL-адреса сервера карт, должен содержать поля \"{x}\", \"{y}\", \"{z}\" для подстановки индекса плитки'], + ['Адрес АФСП левого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора АФСП'], + ['Адрес АФСП правого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора АФСП'], + ['Адрес БПО левого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора БПО'], + ['Адрес БПО правого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора БПО'], + ['Период опроса состояния БПО, секунды', TableEdit, TableEdit, 'Время в секундах' ], + ['Период опроса состояния АФСП, секунды', TableEdit, TableEdit, 'Время в секундах' ], + ['уарэп-трасса', TableEdit, TableEdit, 'IP-адрес для связи с Трассой [<адрес этого узла>, <адрес удалённого узла>, <порт этого узла>, <порт удалённого узла>]'], + ['Включить работу по своим целям', TableEdit, TableToggle, 'Разрешает работу в секторе со своей целью'], + ['Список своих протоколов', TableEdit, TableEdit, 'Список протоколов целей, по которым запрещено работать' ], + ['Цвет кнопки \"Подавление\"', TableEdit, TableColorPick, 'Цвет кнопки. Введено по требованию ПЗ' ] ] + +## TODO: Придумать как избавиться от индексов +## Индексы строк таблицы. +const EXTERNAL_CU = 16 ## Внешнее целеуказание +const TRASSA = 17 ## Строка - Трасса +const SUPPRESS = 18 ## Строка - Подавление +const KEYBOARD = 19 ## Строка - Виртуальная клавиатура +const HIDE_EMS2 = 20 ## Строка - Скрыть вкладку ЭМС 2 +const DEBAG_CONTROL = 21 ## Строка - Отладка контроля +const COMMIT = 22 ## Строка - Версия УАРЭП +const GOS_BTN = 52 ## Разрешить работу по своим целям +const COLOR_BTN_ACT = 54 ## Цвет кнопки "Подавление" + + +var name_to_line_index: = {} ## Для преобразования названия параметра в номер строки +var table_color_instance: Node ## Нода цвета кнопки подавления + +func on_checkbutton_pressed(i_row: int): on_row_pressed(i_row) + + +## Вызывается, когда узел впервые попадает в дерево сцены. +func _ready() -> void: + setting_tab() + if not OS.get_cmdline_args().has('++ограниченный'): + return + $Label2.text = 'Текущий режим доступа: ограниченный' + for node in $GridContainer.get_children().filter(func(b): return b is Button): + node.disabled = true + + +func on_external_cu_btn_pressed(btn) -> void: + ProjectSettings.set_setting('application/config/Внешнее управление', btn.button_pressed) + if btn.button_pressed: + signaller.emit_signal('interfer_off_all') + + +func on_trassa_btn_pressed(btn) -> void: + ProjectSettings.set_setting('application/config/Внешнее указание Трасса', btn.button_pressed) + + +func on_vk_pressed(btn) -> void: + signaller.emit_signal('kb_pressed', btn.button_pressed) + + +func on_gos_pressed(btn) -> void: + ProjectSettings.set_setting('application/config/Включить работу по своим целям', btn.button_pressed) + + +func on_ems2_pressed(btn) -> void: + var state = btn.button_pressed + signaller.emit_signal('ems2_hide_pressed', state) + + +func on_debag_control_pressed(btn) -> void: + var state = btn.button_pressed + signaller.emit_signal("debag_control_pressed", state) + + +func on_row_pressed(i_row: int): + $scroll_set/table.clear_rows_selected() + $scroll_set/table.set_row_selected(i_row, true) + + +func parse_cmd_line_args(settings_data: Dictionary): + var args = OS.get_cmdline_args() + for i in range(0, args.size(), 2): + var key: String = args[i] + key = key.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes() + if not settings_data.has(key): + continue + if not ((i + 1) < args.size()): + push_error('для аргумента \"%s\" не указано значение.' % key) + break + var val0 = args[i + 1] + var val1 = settings_data[key] + val0 = val0.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes() + if typeof(val1) == TYPE_BOOL: + if val0 not in ['yes', 'true', 'да', 'no', 'false', 'нет']: + push_error('для аргумента \"%s\" указано неверное значение \"%s\".' % [key, val0]) + break + settings_data[key] = true if val0 in ['yes', 'true', 'да'] else false + elif typeof(val1) == TYPE_ARRAY: + var val0s = val0.split(',') + if val0s.size() != val1.size(): + push_error('для аргумента \"%s\" указано неверное значение \"%s\" (исходное: \"%s\").' % [key, val0, val1]) + break + for j in val0s.size(): + var val: String = val0s[j] + val = val.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes() + if tools.type_is_num(val): + val0s[j] = int(val) + elif val in ['true', 'false']: + val0s[j] = true if val == 'true' else false + else: + val0s[j] = val + elif typeof(val1) == TYPE_STRING: + settings_data[key] = val0 + + +func setting_tab(): + $heard_table.set_header(HEADER_ROW) + $heard_table.set_header_text(HEADER_ROW_TEXT) + $heard_table.set_columns_min_size([600, 950]) + $heard_table.set_columns_alignments(ALIGNMENT) + var settings_data = {} + parse_cmd_line_args(settings_data) + for key in settings_data: + ProjectSettings.set_setting('application/config/%s' % key, settings_data[key]) + for i in SETTING_TABLE.size(): + var tbl_row = SETTING_TABLE[i] + var param_name = tbl_row[0] + var node_label = tbl_row[1] + var node_value = tbl_row[2] + var tootip_text = tbl_row[3] + name_to_line_index[param_name] = i + $scroll_set/table.add_row([node_label, node_value]) + var label_instance = $scroll_set/table.get_node2(0, i) + label_instance.text = param_name + label_instance.tooltip_text = tootip_text + $scroll_set/table.set_node_editable(0, i, false) + var node_values = $scroll_set/table.get_node2(1, i).get_children() + var edit_node = $scroll_set/table.get_node2(1, i) + if node_values.size(): + var child = node_values[0] + if child is CheckButton: + child.connect('pressed', Callable(self, 'on_checkbutton_pressed').bind(i)) + var val = ProjectSettings.get_setting('application/config/%s' % param_name, true) + child.set_pressed(val) + else: + if settings_data.has(param_name): + var val = settings_data[param_name] + if typeof(val) == TYPE_STRING: + $scroll_set/table.get_node2(1, i).text = settings_data[param_name] + if edit_node: + if edit_node is LineEdit: + $scroll_set/table.set_node_control(1, i, true) + $scroll_set/table.set_node_editable(1, COMMIT, false) + $scroll_set/table.set_columns_min_size([600, 950]) + $scroll_set/table.set_columns_alignments(ALIGNMENT) + $scroll_set/table.connect('row_pressed', Callable(self, 'on_row_pressed')) + var commit_instance = $scroll_set/table.get_node2(1, COMMIT) + commit_instance.text = '%s' % commit.VCS_HEAD + for i in SETTING_TABLE.size(): + var param_name = SETTING_TABLE[i][0] + var profile = $scroll_set/table.get_node2(1, i) + if settings.UnitProfiles.has(param_name): + var unit_data = settings.UnitProfiles[param_name][1] + profile.text = '' + for val in unit_data: + profile.text += str(val) + ',' + profile.text = profile.text.trim_suffix(',') + continue + var psk = 'application/config/%s' % param_name + if ProjectSettings.has_setting(psk): + var unit_data = ProjectSettings.get_setting(psk) + if is_instance_of(unit_data, TYPE_STRING): + profile.text = unit_data + button_settings() + + +func button_settings(): + var extern_cu_node = $scroll_set/table.get_node2(1, EXTERNAL_CU).get_children()[0] + extern_cu_node.connect('pressed', on_external_cu_btn_pressed.bind(extern_cu_node)) + on_external_cu_btn_pressed(extern_cu_node) + var trassa_node = $scroll_set/table.get_node2(1, TRASSA).get_children() + trassa_node = trassa_node[0] + trassa_node.connect('pressed', on_trassa_btn_pressed.bind(trassa_node)) + var vk_node = $scroll_set/table.get_node2(1, KEYBOARD).get_children()[0] + vk_node.connect('pressed', on_vk_pressed.bind(vk_node)) + var ems2_hide_node = $scroll_set/table.get_node2(1, HIDE_EMS2).get_children()[0] + ems2_hide_node.connect('pressed', on_ems2_pressed.bind(ems2_hide_node)) + ems2_hide_node.set_pressed(true) + on_ems2_pressed(ems2_hide_node) + var gos_node = $scroll_set/table.get_node2(1, GOS_BTN).get_children()[0] + gos_node.connect('pressed', on_gos_pressed.bind(gos_node)) + var debag_control = $scroll_set/table.get_node2(1, DEBAG_CONTROL).get_children()[0] + debag_control.connect('pressed', on_debag_control_pressed.bind(debag_control)) + debag_control.set_pressed(false) + on_debag_control_pressed(debag_control) + var color_btn_act = $scroll_set/table.get_node2(1, COLOR_BTN_ACT) + color_btn_act.connect('popup_closed', on_color_closed.bind(color_btn_act)) + var json_col = ProjectSettings.get_setting('application/config/%s' % 'Цвет кнопки \"Подавление\"', '[1.0, 1.0, 1.0, 1.0]') + var arr_col = JSON.parse_string(json_col) + color_btn_act.color = Color(arr_col[0], arr_col[1], arr_col[2], arr_col[3]) if arr_col else Color.WHITE + color_btn_act.text = JSON.stringify(arr_col) + + +func on_color_closed(color_btn_act: ColorPickerButton): + var col = [color_btn_act.color.r, color_btn_act.color.g, color_btn_act.color.b, color_btn_act.color.a] + color_btn_act.text = JSON.stringify(col) + ProjectSettings.set_setting('application/config/%s' % 'Цвет кнопки \"Подавление\"', color_btn_act.text) + + +func _on_btn_save_settings_pressed(): + var json_data = {} + for i in SETTING_TABLE.size(): + var parameter = SETTING_TABLE[i][0] + if parameter in settings.UnitProfiles: + var ref_profile = settings.UnitProfiles[parameter][1] + var profiles = $scroll_set/table.get_node2(1, i) + var value = profiles.get_text() + if parameter not in json_data: + var row: = [] + for token in value.split(','): + var j: = row.size() + if token.is_valid_int(): + token = int(token) + elif token == 'false': + token = false + elif token == 'true': + token = true + if typeof(ref_profile[j]) == typeof(token): + row.append(token) + else: + # TODO: Это надо вывести на экран пользователю + push_error([parameter, j, type_string(typeof(ref_profile[j])), type_string(typeof(token))]) + row.append(ref_profile[j]) + json_data[parameter] = row + else: + var children = $scroll_set/table.get_node2(1, i).get_children() + if len(children): + var child = children[0] + json_data[parameter] = child.is_pressed() + else: + var row = $scroll_set/table.get_row(i) + json_data[parameter] = row[1].text + for key in json_data: + ProjectSettings.set_setting('application/config/%s' % key, json_data[key]) + var settings_file: = settings.get_settings_file_path() + var file: = FileAccess.open(settings_file, FileAccess.WRITE) + var abs_path: = ProjectSettings.globalize_path(settings_file) + if not file: + log.error('Не удалось открыть файл для записи \"%s\"' % abs_path) + return + var json_string: = JSON.stringify(json_data, ' ', true) + if file.store_string(json_string): + log.info('Настройки сохранены в файл \"%s\"' % abs_path) + file.close() diff --git a/scenes/настройки/настройки.gd.uid b/scenes/настройки/настройки.gd.uid new file mode 100644 index 00000000..88fb51c0 --- /dev/null +++ b/scenes/настройки/настройки.gd.uid @@ -0,0 +1 @@ +uid://dabpum5iqxc7y diff --git a/scenes/настройки/настройки.tscn b/scenes/настройки/настройки.tscn index d115368b..950d3e74 100644 --- a/scenes/настройки/настройки.tscn +++ b/scenes/настройки/настройки.tscn @@ -1,296 +1,9 @@ [gd_scene load_steps=7 format=3 uid="uid://bnptm4rlp60dq"] +[ext_resource type="Script" uid="uid://dabpum5iqxc7y" path="res://scenes/настройки/настройки.gd" id="1_60bya"] [ext_resource type="Script" uid="uid://c5pq0hbrij34d" path="res://table/table.gd" id="2_6sx73"] [ext_resource type="Texture2D" uid="uid://csnts8f155sf7" path="res://data/save1.png" id="3_dbpks"] -[sub_resource type="GDScript" id="GDScript_fc87o"] -script/source = "class_name configure extends Panel - -const TableHeader = preload('res://table/header.tscn') -const TableToggle = preload('res://table/settings-toggle.tscn') -const TableEdit = preload('res://table/ячейка-2.tscn') - -const ALIGNMENT = [HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER] -const HEADER_ROW = [TableHeader, TableHeader] -const HEADER_ROW_TEXT = ['Параметр', 'Значение'] -const SETTING_TABLE = [ - ['Ограниченный режим', TableEdit, TableToggle, 'Ограничть возможности по постановке помех'], - ['Кнопка «ПД-М4»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «ПД-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «ОЗП-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «МЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «ОРН-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «ОРН-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «ЛЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «ПД-М4С»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «ПД-ЧМ»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «СВ-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «К1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «СВ-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «ОРН»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «JTIDS»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Кнопка «КУПД»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Внешнее управление', TableEdit, TableToggle, 'Передать управление в 5П28'], - ['Внешнее указание Трасса', TableEdit, TableToggle, 'Разрешить постановку помех от Трасса'], - ['Кнопка «Подавление»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], - ['Виртуальная клавиатура', TableEdit, TableToggle, 'Включить отображение экранной клавиатуры'], - ['Скрыть вкладку ЭМС 2', TableEdit, TableToggle, 'Отображать вкладку \\\"ЭМС-2\\\"'], - ['Отладка контроля', TableEdit, TableToggle, 'Отображать отладку контроля'], - ['Текущая версия ПО УАРЭП', TableEdit, TableEdit, 'Время сборки, версия и номер фиксации'], - ['уарэп-яу07-частный', TableEdit, TableEdit, 'IP-адрес для получения частных сообщений от ЯУ-07'], - ['уарэп-яу07-общий', TableEdit, TableEdit, 'IP-адрес для получения широковещательных сообщений от ЯУ-07'], - ['уарэп-капсрпб', TableEdit, TableEdit, 'IP-адрес для связи с КАПС-РПБ [<адрес этого узла>, <адрес удалённого узла>, <порт этого узла>, <порт удалённого узла>]'], - ['уарэп-эмс', TableEdit, TableEdit, 'IP-адрес для связи с ЭМС'], - ['уарэп-яу07-2в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 2'], - ['уарэп-яу07-2н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 2'], - ['уарэп-яу07-2к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 2'], - ['уарэп-яу07-4в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 4'], - ['уарэп-яу07-4н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 4'], - ['уарэп-яу07-4к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 4'], - ['уарэп-яу07-1в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 1'], - ['уарэп-яу07-1н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 1'], - ['уарэп-яу07-1к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 1'], - ['уарэп-яу07-3в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 3'], - ['уарэп-яу07-3н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 3'], - ['уарэп-яу07-3к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 3'], - ['уарэп-5п28', TableEdit, TableEdit, 'IP-адрес для связи с 5П28'], - ['навигация', TableEdit, TableEdit, 'Порт назначения для получения данных от АКНГ'], - ['уарэп-щ3', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором Щ3'], - ['уарэп-спт25-1', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором СПТ-25 1'], - ['уарэп-спт25-2', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором СПТ-25 2'], - ['Шаблон адреса сервера карт', TableEdit, TableEdit, 'Шаблон URL-адреса сервера карт, должен содержать поля \\\"{x}\\\", \\\"{y}\\\", \\\"{z}\\\" для подстановки индекса плитки'], - ['Адрес АФСП левого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора АФСП'], - ['Адрес АФСП правого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора АФСП'], - ['Адрес БПО левого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора БПО'], - ['Адрес БПО правого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора БПО'], - ['Период опроса состояния БПО, секунды', TableEdit, TableEdit, 'Время в секундах' ], - ['Период опроса состояния АФСП, секунды', TableEdit, TableEdit, 'Время в секундах' ], - ['уарэп-трасса', TableEdit, TableEdit, 'IP-адрес для связи с Трассой [<адрес этого узла>, <адрес удалённого узла>, <порт этого узла>, <порт удалённого узла>]'], - ['Включить работу по своим целям', TableEdit, TableToggle, 'Разрешает работу в секторе со своей целью'], - ['Список своих протоколов', TableEdit, TableEdit, 'Список протоколов целей, по которым запрещено работать' ], ] - -const EXTERNAL_CU = 16 ## Внешнее целеуказание -const TRASSA = 17 -const SUPPRESS = 18 ## Строка - Подавление -const KEYBOARD = 19 ## Строка - Виртуальная клавиатура -const HIDE_EMS2 = 20 ## Строка - Скрыть вкладку ЭМС 2 -const DEBAG_CONTROL = 21## Строка - Отладка контроля -const COMMIT = 22 ## Строка - Версия УАРЭП -const GOS_BTN = 52 ## Разрешить работу по своим целям - -var name_to_line_index: = {} ## Для преобразования названия параметра в номер строки - -func on_checkbutton_pressed(i_row: int): on_row_pressed(i_row) - - -## Вызывается, когда узел впервые попадает в дерево сцены. -func _ready() -> void: - setting_tab() - if not OS.get_cmdline_args().has('++ограниченный'): - return - $Label2.text = 'Текущий режим доступа: ограниченный' - for node in $GridContainer.get_children().filter(func(b): return b is Button): - node.disabled = true - - -func on_external_cu_btn_pressed(btn) -> void: - ProjectSettings.set_setting('application/config/Внешнее управление', btn.button_pressed) - if btn.button_pressed: - signaller.emit_signal('interfer_off_all') - - -func on_trassa_btn_pressed(btn) -> void: - ProjectSettings.set_setting('application/config/Внешнее указание Трасса', btn.button_pressed) - - -func on_vk_pressed(btn) -> void: - signaller.emit_signal('kb_pressed', btn.button_pressed) - - -func on_gos_pressed(btn) -> void: - ProjectSettings.set_setting('application/config/Включить работу по своим целям', btn.button_pressed) - - -func on_ems2_pressed(btn) -> void: - var state = btn.button_pressed - signaller.emit_signal('ems2_hide_pressed', state) - - -func on_debag_control_pressed(btn) -> void: - var state = btn.button_pressed - signaller.emit_signal(\"debag_control_pressed\", state) - - -func on_row_pressed(i_row: int): - $scroll_set/table.clear_rows_selected() - $scroll_set/table.set_row_selected(i_row, true) - - -func parse_cmd_line_args(settings_data: Dictionary): - var args = OS.get_cmdline_args() - for i in range(0, args.size(), 2): - var key: String = args[i] - key = key.lstrip('\\'\\\" ').rstrip('\\'\\\" ').strip_edges().strip_escapes() - if not settings_data.has(key): - continue - if not ((i + 1) < args.size()): - push_error('для аргумента \\\"%s\\\" не указано значение.' % key) - break - var val0 = args[i + 1] - var val1 = settings_data[key] - val0 = val0.lstrip('\\'\\\" ').rstrip('\\'\\\" ').strip_edges().strip_escapes() - if typeof(val1) == TYPE_BOOL: - if val0 not in ['yes', 'true', 'да', 'no', 'false', 'нет']: - push_error('для аргумента \\\"%s\\\" указано неверное значение \\\"%s\\\".' % [key, val0]) - break - settings_data[key] = true if val0 in ['yes', 'true', 'да'] else false - elif typeof(val1) == TYPE_ARRAY: - var val0s = val0.split(',') - if val0s.size() != val1.size(): - push_error('для аргумента \\\"%s\\\" указано неверное значение \\\"%s\\\" (исходное: \\\"%s\\\").' % [key, val0, val1]) - break - for j in val0s.size(): - var val: String = val0s[j] - val = val.lstrip('\\'\\\" ').rstrip('\\'\\\" ').strip_edges().strip_escapes() - if tools.type_is_num(val): - val0s[j] = int(val) - elif val in ['true', 'false']: - val0s[j] = true if val == 'true' else false - else: - val0s[j] = val - elif typeof(val1) == TYPE_STRING: - settings_data[key] = val0 - - -func setting_tab(): - $heard_table.set_header(HEADER_ROW) - $heard_table.set_header_text(HEADER_ROW_TEXT) - $heard_table.set_columns_min_size([600, 950]) - $heard_table.set_columns_alignments(ALIGNMENT) - var settings_data = {} - parse_cmd_line_args(settings_data) - for key in settings_data: - ProjectSettings.set_setting('application/config/%s' % key, settings_data[key]) - for i in SETTING_TABLE.size(): - var tbl_row = SETTING_TABLE[i] - var param_name = tbl_row[0] - var node_label = tbl_row[1] - var node_value = tbl_row[2] - var tootip_text = tbl_row[3] - name_to_line_index[param_name] = i - $scroll_set/table.add_row([node_label, node_value]) - var label_instance = $scroll_set/table.get_node2(0, i) - label_instance.text = param_name - label_instance.tooltip_text = tootip_text - $scroll_set/table.set_node_editable(0, i, false) - var node_values = $scroll_set/table.get_node2(1, i).get_children() - var edit_node = $scroll_set/table.get_node2(1, i) - if node_values.size(): - var child = node_values[0] - if child is CheckButton: - child.connect('pressed', Callable(self, 'on_checkbutton_pressed').bind(i)) - var val = ProjectSettings.get_setting('application/config/%s' % param_name, true) - child.set_pressed(val) - else: - if settings_data.has(param_name): - var val = settings_data[param_name] - if typeof(val) == TYPE_STRING: - $scroll_set/table.get_node2(1, i).text = settings_data[param_name] - if edit_node: - if edit_node is LineEdit: - $scroll_set/table.set_node_control(1, i, true) - $scroll_set/table.set_node_editable(1, COMMIT, false) - $scroll_set/table.set_columns_min_size([600, 950]) - $scroll_set/table.set_columns_alignments(ALIGNMENT) - $scroll_set/table.connect('row_pressed', Callable(self, 'on_row_pressed')) - var commit_instance = $scroll_set/table.get_node2(1, COMMIT) - commit_instance.text = '%s' % commit.VCS_HEAD - for i in SETTING_TABLE.size(): - var param_name = SETTING_TABLE[i][0] - var profile = $scroll_set/table.get_node2(1, i) - if settings.UnitProfiles.has(param_name): - var unit_data = settings.UnitProfiles[param_name][1] - profile.text = '' - for val in unit_data: - profile.text += str(val) + ',' - profile.text = profile.text.trim_suffix(',') - continue - var psk = 'application/config/%s' % param_name - if ProjectSettings.has_setting(psk): - var unit_data = ProjectSettings.get_setting(psk) - if is_instance_of(unit_data, TYPE_STRING): - profile.text = unit_data - button_settings() - - -func button_settings(): - var extern_cu_node = $scroll_set/table.get_node2(1, EXTERNAL_CU).get_children()[0] - extern_cu_node.connect('pressed', on_external_cu_btn_pressed.bind(extern_cu_node)) - on_external_cu_btn_pressed(extern_cu_node) - var trassa_node = $scroll_set/table.get_node2(1, TRASSA).get_children() - trassa_node = trassa_node[0] - trassa_node.connect('pressed', on_trassa_btn_pressed.bind(trassa_node)) - var vk_node = $scroll_set/table.get_node2(1, KEYBOARD).get_children()[0] - vk_node.connect('pressed', on_vk_pressed.bind(vk_node)) - var ems2_hide_node = $scroll_set/table.get_node2(1, HIDE_EMS2).get_children()[0] - ems2_hide_node.connect('pressed', on_ems2_pressed.bind(ems2_hide_node)) - ems2_hide_node.set_pressed(true) - on_ems2_pressed(ems2_hide_node) - var gos_node = $scroll_set/table.get_node2(1, GOS_BTN).get_children()[0] - gos_node.connect('pressed', on_gos_pressed.bind(gos_node)) - var debag_control = $scroll_set/table.get_node2(1, DEBAG_CONTROL).get_children()[0] - debag_control.connect('pressed', on_debag_control_pressed.bind(debag_control)) - debag_control.set_pressed(false) - on_debag_control_pressed(debag_control) - - -func _on_btn_save_settings_pressed(): - var json_data = {} - for i in SETTING_TABLE.size(): - var parameter = SETTING_TABLE[i][0] - if parameter in settings.UnitProfiles: - var ref_profile = settings.UnitProfiles[parameter][1] - var profiles = $scroll_set/table.get_node2(1, i) - var value = profiles.get_text() - if parameter not in json_data: - var row: = [] - for token in value.split(','): - var j: = row.size() - if token.is_valid_int(): - token = int(token) - elif token == 'false': - token = false - elif token == 'true': - token = true - if typeof(ref_profile[j]) == typeof(token): - row.append(token) - else: - # TODO: Это надо вывести на экран пользователю - push_error([parameter, j, type_string(typeof(ref_profile[j])), type_string(typeof(token))]) - row.append(ref_profile[j]) - json_data[parameter] = row - else: - var children = $scroll_set/table.get_node2(1, i).get_children() - if len(children): - var child = children[0] - json_data[parameter] = child.is_pressed() - else: - var row = $scroll_set/table.get_row(i) - json_data[parameter] = row[1].text - for key in json_data: - ProjectSettings.set_setting('application/config/%s' % key, json_data[key]) - var settings_file: = settings.get_settings_file_path() - var file: = FileAccess.open(settings_file, FileAccess.WRITE) - var abs_path: = ProjectSettings.globalize_path(settings_file) - if not file: - log.error('Не удалось открыть файл для записи \\\"%s\\\"' % abs_path) - return - var json_string: = JSON.stringify(json_data, ' ', true) - if file.store_string(json_string): - log.info('Настройки сохранены в файл \\\"%s\\\"' % abs_path) - file.close() -" - [sub_resource type="StyleBoxTexture" id="StyleBoxTexture_pyq6h"] texture = ExtResource("3_dbpks") modulate_color = Color(0.8, 0.533333, 0.27451, 1) @@ -305,7 +18,7 @@ modulate_color = Color(0.8, 0.533333, 0.27451, 1) texture = ExtResource("3_dbpks") [node name="Настройки" type="Panel"] -script = SubResource("GDScript_fc87o") +script = ExtResource("1_60bya") [node name="heard_table" type="GridContainer" parent="."] layout_mode = 0 diff --git a/scenes/работа/работа.gd b/scenes/работа/работа.gd index c2fe4edc..195378f2 100644 --- a/scenes/работа/работа.gd +++ b/scenes/работа/работа.gd @@ -38,6 +38,7 @@ var color_select: Color var color_emit: Color var color_emit_sel: Color var color_closed: Color +var col_btn_act: Color = Color.WHITE var color_closed_emit: Color var signal_conections: Array @@ -149,6 +150,9 @@ func on_settings_changed(): color_closed *= Color(1.0, 1.0, 1.0, 0.0) color_closed_emit *= Color(1.0, 1.0, 1.0, 1.0) + var json_col = ProjectSettings.get_setting('application/config/%s' % 'Цвет кнопки \"Подавление\"', '[1.0, 1.0, 1.0, 1.0]') + var arr_col = JSON.parse_string(json_col) + col_btn_act = Color(arr_col[0], arr_col[1], arr_col[2], arr_col[3]) if arr_col else Color.WHITE ## Обработчик сигнала изменения списка целей. @@ -190,7 +194,7 @@ func init_fs_failed(): var sectors_count = $canvas.fs_default_colors.size() fs_failed.resize(sectors_count) for i in fs_failed.size(): - fs_failed[i] = AntBandState.ANT_BAND_READY + fs_failed[i] = AntBandState.ANT_BAND_FAILED ## Производит инициализацию. @@ -300,7 +304,10 @@ func map_threat_to_bip(th: threats.Threat, bip: Control) -> bool: func on_threat_update(th: threats.Threat): var bip = get_node('%d' % th.id) bip.update(th.tick_rx) - bip.set_bip_color(Color.CORAL if th.proto else Color.WHITE) + if th.gos: + bip.set_bip_color(Color.GREEN) + else: + bip.set_bip_color(Color.CORAL if th.proto else Color.WHITE) bip.visible = map_threat_to_bip(th, bip) @@ -552,7 +559,7 @@ func set_fs_color(ecms): func update_fs_colors(): - var fs_colors = $canvas.fs_default_colors.duplicate() + var fs_colors = $canvas.fs_default_colors for key in fs_active.keys(): fs_colors[key] = color_ecm for key in fs_emit.keys(): @@ -571,7 +578,7 @@ func update_fs_colors(): $canvas.set_band_failures(fs_failed) if fs_emit.size(): if $btn_activate.pressed: - $btn_activate.self_modulate = Color.RED + $btn_activate.self_modulate = col_btn_act else: $btn_activate.self_modulate = Color.WHITE else: @@ -627,7 +634,7 @@ func on_interfer_prinuditelno(prenuditelno_sectors): ## Вызывается при получении информации о состоянии модулей ФС от КАПС РПБ. func on_fs_update_state(fs_dict: Dictionary): for key in fs_dict.keys(): - fs_failed[key] = fs_dict[key].isg + fs_failed[key] = fs_dict[key].ready func on_btn_center_toggled(toggled_on: bool) -> void: diff --git a/scenes/работа/работа.tscn b/scenes/работа/работа.tscn index 807aa342..c08c2b77 100644 --- a/scenes/работа/работа.tscn +++ b/scenes/работа/работа.tscn @@ -380,7 +380,6 @@ texture_normal = ExtResource("14_ggrwd") [connection signal="drag_continue" from="." to="." method="_on_drag_continue"] [connection signal="toggled" from="btn_view" to="." method="on_button_view_toggled"] [connection signal="toggled" from="chk_auto" to="." method="on_value_changed"] -[connection signal="toggled" from="btn_activate" to="." method="on_btn_activate"] [connection signal="toggled" from="btn_activate" to="." method="on_btn_activate_toggled"] [connection signal="toggled" from="btn_center" to="." method="on_btn_center_toggled"] [connection signal="button_down" from="zoom_plus" to="tilemap" method="_on_zoom_plus_button_down"] diff --git a/scenes/эмс/yems-boards.gd b/scenes/эмс/yems-boards.gd index eac8030a..42e41dd8 100644 --- a/scenes/эмс/yems-boards.gd +++ b/scenes/эмс/yems-boards.gd @@ -54,9 +54,6 @@ class EmsBoard: ## Устанавливает состояние входов и выходов платы func set_status(status: PackedByteArray): - if not status.size(): - push_error('status.size():%d' % status.size()) - return var offset = 0 if id_board < 3: offset = yemsconsts.STATUS_OFFSET[id_board] @@ -310,10 +307,12 @@ class EmsBoard: return true func set_load_done(): + if unit_ems.cmd_state != unit_ems.CmdState.DONE: return state_board = LOADING unit_ems.send_load_ems_done(unit_ems.CmdCode.LOAD_EMS_DONE) func execute_cmd(): + if unit_ems.cmd_state != unit_ems.CmdState.DONE: return if len(cmd_array): state_board = WRITE var cmd: Array = cmd_array.pop_front() diff --git a/scenes/эмс2/эмс_тг.gd b/scenes/эмс2/эмс-тг.gd similarity index 100% rename from scenes/эмс2/эмс_тг.gd rename to scenes/эмс2/эмс-тг.gd diff --git a/scenes/эмс2/эмс_тг.gd.uid b/scenes/эмс2/эмс-тг.gd.uid similarity index 100% rename from scenes/эмс2/эмс_тг.gd.uid rename to scenes/эмс2/эмс-тг.gd.uid diff --git a/scenes/эмс2/эмс-тг.tscn b/scenes/эмс2/эмс-тг.tscn index 4a39180c..a5c5f5f0 100644 --- a/scenes/эмс2/эмс-тг.tscn +++ b/scenes/эмс2/эмс-тг.tscn @@ -6,15 +6,13 @@ [ext_resource type="Texture2D" uid="uid://cckk3jk5r32bh" path="res://data/ГО.png" id="5_qxr47"] [ext_resource type="Texture2D" uid="uid://kyrnn1mqpc08" path="res://data/РЛС1.png" id="6_8sxps"] [ext_resource type="Texture2D" uid="uid://cx0f3wcx76u1k" path="res://data/РЛС2.png" id="7_0bfmy"] +[ext_resource type="Texture2D" uid="uid://csxruavk0s40l" path="res://data/Окно частот0.png" id="8_4em3i"] [ext_resource type="Texture2D" uid="uid://duu8q7sv0jwfh" path="res://data/ННВС.png" id="8_aiy4x"] [sub_resource type="CompressedTexture2D" id="CompressedTexture2D_5u4bk"] -load_path = "res://.godot/imported/Окно частот0.png-6b01791c971bddb01337caf9077bf060.ctex" [sub_resource type="CompressedTexture2D" id="CompressedTexture2D_pd85g"] -[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_4em3i"] - [node name="Control" type="Panel"] [node name="Sprite2D" type="Sprite2D" parent="."] @@ -94,6 +92,5 @@ scale = Vector2(0.911215, 0.911215) texture = SubResource("CompressedTexture2D_pd85g") [node name="ТаблицаЧастот" type="Sprite2D" parent="."] -position = Vector2(808.166, 537.125) -scale = Vector2(0.956689, 0.95669) -texture = SubResource("CompressedTexture2D_4em3i") +position = Vector2(794, 569) +texture = ExtResource("8_4em3i") diff --git a/scenes/эмс2/эмс2.tscn b/scenes/эмс2/эмс2.tscn index 09fb4311..fd4280ec 100644 --- a/scenes/эмс2/эмс2.tscn +++ b/scenes/эмс2/эмс2.tscn @@ -1,8 +1,7 @@ -[gd_scene load_steps=35 format=3 uid="uid://musb21x2u0xs"] +[gd_scene load_steps=36 format=3 uid="uid://musb21x2u0xs"] [ext_resource type="Texture2D" uid="uid://hkcvl2waf63s" path="res://data/вид сверху.png" id="1_b7vcf"] -[ext_resource type="Script" uid="uid://bvlqgv7aapebl" path="res://scenes/эмс2/эмс_тг.gd" id="1_l3ueu"] -[ext_resource type="Texture2D" uid="uid://b1dw06ahtftq2" path="res://data/Окно частот0.png" id="3_2spgl"] +[ext_resource type="Script" uid="uid://bvlqgv7aapebl" path="res://scenes/эмс2/эмс-тг.gd" id="1_l3ueu"] [ext_resource type="Texture2D" uid="uid://0w6q4vfst0ry" path="res://data/OP-63.png" id="3_8gk36"] [ext_resource type="Texture2D" uid="uid://coxhivvc6uibs" path="res://data/Состояние РЭС 40.png" id="4_b3mus"] [ext_resource type="Texture2D" uid="uid://073el51yholj" path="res://data/454.png" id="4_nqi0i"] @@ -24,9 +23,9 @@ [ext_resource type="Texture2D" uid="uid://b1kuhj03yigih" path="res://data/Квадрат салатный 454.png" id="23_h11e0"] [ext_resource type="Texture2D" uid="uid://d3v1r4r62na8" path="res://data/Квадрат салатный ОР-63.png" id="24_2pcsf"] [ext_resource type="Texture2D" uid="uid://ddm55bo28sxcs" path="res://data/Квадрат салатный РЛС1.png" id="25_wmu4u"] +[ext_resource type="Texture2D" uid="uid://fuhhvsa5um4m" path="res://data/Скруглённый квадрат серый.png" id="26_2spgl"] [ext_resource type="Texture2D" uid="uid://dneqjcul4ipub" path="res://data/Квадрат салатный РЛС2.png" id="26_w5eif"] [ext_resource type="Texture2D" uid="uid://cyb60nh23ys6k" path="res://data/Квадрат салатный ГО.png" id="27_2ft3r"] -[ext_resource type="Texture2D" uid="uid://bymxiptkbufvs" path="res://data/Скруглённый квадрат серый.png" id="27_b5v2s"] [ext_resource type="Texture2D" uid="uid://cw8sd7v5f31ww" path="res://data/Квадрат салатный с трубкой.png" id="28_rra4y"] [ext_resource type="Texture2D" uid="uid://busl8rb38lis" path="res://data/Скруглённый прямоуг салатный.png" id="29_5u4bk"] [ext_resource type="Texture2D" uid="uid://xux3mch12733" path="res://data/Приём.png" id="30_l3ueu"] @@ -34,6 +33,9 @@ [ext_resource type="Texture2D" uid="uid://7ody4v7qy36g" path="res://data/Скруглённый прямоугольник серый.png" id="31_b5v2s"] [ext_resource type="Texture2D" uid="uid://carr8bw5rwiwj" path="res://data/Кнопка подтверждения01.png" id="32_p41nv"] [ext_resource type="Texture2D" uid="uid://3siondd3feev" path="res://data/Скруглённый прямоугольник белый.png" id="33_5ifkb"] +[ext_resource type="Texture2D" uid="uid://csxruavk0s40l" path="res://data/Окно частот0.png" id="34_b5v2s"] + +[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_5u4bk"] [node name="Panel" type="Panel"] script = ExtResource("1_l3ueu") @@ -52,7 +54,7 @@ offset_top = 240.0 offset_right = 1649.0 offset_bottom = 813.0 scale = Vector2(0.95, 0.95) -texture = ExtResource("3_2spgl") +texture = SubResource("CompressedTexture2D_5u4bk") expand_mode = 1 [node name="Op-63" type="TextureRect" parent="."] @@ -258,7 +260,7 @@ texture = ExtResource("28_rra4y") [node name="СкруглённыйКвадрат" type="Sprite2D" parent="."] position = Vector2(1299, 873) -texture = ExtResource("27_b5v2s") +texture = ExtResource("26_2spgl") [node name="СкруглённыйКвадратБелый" type="Sprite2D" parent="СкруглённыйКвадрат"] position = Vector2(0, 49) @@ -382,43 +384,23 @@ texture = ExtResource("15_2spgl") [node name="СкруглённыйКвадратСерый2" type="Sprite2D" parent="СкруглённыйКвадрат"] position = Vector2(49, 49) -texture = ExtResource("27_b5v2s") +texture = ExtResource("26_2spgl") [node name="СкруглённыйКвадратСерый3" type="Sprite2D" parent="СкруглённыйКвадрат"] position = Vector2(98, 98) -texture = ExtResource("27_b5v2s") +texture = ExtResource("26_2spgl") [node name="СкруглённыйКвадратСерый4" type="Sprite2D" parent="СкруглённыйКвадрат"] position = Vector2(147, 147) -texture = ExtResource("27_b5v2s") +texture = ExtResource("26_2spgl") [node name="СкруглённыйКвадратСерый5" type="Sprite2D" parent="СкруглённыйКвадрат"] position = Vector2(245, 245) -texture = ExtResource("27_b5v2s") +texture = ExtResource("26_2spgl") [node name="СкруглённыйКвадратСерый6" type="Sprite2D" parent="СкруглённыйКвадрат"] position = Vector2(196, 196) -texture = ExtResource("27_b5v2s") - -[node name="Label" type="Label" parent="."] -layout_mode = 0 -offset_left = 800.0 -offset_top = 246.0 -offset_right = 873.0 -offset_bottom = 265.0 -theme_override_colors/font_color = Color(0, 0, 0, 1) -theme_override_font_sizes/font_size = 16 -text = "Излучение" - -[node name="Label2" type="Label" parent="."] -layout_mode = 0 -offset_left = 813.0 -offset_top = 503.0 -offset_right = 861.0 -offset_bottom = 522.0 -theme_override_colors/font_color = Color(0, 0, 0, 1) -theme_override_font_sizes/font_size = 16 -text = "Приём" +texture = ExtResource("26_2spgl") [node name="СкруглённыйПрямоугСалатный" type="Sprite2D" parent="."] position = Vector2(84, 828) @@ -481,11 +463,15 @@ text = "Изделие" [node name="Label" type="Label" parent="СкруглённыйПрямоугСалатный"] offset_left = -33.0 -offset_top = -10.2857 +offset_top = -17.1429 offset_right = 35.0 -offset_bottom = 8.71429 +offset_bottom = 13.8571 theme_override_colors/font_color = Color(0, 0, 0, 1) -text = "Комплекс" +theme_override_font_sizes/font_size = 12 +text = "Источник +информации" +horizontal_alignment = 1 +vertical_alignment = 3 [node name="Label3" type="Label" parent="СкруглённыйПрямоугСалатный"] offset_left = 133.0 @@ -515,19 +501,20 @@ horizontal_alignment = 1 [node name="Label6" type="Label" parent="СкруглённыйПрямоугСалатный"] offset_left = 516.75 -offset_top = -10.2857 +offset_top = -18.8572 offset_right = 574.75 -offset_bottom = 8.7143 +offset_bottom = 22.1428 theme_override_colors/font_color = Color(0, 0, 0, 1) -text = "Верхняя" +text = "Верхняя частота" [node name="Label7" type="Label" parent="СкруглённыйПрямоугСалатный"] offset_left = 441.0 -offset_top = -10.2857 +offset_top = -19.7143 offset_right = 495.0 -offset_bottom = 8.7143 +offset_bottom = 21.2857 theme_override_colors/font_color = Color(0, 0, 0, 1) -text = "Нижняя" +text = "Нижняя частота" +horizontal_alignment = 1 [node name="Label8" type="Label" parent="СкруглённыйПрямоугСалатный"] offset_left = 362.25 @@ -1188,3 +1175,26 @@ offset_bottom = 9.0 theme_override_colors/font_color = Color(0, 0, 0, 1) text = "--" horizontal_alignment = 1 + +[node name="ТаблицаЧастот" type="Sprite2D" parent="."] +position = Vector2(800, 502.25) +scale = Vector2(0.987573, 0.885314) +texture = ExtResource("34_b5v2s") + +[node name="Label" type="Label" parent="ТаблицаЧастот"] +offset_left = -6.0755 +offset_top = -293.757 +offset_right = 66.9245 +offset_bottom = -274.757 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 16 +text = "Излучение" + +[node name="Label2" type="Label" parent="ТаблицаЧастот"] +offset_left = 8.10067 +offset_top = -7.05967 +offset_right = 65.1007 +offset_bottom = 11.9403 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 16 +text = "Приём" diff --git a/scripts/interfer.gd b/scripts/interfer.gd index 4dcc22dc..256571b8 100644 --- a/scripts/interfer.gd +++ b/scripts/interfer.gd @@ -111,6 +111,12 @@ var gos_nmfs: Array ## Список номеров var fs_closed: Dictionary ## Словарь секторов запрета +## Режимы работы АФСП и БПО (Протокол ТНИИС-СТЦ, пункт 2.5.10) +enum AFSP_BPO_MODE { + run = 1, + test = 2 } + + ## Сеанс помехи. class Interfer: var ispp: int = 0 ## Индекс сеанса. @@ -127,6 +133,7 @@ class Interfer: var um: float ## Угол места для помехи. var nmfs: int = 0 ## Номер модуля ФС в нумерации СТЦ var priority: int = 0 ## Приоритет помехи + static var afsp_bpo_mode: = AFSP_BPO_MODE.run ## Режим работы АФСП и БПО func _to_string() -> String: return 'номер: %d название: %s частота: %0.1f МГц пеленг: %0.1f гр.' % [ispp, ITERFER_MODE[krp][0], params['freq'], kni] @@ -138,6 +145,7 @@ class Interfer: data_to_json['ispp'] = ispp data_to_json['krp'] = ITERFER_MODE[krp][0] data_to_json['nmfs'] = nmfs + data_to_json['sa'] = afsp_bpo_mode if krp != INTERFER_OFF: data_to_json['kni'] = kni data_to_json['powp'] = powp @@ -211,6 +219,8 @@ func _ready() -> void: signaller.connect('interfer_prinuditelno', Callable(self, 'on_interfer_prinuditelno')) signaller.connect('emit_changed', Callable(self, 'on_emit_changed').bind(ecms)) signaller.connect('режим_тренаж', on_trenazh_mode) + signaller.connect('режим_контроль', on_kontrol_mode) + signaller.connect('режим_работа', on_rabota_mode) signaller.connect('update_fs_closed', Callable(self, 'on_update_fs_closed')) threats.connect('threat_lost', Callable(self, 'on_threats_lost').bind(ecms, unit_caps)) threats.connect('threats_resized', Callable(self, 'on_threats_resized')) @@ -222,6 +232,8 @@ func _ready() -> void: func on_trenazh_mode(val: bool): trenazh_mode = val +func on_kontrol_mode(): Interfer.afsp_bpo_mode = AFSP_BPO_MODE.test +func on_rabota_mode(): Interfer.afsp_bpo_mode = AFSP_BPO_MODE.run func on_nav_data_received(coords: Dictionary, unit_caps): @@ -261,7 +273,7 @@ func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit_instance) -> v gos_nmfs.clear() for thr in threats.values(): var fs_arr: Array = [] - var th_aoa = fposmod(thr.aoa - course, 360) + var th_aoa: = fposmod(thr.aoa - course, 360) prd.find_fs_index(th_aoa, thr.freq, fs_arr) if fs_arr.size(): for item in fs_arr: @@ -277,10 +289,10 @@ func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit_instance) -> v var ecm_active = true if not gos_flag: if ecm.nmfs in gos_nmfs: - interfer_off(ecm, unit_instance) + signaller.emit_signal('interfer_off', ecm) ecm_active = false if ecm_active and (prd.fs_caps_id[ecm.nmfs] in fs_closed): - interfer_off(ecm, unit_instance) + signaller.emit_signal('interfer_off', ecm) var th_id = thr.id for ecm_i in thrs.keys(): @@ -290,9 +302,9 @@ func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit_instance) -> v ecm.kni = fposmod(thr.aoa - course, 360) call_ecm_proc(ecm) if ecm.nmfs in gos_nmfs: - interfer_off(ecm, unit_instance) + signaller.emit_signal('interfer_off', ecm) elif prd.fs_caps_id[ecm.nmfs] in fs_closed: - interfer_off(ecm, unit_instance) + signaller.emit_signal('interfer_off', ecm) else: send_ecm(ecm, unit_instance) signaller.emit_signal('fs_update_color', ecms) @@ -382,7 +394,7 @@ func on_interfer_create(interfer_name, sel_threats, fs_arr, power, u, ecms) -> v for ecm in ecms.values(): if ecm.nmfs == item.nmfs: if item.priority > ecm.priority: - interfer_off(ecm, u) + signaller.emit_signal('interfer_off', ecm) elif item.priority < ecm.priority: need_continue = true break @@ -496,7 +508,6 @@ func interfer_create(u, interfer_name, ecms, param, kni, id, dict, source_interf func send_ecm(ecm, unit0) -> void: if ecm.krp != INTERFER_OFF: if not ecm.modulation: - ecm.svk = 0 call_deferred('emit_signal', 'interfer_update', ecm) return msg6_num += 1 @@ -504,17 +515,17 @@ func send_ecm(ecm, unit0) -> void: unit0.tx_stack.append(json_data) -func on_interfer_off_all(unit0, ecms: Dictionary) -> void: +func on_interfer_off_all(_unit0, ecms: Dictionary) -> void: for ecm in ecms.values(): - interfer_off(ecm, unit0) + signaller.emit_signal('interfer_off', ecm) -func on_threats_lost(th, ecms, unit0) -> void: +func on_threats_lost(th, ecms, _unit0) -> void: for key in interfer.thrs: if interfer.thrs[key] == th.id: var ecm_id = key var ecm = ecms[ecm_id] - interfer_off(ecm, unit0) + signaller.emit_signal('interfer_off', ecm) func pop_id() -> int: @@ -641,19 +652,36 @@ func get_krp(threat: threats.Threat): for key in ITERFER_MODE.keys(): var ecm_params = ITERFER_MODE[key][1] if not ecm_params.has('files'): continue - if ecm_params['files'] == threat.rparams['filename']: - krp = key - return krp + if typeof(ecm_params['files']) == TYPE_DICTIONARY: + for value in ecm_params['files'].values(): + if typeof(value) == TYPE_STRING: + if value == threat.rparams['filename']: + krp = key + return krp + elif typeof(value) == TYPE_ARRAY: + if value[0] == threat.rparams['filename']: + krp = key + return krp + elif typeof(ecm_params['files']) == TYPE_STRING: + if ecm_params['files'] == threat.rparams['filename']: + krp = key + return krp return krp -func on_interfer_off(ecm: Interfer, _ecms, unit_caps): +func on_interfer_off(ecm: Interfer, ecms, unit_caps): ecm.krp = INTERFER_OFF send_ecm(ecm, unit_caps) - - -func interfer_off(ecm, _unit_caps): - signaller.emit_signal('interfer_off', ecm) + if not unit_caps.online: + var sz = ecms.size() + signaller.emit_signal('on_prog_ecm_off', ecm) + ecms.erase(ecm.ispp) + thrs.erase(ecm.ispp) + cu.erase(ecm.ispp) + fs.erase(ecm.ispp) + push_id(ecm.ispp) + if sz != ecms.size(): + interfer.call_deferred('emit_signal', 'interfer_resized', ecms) func on_interfer_new(ecm, unit_caps): diff --git a/scripts/prd.gd b/scripts/prd.gd index 33f804f8..8a56a356 100644 --- a/scripts/prd.gd +++ b/scripts/prd.gd @@ -2,6 +2,8 @@ extends Node enum PrdState {WORK, CONTROL} +const TIME_YAU07_SEND = 50 + ## Границы секторов блоков ФС по частоте в режиме РТО. const FS_BAND_RTO: Dictionary = { 0: [200.0, 250.0], @@ -119,6 +121,9 @@ class Fs: var freq_caps_rx: float = 0.0 ## Частота принятая от КАПС РПБ var width_caps_rx: float = 0.0 ## Ширина полосы принятая от КАПС РПБ var msvk: Array + var ready: bool = false ## Готовность сектора к излучению + var caps_online: bool = false ## Состояние связи с КАПС РПБ + var yau_07_online: bool = false ## Состояние связи ЯУ-07 signal update_modulation(index) @@ -149,6 +154,9 @@ class Fs: data_arr.append(um_port) data_arr.append(val) + # Установка готовности модуля ФС к излучению + func set_ready(): + ready = isg and caps_online and yau_07_online class PRD: enum STATE_DEVICE { @@ -208,7 +216,6 @@ class PRD: if port == fs.um_port: fs.um_code_rx = u.isa_ports[port] & 0x7 - func on_line_changed(unit_ems): if not unit_ems.online: yemsg_board.ems_load = yemsg_board.LoadState.NOT_DEFINED @@ -303,7 +310,6 @@ class PRD: break return STATE_DEVICE.NONE if all_online else STATE_DEVICE.ERROR - func execute_cmd(): if not len(cmd_array): return if unit_yau07.cmd_state != unit_yau07.CmdState.DONE: return @@ -338,14 +344,16 @@ class PRD: yemsg_board.set_wait() log.error('Не удалось прочитать файл настроек ячейки ЭМС-Г %s' %abs_dir) - func on_update_modulation(index): yemsg_board.add_cmd(index/4, fs_dic[index].modulation) func set_um(data_arr): cmd_array.append([unit_yau07.CmdCode.WRITE_ISA, data_arr]) - + func set_fs_caps_online(caps_online: bool): + for fs in fs_dic.values(): + fs.caps_online = caps_online + fs.set_ready() func _ready() -> void: check_dir() @@ -353,6 +361,7 @@ func _ready() -> void: var unit_prd = network.get_unit_instance(prd_name) var new_prd = PRD.new(prd_name, unit_prd) prd_dict[prd_name] = new_prd + new_prd.unit_yau07.connect('line_changed', on_yau07_line_changed.bind(new_prd)) var unit_control = TestPRD.new({'unit_prd': unit_prd}, new_prd.cmd_array) add_child(unit_control) new_prd.unit_control = unit_control @@ -367,6 +376,7 @@ func _ready() -> void: fs_caps_id[FS_PRD[key][1]] = key var unit_caps = network.get_unit_instance('уарэп-капсрпб') unit_caps.connect('data_received', Callable(self, 'on_data_capsrpb_received')) + unit_caps.connect('line_changed', Callable(self, 'on_caps_line_changed')) signaller.connect('режим_контроль', Callable(self, 'on_mode_changed').bind(PrdState.CONTROL)) signaller.connect('режим_работа', Callable(self, 'on_mode_changed').bind(PrdState.WORK)) var unit_nav = network.get_unit_instance('навигация') @@ -433,7 +443,6 @@ func update_fs_state(ecms, trenaz_mode: bool): prd_module.set_um(um_data_array) - ## Проверяет ниличие директории, если их нет, создаёт func check_dir(): var dir = DirAccess.open(yemsconsts.emsg_files_folder) @@ -461,6 +470,7 @@ func on_data_capsrpb_received(unit0: capsrpb.CapsRpb): var fs_module = fs_dict[ii] if fs.has('isg'): fs_module.isg = int(fs['isg']) + fs_module.set_ready() if fs.has('pow'): fs_module.pow_caps_rx = int(fs['pow']) if fs.has('freq'): @@ -479,3 +489,16 @@ func on_mode_changed(changed_mode: int) -> void: func on_navi_data_received(data: Dictionary): course = data.get('k', 0.0) + + +func on_caps_line_changed(unit_caps): + for pribor_prd in prd_dict.values(): + pribor_prd.set_fs_caps_online(unit_caps.online) + signaller.emit_signal('fs_update_state', fs_dict) + + +func on_yau07_line_changed(unit_yau07, prd_pribor): + for fs in prd_pribor.fs_dic.values(): + fs.yau_07_online = unit_yau07.online + fs.set_ready() + signaller.emit_signal('fs_update_state', fs_dict) diff --git a/scripts/pribor-prd.gd b/scripts/pribor-prd.gd index e6385964..1097ddde 100644 --- a/scripts/pribor-prd.gd +++ b/scripts/pribor-prd.gd @@ -14,7 +14,7 @@ const PROGRESS_RAY_STATES: float = 50.0 const PROGRESS_COMPLETE: float = 100.0 ## Константы для работы с лучами управления -const COUNT_PACK_POWER_RECIEVE = 15 +const COUNT_PACK_POWER_RECIEVE = 10 const RAY_MASK = 0x07 const SPECIAL_LITERAS = [3, 5, 7] const RAY_m5: String = 'RAY_m5' @@ -160,7 +160,7 @@ var current_status: String = 'Ожидание запуска контроля' ## Сигналы класса signal control_is_over(device_name: String) # Когда контроль завершен signal status_updated(status_text: String) # Сигнал для обновления статуса -signal control_results_updated(control_results: Dictionary) # Обновление результатов контроля +signal control_results_updated(control_results: Dictionary) # Обновление результатов контроля signal update_progress(progress_value: float) # Обновление статуса выполнения контроля signal update_max_value_progress(max_progress_value: int) # Установка максимального значения для прогресс бара @@ -289,6 +289,8 @@ func _process(_delta: float) -> void: ## Обработка данных от ЯУ-07 func on_data_received(unit_pribor: Object) -> void: var status: PackedByteArray = unit_pribor.status + if status.size() < 100: push_error('Принимаемые значения от ЯУ-07б:%s не коррентны. (размер пакета: %d)' % [self_name, status.size()]); return + temperature_um = check_temperature_um(status) flags.temperature_ok = check_overheating(temperature_um) block_ip_config = check_block_ip(status, block_ip_config) @@ -390,7 +392,6 @@ func _handle_init_state() -> void: if _get_current_ecm(): return state = STATE_MACHINE.CHEK_KASSETA_Y5 else: - if _get_current_ecm(): return # Завершение контроля если литеры закончились flags.control_is_over = true power_result = prep_power(power_for_litera, self_name) @@ -996,18 +997,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, cur_litera: int) -> bool: var result_1: int - var result_2: int if cur_litera == 1: result_1 = ((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_1]]) prd_cmd_array.append([prd_unit.CmdCode.WRITE_ISA, [settings_ug.ADDR_UG_LITERA_3, settings_ug.ATT_UM_3]]) else: - #if cur_litera in [2, 4, 6]: - result_1 = ((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_1]]) - #elif cur_litera in [3, 5, 7]: - 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_2, result_2]]) + if cur_litera in [2, 4, 6]: + result_1 = ((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_1]]) + elif cur_litera in [3, 5, 7]: + result_1 = ((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_1]]) return true @@ -1140,7 +1140,7 @@ static func _create_fs_mapping(s_name: String) -> Dictionary: ## Получение статуса ФС static func on_fs_state(packet_type_7: Dictionary, fs_mapping: Dictionary, fs_results: Dictionary, fs_rules_config: Array) -> Dictionary: - var updated_results := fs_results.duplicate() + var updated_results := fs_results for fs_num in packet_type_7: if not (fs_num in fs_mapping and fs_mapping[fs_num]['condition']): continue @@ -1209,19 +1209,19 @@ static func power_um_ukp(status: PackedByteArray, litera: int, pwr_result: Array static func update_max_power_values(power_data: Array, max_power_values: Array) -> Array: if power_data.size() != 6: if max_power_values.is_empty(): - max_power_values = power_data.duplicate() + max_power_values = power_data elif power_data[0] > max_power_values[0]: - max_power_values = power_data.duplicate() + max_power_values = power_data return max_power_values if max_power_values.is_empty(): - max_power_values = power_data.duplicate() + max_power_values = power_data else: for i in 6: if power_data[i] > max_power_values[i]: max_power_values[i] = power_data[i] - return max_power_values.duplicate() + return max_power_values ## Подготовка принятых данных по контролю для передачи в сцену @@ -1322,7 +1322,7 @@ func _deep_copy_power_structure() -> Dictionary: for litera in power_for_litera: copy[litera] = {} for ray_type in power_for_litera[litera]: - copy[litera][ray_type] = power_for_litera[litera][ray_type].duplicate() + copy[litera][ray_type] = power_for_litera[litera][ray_type] return copy ## Восстановление состояний по умолчанию diff --git a/scripts/signaller.gd b/scripts/signaller.gd index 434df1ea..c2271316 100644 --- a/scripts/signaller.gd +++ b/scripts/signaller.gd @@ -204,7 +204,7 @@ signal update_coordinates_map(new_coordinates) ## Вызывается при изменении исправности прибора УФ.[br] ## [param uf_serviceaability] - обновленное значение состояния исправности ([b]true[/b] -signal update_uf_serviceability(uf_serviceaability: bool) +signal update_uf_serviceability(uf_serviceaability: int) signal tool_tip(new_ctrl_pos) diff --git a/scripts/threats.gd b/scripts/threats.gd index 1070cd29..407ef74b 100644 --- a/scripts/threats.gd +++ b/scripts/threats.gd @@ -2,6 +2,8 @@ extends Node ## Работа с целями. +var gos_flag = true ## Флаг работать по своим целям +var gos_protocols: PackedStringArray ## Список протоколов своих целей ## Цель class Threat: @@ -15,7 +17,7 @@ class Threat: var id: int ## Идентификатор цели. var lat: float ## Текущие координаты, широта в градусах. var lon: float ## Текущие координаты, долгота в градусах. - var power: float ## Уровень принимаемого сигнала, дБм. + var pow: float ## Уровень принимаемого сигнала, дБм. var proto: String ## Тип протокола источника сигнала. var rkrp: String ## Рекомендуемый режим помехи. var rparams: Dictionary ## Рекомендуемые параметры помехи. @@ -31,6 +33,7 @@ class Threat: var emit_state: int = 0 ## 0 - подавление не назначено, 1 - назначено, 2 - выполняется var nmfs: int ## Индекс модуля ФС, в зону действия которого попала цель var priority: int ## Приоритет опасности цели + var gos: bool = false ## Своя или чужая цель func _init(): clear_fflags() func _to_string() -> String: return 'номер: %d пеленг: %0.1f частота: %0.1f МГц' % [id, aoa, freq] @@ -69,6 +72,8 @@ func _ready() -> void: signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(threats)) signaller.connect('interfer_init', Callable(self, 'on_interfer_init').bind(threats)) + ProjectSettings.connect('settings_changed', on_settings_changed.bind(threats)) + ## Периодически удаляет устаревшие цели. func on_timer_check_lost(time_lost: int, threats: Dictionary): @@ -147,12 +152,31 @@ func on_data_capsrpb_received(unit: capsrpb.CapsRpb, threats: Dictionary): th.priority = 1 else: th.priority = 0 + set_gos(th) call_deferred('emit_signal', 'threat_update', th) + else: var th: = Threat.new() th.set_from_dic(dic_th) threats[id] = th th.tick_rx = unit.tick + set_gos(th) call_deferred('emit_signal', 'threat_new', th) if sz != threats.size(): call_deferred('emit_signal', 'threats_resized', threats) + + +func on_settings_changed(ths): + gos_flag = ProjectSettings.get_setting('application/config/Включить работу по своим целям', true) + var protocols: String = ProjectSettings.get_setting('application/config/Список своих протоколов', '') + gos_protocols = protocols.split(",", true) + for th in ths.values(): + set_gos(th) + + + +func set_gos(th: Threat): + if gos_flag: + th.gos = false + elif (th.proto in gos_protocols) and th.fflags.proto: + th.gos = true diff --git a/scripts/unit.gd b/scripts/unit.gd index db8e8b33..bffe7961 100644 --- a/scripts/unit.gd +++ b/scripts/unit.gd @@ -9,7 +9,7 @@ class Unit extends Object: SEND, ## Буфер готов для отправки. WAIT, ## Ожидание выполнения. DONE, ## Команда выполнена. - FAIL, ## Команда не выполнена. + FAIL ## Команда не выполнена. } signal line_changed(unit) ## Вызывается при изменении состояния связи @@ -18,7 +18,7 @@ class Unit extends Object: signal parse_failed(unit) ## Вызывается при обнаружении ошибки во входных данных signal data_received(data) ## Вызывается по приёму данных - var cmd_state = CmdState.UNCK ## Состояние выполнения команды + var cmd_state: = CmdState.UNCK ## Состояние выполнения команды var tx_data: = PackedByteArray() ## Буфер для отправки. var tx_len: int = 0 ## Длина последнего отправленного пакета. var tx_tick: int = 0 ## Тик-время отправки буфера diff --git a/scripts/yau07.gd b/scripts/yau07.gd index 54e02478..328c4563 100644 --- a/scripts/yau07.gd +++ b/scripts/yau07.gd @@ -72,6 +72,8 @@ class YaU07 extends unit.Unit: rc = Error.OK cmd_tick_tx = tick cmd_retry -= 1 + cmd_num_tx = (cmd_num_rx + 1) % 0xffff + tx_data.encode_u16(2, cmd_num_tx) else: cmd_state = CmdState.FAIL emit_signal('command_fail', self) @@ -171,7 +173,7 @@ class YaU07 extends unit.Unit: cmd_code_tx = cmd_code return true - func send_load_ems_done(cmd_code: int): + func send_load_ems_done(cmd_code: int) -> bool: if (cmd_state == CmdState.WAIT) \ or (cmd_state == CmdState.SEND) \ or (cmd_state == CmdState.UNCK): @@ -185,6 +187,7 @@ class YaU07 extends unit.Unit: tx_len = 7 cmd_state = CmdState.SEND cmd_code_tx = cmd_code + return true ## Возвращает код команды ЯУ-07. ## rx_data - Принятые данные. @@ -303,24 +306,24 @@ class YaU07 extends unit.Unit: if cmd_result != 1: # Команда не выполнена return false - var cmd_code: CmdCode = rx_data[cmd_code_pos] as CmdCode # "код команды" - var rc: = true - if (cmd_code == CmdCode.READ_ISA) or (cmd_code == CmdCode.WRITE_ISA): - rc = parse_isa(rx_data, status_len) + var cmd_code: int = rx_data[cmd_code_pos] # Код команды - elif (cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK): - rc = parse_block(rx_data, status_len) + cmd_code_rx = cmd_code + if (cmd_state == CmdState.WAIT) and (cmd_num_rx == cmd_num_tx) and (cmd_code == cmd_code_tx): + var rc: = true + if (cmd_code == CmdCode.READ_ISA) or (cmd_code == CmdCode.WRITE_ISA): + rc = parse_isa(rx_data, status_len) + elif (cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK): + rc = parse_block(rx_data, status_len) + elif (cmd_code == CmdCode.ERASE_FLASH) or (cmd_code == CmdCode.WRITE_FLASH) \ + or (cmd_code == CmdCode.READ_FLASH_MP550) or (cmd_code == CmdCode.WRITE_FLASH_MP550) \ + or (cmd_code == CmdCode.READ_FLASH) or (cmd_code == CmdCode.LOAD_FLASH): + rc = parse_flash(rx_data, status_len, cmd_code) - elif (cmd_code == CmdCode.ERASE_FLASH) or (cmd_code == CmdCode.WRITE_FLASH) \ - or (cmd_code == CmdCode.READ_FLASH_MP550) or (cmd_code == CmdCode.WRITE_FLASH_MP550) \ - or (cmd_code == CmdCode.READ_FLASH) or (cmd_code == CmdCode.LOAD_FLASH): - rc = parse_flash(rx_data, status_len, cmd_code) - - if rc: - if (cmd_state == CmdState.WAIT) and (cmd_num_rx == cmd_num_tx): + if rc: cmd_state = CmdState.DONE - cmd_code_rx = cmd_code emit_signal('command_done', self) - else: - emit_signal('parse_failed', self) + else: + emit_signal('parse_failed', self) + return true diff --git a/table/ячейка-цвет.tscn b/table/ячейка-цвет.tscn new file mode 100644 index 00000000..e239b982 --- /dev/null +++ b/table/ячейка-цвет.tscn @@ -0,0 +1,8 @@ +[gd_scene format=3 uid="uid://cug5xjbfdm7x7"] + +[node name="ячейка-цвет" type="ColorPickerButton"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2