15 Commits

Author SHA1 Message Date
sasha80
12fbb1fd55 Доработка. Добавлено ожидание выполнения команды по её коду 2025-12-09 08:49:21 +03:00
sasha80
fd9cf0317f Доработка. Добавлена команда отключения заданий разведки в приборах АФСП и БПО 2025-12-08 16:05:18 +03:00
sasha80
4843d3294a Рефактор. 2025-12-08 10:53:18 +03:00
sasha80
b7a5d24de8 Доработка. Добавлена настройка цвета для кнопки "Подавление" 2025-12-08 10:51:25 +03:00
sasha80
0c36709b54 Доработка. Важное замечание 2025-12-08 10:49:35 +03:00
sasha80
3eb35faa77 Доработка. Важное замечание 2025-12-08 10:48:48 +03:00
sasha80
167048af54 Доработка. Важное замечание 2025-12-08 10:47:23 +03:00
sasha80
f62dab4e4e Доработка. Добавлена настройка цвета для кнопки "Подавление" 2025-12-08 10:40:13 +03:00
sasha80
7e31052148 Доработка. Важное замечание 2025-12-08 10:19:15 +03:00
sasha80
6864b960fb Рефактор. Скрипт режима Настройки вынесен в отдельный файл 2025-12-08 09:06:05 +03:00
sasha80
5ad837ea3e Исправление. Опечатка 2025-12-05 13:42:02 +03:00
sasha80
53f555690b Регрессия. Потерялись изменения изображений для ЭМС-ТГ после 0354c59128 2025-12-05 13:15:47 +03:00
sasha80
662bf5cfc5 Рефактор. Опечатка 2025-12-05 12:51:18 +03:00
sasha80
b74976842e Рефактор. Уменьшить область видимости переменной 2025-12-05 12:50:18 +03:00
sasha80
df69a74411 Исправление. Режим Работа. После запуска должен быть включен режим выбора сектора 2025-12-05 12:49:23 +03:00
46 changed files with 543 additions and 728 deletions

View File

@@ -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`

View File

@@ -4,19 +4,6 @@
[resource]
fallbacks = Array[Font]([ExtResource("1_cxid7")])
cache/0/16/0/ascent = 0.0
cache/0/16/0/descent = 0.0
cache/0/16/0/underline_position = 0.0
cache/0/16/0/underline_thickness = 0.0
cache/0/16/0/scale = 1.0
cache/0/16/0/kerning_overrides/17/0 = Vector2(0, 0)
cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0)
cache/0/16/0/kerning_overrides/18/0 = Vector2(0, 0)
cache/0/16/0/kerning_overrides/14/0 = Vector2(0, 0)
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
@@ -30,11 +17,19 @@ 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/16/0/ascent = 0.0
cache/0/16/0/descent = 0.0
cache/0/16/0/underline_position = 0.0
cache/0/16/0/underline_thickness = 0.0
cache/0/16/0/scale = 1.0
cache/0/16/0/kerning_overrides/17/0 = Vector2(0, 0)
cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0)
cache/0/16/0/kerning_overrides/18/0 = Vector2(0, 0)
cache/0/16/0/kerning_overrides/14/0 = Vector2(0, 0)
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/18/0/ascent = 0.0
cache/0/18/0/descent = 0.0
cache/0/18/0/underline_position = 0.0
@@ -118,3 +113,8 @@ 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -21,8 +21,8 @@ script_export_mode=0
[preset.0.options]
custom_template/debug=""
custom_template/release="/home/user/temp/godot.linuxbsd.template_release.x86_64"
debug/export_console_wrapper=0
custom_template/release=""
debug/export_console_wrapper=2
binary_format/embed_pck=true
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false

View File

@@ -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

View File

@@ -21,7 +21,6 @@ func _ready() -> void:
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)
@@ -44,6 +43,7 @@ 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)

View File

@@ -21,7 +21,6 @@ func _ready() -> void:
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)
@@ -44,6 +43,7 @@ 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)

View File

@@ -21,7 +21,6 @@ func _ready() -> void:
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)
@@ -44,6 +43,7 @@ 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)

View File

@@ -1,103 +1,113 @@
@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 uf_control: Object
var unit_uf: 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()
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)
control_ems(unit_uf.status)
status_uf()
find_labels(self)
func on_update_uf_serviceability(_state: int):
control_ems(uf_control.get_current_status())
func _on_start_contol_device():
on_line_changed()
control_ems(unit_uf.status) # проверка ЭМС ячеек
status_uf() # отслеживание состояния прибора
#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['УФ-онлайн']:
func on_line_changed():
if unit_uf.online: # проверка ЯУ, внутреннего коммутатора и ИП-5Б
$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_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
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD ## заглушка для зеленения ВК-110
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
status_uf(status)
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.NONE
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
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
$lbl_header2.visible = true
emit_signal('control_is_over', unit_uf.name)
func find_labels(node1: Node):

View File

@@ -1,93 +0,0 @@
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

View File

@@ -1 +0,0 @@
uid://b6avo0uvwrxnj

View File

@@ -1,6 +1,6 @@
extends Label
enum DEVICE_STATE {
enum PRD_STATE {
NONE, # Нет связи
GOOD, # Исправно
ERR # Отказ
@@ -13,9 +13,9 @@ enum DEVICE_STATUS {
}
const STATUS_CONFIG := {
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}
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}
}
class DeviceObserver:
@@ -58,8 +58,7 @@ class DeviceObserver:
return changed
var device_observers: Dictionary = {}
var overall_prd_state: DEVICE_STATE = DEVICE_STATE.NONE
var status_uf: int = DEVICE_STATE.NONE # Статус УФ (УАРЭП-ЭМС)
var overall_prd_state: PRD_STATE = PRD_STATE.NONE
func _ready() -> void:
tooltip_text = 'Нет связи с приборами комплекса'
@@ -78,7 +77,9 @@ func _ready() -> void:
prd_module.unit_yau07.connect('line_changed', Callable(self, '_on_prd_online_changed').bind(prd_module))
# Подписка на УФ
signaller.connect('update_uf_serviceability', _on_uf_status_receive)
var unit_uf = network.get_unit_instance('уарэп-эмс')
if unit_uf:
unit_uf.data_received.connect(Callable(self, '_on_uf_status_receive'))
# Инициализация начального состояния
_recalculate_overall_state()
@@ -110,51 +111,41 @@ func _on_prd_control_results(results: Dictionary, prd_module: Object) -> void:
_recalculate_overall_state()
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 _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 _recalculate_overall_state() -> void:
var new_state := DEVICE_STATE.NONE
# Проверяем статус ПРД
var prd_state := DEVICE_STATE.NONE
var has_online_prd := false
var all_prd_operational := true
var new_state := PRD_STATE.NONE
var has_online_devices := false
var all_operational := true
for observer in device_observers.values():
if observer.status[DEVICE_STATUS.ONLINE]:
has_online_prd = true
has_online_devices = true
if observer.status[DEVICE_STATUS.CONTROL]:
# Если контроль завершен - строгая проверка
if not observer.status[DEVICE_STATUS.STATUS]:
all_prd_operational = false
all_operational = false
break
else:
# Если контроль в процессе - мягкая проверка
if not observer.status[DEVICE_STATUS.STATUS]:
all_prd_operational = false
all_operational = false
# Не прерываем, чтобы проверить все устройства
if has_online_prd:
if all_prd_operational:
prd_state = DEVICE_STATE.GOOD
else:
prd_state = DEVICE_STATE.ERR
if has_online_devices:
new_state = PRD_STATE.GOOD if all_operational else PRD_STATE.ERR
else:
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
new_state = PRD_STATE.NONE
if overall_prd_state != new_state:
overall_prd_state = new_state
@@ -171,83 +162,15 @@ 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:
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 "Неисправен"
PRD_STATE.NONE:
return "Нет связи с приборами комплекса"
PRD_STATE.GOOD:
return "Все приборы комплекса исправны"
PRD_STATE.ERR:
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
return "Неизвестное состояние"
# Публичные методы для получения информации
@@ -258,8 +181,7 @@ 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(),
"status_uf": status_uf
"last_results": observer.last_results.duplicate()
}
return {}
@@ -282,6 +204,5 @@ func get_overall_status() -> Dictionary:
"online_devices": online_count,
"operational_devices": operational_count,
"total_devices": device_observers.size(),
"control_complete_devices": control_complete_count,
"uf_status": status_uf
"control_complete_devices": control_complete_count
}

View File

@@ -45,14 +45,6 @@ func enter_press():
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()

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=32 format=3 uid="uid://lwmw4egynmd1"]
[gd_scene load_steps=30 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,7 +54,6 @@ 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 = {}
@@ -107,7 +106,6 @@ 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))
# Пиктограммы приборов, которые отображают состояние подключения только
@@ -116,9 +114,7 @@ func _ready():
var unit_instance: = network.get_unit_instance(unit_name)
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)
@@ -174,8 +170,8 @@ func on_serviceability_changed(state: int, prd_pribor_node: Node)-> void:
prd_pribor_node.state = state
func on_update_uf_serviceability(uf_serviceaability: int, uf_pribor: Node)-> void:
uf_pribor.state = uf_serviceaability
func on_update_uf_serviceability(uf_serviceaability: bool, uf_pribor: Node)-> void:
uf_pribor.state = 1 if uf_serviceaability else 2
func _on_chk_show_functional_toggled(toggled_on: bool) -> void:
@@ -260,21 +256,6 @@ shader_parameter/white = Vector3(0.14, 0.13, 0.13)
shader_parameter/black = Vector3(0.95, 0.55, 0.05)
shader_parameter/gamma = 2.0
[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
@@ -475,7 +456,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(100, 0, 0, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
metadata/online_proc = "on_line_changed"
metadata/unit_name = ["уарэп-яу07-1н"]
@@ -566,6 +547,7 @@ 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
@@ -1443,7 +1425,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(100, 0, 0, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
metadata/unit_name = ["уарэп-яу07-1в"]
metadata/online_proc = "on_line_changed"
@@ -1530,7 +1512,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(100, 0, 0, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
metadata/unit_name = ["уарэп-яу07-1к"]
metadata/online_proc = "on_line_changed"
@@ -1936,7 +1918,6 @@ offset_top = 15.0
offset_right = 1408.0
offset_bottom = 49.0
theme_override_font_sizes/font_size = 22
disabled = true
text = "Показать функциональную схему Э2"
flat = true
@@ -1996,16 +1977,11 @@ default_color = Color(1, 1, 1, 0.352941)
[node name="control_prd_button" type="Button" parent="."]
layout_mode = 0
offset_left = 1040.0
offset_left = 1043.0
offset_top = 64.0
offset_right = 1416.0
offset_right = 1390.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

View File

@@ -0,0 +1,298 @@
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, 'Ограничть возможности по постановке помех'],
['Кнопка «ПД-М', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «ПД-М', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «ОЗП-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «МЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «ОРН-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «ОРН-М', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «ЛЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «ПД-М4С»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «ПД-ЧМ»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «СВ-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «К', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
['Кнопка «СВ-М', 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: = {} ## Для преобразования названия параметра в номер строки
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))
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, 1.0]
ProjectSettings.set_setting('application/config/%s' % 'Цвет кнопки \"Подавление\"', col)
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()

View File

@@ -0,0 +1 @@
uid://dabpum5iqxc7y

View File

@@ -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

View File

@@ -16,13 +16,13 @@ class_name work extends Panel
@export var strob_max_width: float ## Максимальная ширина строба по углу.
@export var strob_min_band: float ## Минимальная ширина строба по частоте.
@export var strob_min_width: float ## Минимальная ширина строба по углу.
@export var window_0_id: int ## Идетификатор окна. Присваивается godot от 0 до количества созданных окон.
@export var window_0_id: int ## Идентификатор окна. Присваивается godot от 0 до количества созданных окон.
const SVK_EMIT = 1 ## Код состояния выполнения помехи - выполняется
var drag_button: MouseButton ## Кнопка мыши нажатая при перетаскивании.
var drag_fsm: DragFSM = DragFSM.IDLE ## Текущее состояние перетаскивания.
var btn_select: BtnSel = BtnSel.THREAT ## Текущее состояние кнопки выбора цели.
var btn_select: BtnSel = BtnSel.SECTOR ## Текущее состояние кнопки выбора цели.
var drag_pos_begin: Vector2 ## Точка начала перетаскивания.
var max_zoom: int ## Максимальный уровень детализации.
var min_zoom: int ## Минимальный уровень детализации.
@@ -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,7 @@ 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)
col_btn_act = ProjectSettings.get_setting('application/config/%s' % 'Цвет кнопки \"Подавление\"', Color.WHITE)
## Обработчик сигнала изменения списка целей.
@@ -190,7 +192,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_FAILED
fs_failed[i] = AntBandState.ANT_BAND_READY
## Производит инициализацию.
@@ -201,6 +203,7 @@ func _ready():
drag_fsm = DragFSM.OFF
var btns_select: Array = get_tree().get_nodes_in_group('группа-режим-выбора')
btns_select.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_select').bind(btn, btns_select)))
on_button_select($btns_select/btn_fs_sector, btns_select)
var nodes: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
nodes.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_pressed').bind(btn, nodes)))
$btn_close.button_connect('pressed', on_btn_close)
@@ -408,9 +411,9 @@ func on_button_select(btn_this, btn_others) -> void:
func on_button_pressed(btn_this, btn_others) -> void:
$chk_auto.set_pressed_no_signal(false)
on_value_changed(false)
var fs_arr: Array = []
for btn_other in btn_others: btn_other.set_pressed(btn_this == btn_other)
var interfer_name: String = btn_this.get_meta('rfi_name')
var interfer_name: String = btn_this.get_meta('rfi_name', 'off')
var fs_arr: Array = []
for key in fs_selected.keys():
fs_arr.append(prd.get_fs_param(key))
signaller.emit_signal('interfer_init', interfer_name, fs_arr, interfer.POW_DEFAULT)
@@ -570,7 +573,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:
@@ -626,7 +629,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].ready
fs_failed[key] = fs_dict[key].isg
func on_btn_center_toggled(toggled_on: bool) -> void:

View File

@@ -197,6 +197,7 @@ size_flags_vertical = 3
tooltip_text = "Кнопка для выбора сектора при помощи клика мышкой"
strips_rotation = 25.0
text = "Сектор"
pressed = true
metadata/state = 2
[node name="chk_auto" type="CheckBox" parent="."]
@@ -383,8 +384,8 @@ texture_normal = ExtResource("14_ggrwd")
[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"]
[connection signal="button_up" from="zoom_plus" to="tilemap" method="_on_zoom_button_up"]
[connection signal="button_up" from="zoom_plus" to="tilemap" method="_on_zoom_plus_button_up"]
[connection signal="button_up" from="zoom_plus" to="tilemap" method="_on_zoom_button_up"]
[connection signal="button_down" from="zoom_minus" to="tilemap" method="_on_zoom_minus_button_down"]
[connection signal="button_up" from="zoom_minus" to="tilemap" method="_on_zoom_button_up"]
[connection signal="pressed" from="btn_all_work" to="." method="_on_btn_all_work_pressed"]

View File

@@ -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):
@@ -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:
signaller.emit_signal('interfer_off', ecm)
interfer_off(ecm, unit_instance)
ecm_active = false
if ecm_active and (prd.fs_caps_id[ecm.nmfs] in fs_closed):
signaller.emit_signal('interfer_off', ecm)
interfer_off(ecm, unit_instance)
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:
signaller.emit_signal('interfer_off', ecm)
interfer_off(ecm, unit_instance)
elif prd.fs_caps_id[ecm.nmfs] in fs_closed:
signaller.emit_signal('interfer_off', ecm)
interfer_off(ecm, unit_instance)
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:
signaller.emit_signal('interfer_off', ecm)
interfer_off(ecm, u)
elif item.priority < ecm.priority:
need_continue = true
break
@@ -496,6 +508,7 @@ 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
@@ -503,17 +516,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():
signaller.emit_signal('interfer_off', ecm)
interfer_off(ecm, unit0)
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]
signaller.emit_signal('interfer_off', ecm)
interfer_off(ecm, unit0)
func pop_id() -> int:
@@ -646,19 +659,13 @@ func get_krp(threat: threats.Threat):
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)
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 interfer_off(ecm, _unit_caps):
signaller.emit_signal('interfer_off', ecm)
func on_interfer_new(ecm, unit_caps):

View File

@@ -2,8 +2,6 @@ extends Node
enum PrdState {WORK, CONTROL}
const TIME_YAU07_SEND = 50
## Границы секторов блоков ФС по частоте в режиме РТО.
const FS_BAND_RTO: Dictionary = {
0: [200.0, 250.0],
@@ -121,9 +119,6 @@ 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)
@@ -154,9 +149,6 @@ 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 {
@@ -216,6 +208,7 @@ 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
@@ -310,13 +303,11 @@ class PRD:
break
return STATE_DEVICE.NONE if all_online else STATE_DEVICE.ERROR
func execute_cmd():
var time_now = Time.get_ticks_msec()
if (time_now - unit_yau07.time_tx) < TIME_YAU07_SEND: return
if not len(cmd_array): return
if unit_yau07.cmd_state != unit_yau07.CmdState.DONE: return
var cmd: Array = cmd_array.pop_front()
unit_yau07.time_tx = time_now
unit_yau07.send_isa(cmd[0], cmd[1])
func start_load():
@@ -347,16 +338,14 @@ 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()
@@ -364,7 +353,6 @@ 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
@@ -379,7 +367,6 @@ 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('навигация')
@@ -446,6 +433,7 @@ 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)
@@ -473,7 +461,6 @@ 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'):
@@ -492,16 +479,3 @@ 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)

View File

@@ -14,7 +14,7 @@ const PROGRESS_RAY_STATES: float = 50.0
const PROGRESS_COMPLETE: float = 100.0
## Константы для работы с лучами управления
const COUNT_PACK_POWER_RECIEVE = 10
const COUNT_PACK_POWER_RECIEVE = 15
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) # Установка максимального значения для прогресс бара
@@ -390,6 +390,7 @@ 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)
@@ -995,17 +996,18 @@ 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_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]])
#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]])
return true

View File

@@ -204,7 +204,7 @@ signal update_coordinates_map(new_coordinates)
## Вызывается при изменении исправности прибора УФ.[br]
## [param uf_serviceaability] - обновленное значение состояния исправности ([b]true[/b]
signal update_uf_serviceability(uf_serviceaability: int)
signal update_uf_serviceability(uf_serviceaability: bool)
signal tool_tip(new_ctrl_pos)

View File

@@ -41,7 +41,6 @@ class YaU07 extends unit.Unit:
var isa_block: = {} ## Результат выполнения команды "читать массив из порта"
var flash_data: = PackedByteArray() ## Данные прочитанные из Flash
var flash_len: = 0 ## Длинна данных прочитанных из Flash
var time_tx: int = 0 ## Время последней отправки команды
func _to_string() -> String: return String('яу07: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
@@ -304,24 +303,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)
if (cmd_state == CmdState.WAIT) and (cmd_num_rx == cmd_num_tx) and (cmd_code == cmd_code_tx):
cmd_code_rx = cmd_code
cmd_state = CmdState.DONE
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):
cmd_state = CmdState.DONE
cmd_code_rx = cmd_code
if rc:
emit_signal('command_done', self)
else:
emit_signal('parse_failed', self)
else:
emit_signal('parse_failed', self)
return true

View File

@@ -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