Рефакторинг. Аннотации GDScript

This commit is contained in:
sasha80
2023-08-09 15:16:00 +03:00
parent ffb35b8ca6
commit 74abae7195
8 changed files with 173 additions and 191 deletions

View File

@@ -1,19 +1,19 @@
extends Sprite2D
func set_strob_visible(val: bool): $строб.visible = val
func set_strob_dir(val: float): $строб.material.set('shader_parameter/dir', val)
func set_strob_color(val: Color): $строб.material.set('shader_parameter/color', val)
func set_strob_width(val: float): $строб.material.set('shader_parameter/width', val)
func set_strob_band(val: float): $строб.material.set('shader_parameter/band', val / 125.0)
func set_strob_radius(val: float): $строб.material.set('shader_parameter/radius', sv(val))
func set_strob_visible(val: bool): $строб.visible = val
func set_strob_center(val: Vector2): $строб.position = val
func set_strob_dir(val: float): $строб.material.set('shader_parameter/dir', val)
func set_strob_color(val: Color): $строб.material.set('shader_parameter/color', val)
func set_strob_width(val: float): $строб.material.set('shader_parameter/width', val)
func set_strob_band(val: float): $строб.material.set('shader_parameter/band', val / 125.0)
func set_strob_radius(val: float): $строб.material.set('shader_parameter/radius', sv(val))
func get_strob_center() -> Vector2: return $строб.position
func get_strob_visible() -> bool: return $строб.visible
func get_strob_width() -> float: return $строб.material.get('shader_parameter/width')
func get_strob_band() -> float: return $строб.material.get('shader_parameter/band') * 125.0
func get_strob_radius(val: float): return $строб.material.set('shader_parameter/radius', sv(val))
func get_radius_max() -> float: return $строб.scale.x / 3.3
func get_radius_min() -> float: return 212.0
func get_strob_center() -> Vector2: return $строб.position
func get_strob_visible() -> bool: return $строб.visible
func get_strob_width() -> float: return $строб.material.get('shader_parameter/width')
func get_strob_band() -> float: return $строб.material.get('shader_parameter/band') * 125.0
func get_strob_radius(val: float) -> float: return $строб.material.set('shader_parameter/radius', sv(val))
func get_radius_max() -> float: return $строб.scale.x
func get_radius_min() -> float: return 212.0
func sv(val: float) -> float: return val / ($строб.scale.x / 2.0) * 0.125

View File

@@ -4,6 +4,12 @@ var TableHeader = preload('res://table/header.tscn')
var TableNode = preload('res://table/node.tscn')
var db_th_id = 0
func on_row_pressed(i_row: int):
var selected = $scrl_threats/tbl_threats.is_row_selected(i_row)
$scrl_threats/tbl_threats.set_row_selected(i_row, not selected)
func _ready() -> void:
assert(TableHeader)
assert(TableNode)
@@ -16,19 +22,3 @@ func init_table():
$scrl_threats/tbl_threats.set_columns_min_size([50, 140, 140, 100])
$scrl_threats/tbl_threats.pin_header($scrl_threats, self)
$scrl_threats/tbl_threats.connect('row_pressed', Callable(self, 'on_row_pressed'))
func on_row_pressed(i_row: int): $scrl_threats/tbl_threats.set_row_selected(i_row, true)
func _on_btn_add_thr_pressed() -> void:
var i_row = $scrl_threats/tbl_threats.get_rows_count()
$scrl_threats/tbl_threats.add_row([TableNode, TableNode, TableNode, TableNode])
$scrl_threats/tbl_threats.set_row_text(i_row, ['%d' % db_th_id, '%d' % ((i_row * 100) + 2000), '%d' % ((i_row * 20) % 360), 'Нет'])
db_th_id += 1
func _on_btn_del_thr_pressed() -> void:
var i_rows: = Array()
$scrl_threats/tbl_threats.get_selected_rows(i_rows)
for i in i_rows: $scrl_threats/tbl_threats.remove_row(i)

View File

@@ -1,64 +1,55 @@
extends Panel
@export var col_red: Color
@export var col_grey: Color
@export var strob_min_width: float
@export var strob_max_width: float
@export var strob_min_band: float
@export var strob_max_band: float
@export var drag_scale_width: float
@export var drag_scale_band: float
@export var window_0_id: int
@export var Bip: PackedScene
## Основной скрипт для режима "Работа"
signal add_imit_threat (signal_name: String)
signal del_imit_threat (signal_name: String)
enum DRAG_FSM { IDLE, DRAG, OFF }
""" Состояние перетаскивания """
var drag_pos_begin: Vector2
""" Точка начала перетаскивания """
var drag_fsm: DRAG_FSM = DRAG_FSM.IDLE
""" Текущее состояние перетаскивания """
var drag_button: MouseButton
""" Кнопка мыши нажатая при перетаскивании """
var strob_width_begin: float
""" Ширина строба по углу в момент начала перетаскивания """
var strob_dir_begin: float
""" Направление антенны в момент начала перетаскивания """
var strob_band_begin: float
""" Ширина строба в момент начала перетаскивания """
var strob_center: Vector2
""" Центр антенн """
var shift_pressed: bool
""" Кнопка SHIFT нажата """
signal drag_begin
""" Вызывается в момент начала перетаскивания """
signal drag_continue
""" Вызывается во время продолжения перетаскивания """
signal drag_end
""" Вызывается в момент завершения перетаскивания """
signal full_screen
""" Вызывается при смене режима окна полный экран - оконный """
@export var Bip: PackedScene ## Сцена точки индикатора излучения цели
@export var col_grey: Color ## Второй цвет для фона
@export var col_red: Color ## Первый цвет для фона
@export var drag_scale_band: float ## Масштаб изменения параметра от движения мыши для строба по радиальному размеру
@export var drag_scale_width: float ## Масштаб изменения параметра от движения мыши для строба по угловому размеру
@export var radius_internal: float ## Внутренний радиус диаграммы пеленг-частота
@export var radius_outter: float ## Внешний радиус диаграммы пеленг-частота
@export var strob_max_band: float ## Максимальная ширина строба по углу
@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 до количесва созданных окон
var drag_button: MouseButton ## Кнопка мыши нажатая при перетаскивании
var drag_fsm: DRAG_FSM = DRAG_FSM.IDLE ## Текущее состояние перетаскивания
var drag_pos_begin: Vector2 ## Точка начала перетаскивания
var shift_pressed: bool ## Кнопка SHIFT нажата
var strob_band_begin: float ## Ширина строба в момент начала перетаскивания
var strob_center: Vector2 ## Центр антенн
var strob_dir_begin: float ## Направление антенны в момент начала перетаскивания
var strob_width_begin: float ## Ширина строба по углу в момент начала перетаскивания
signal drag_begin ## Вызывается в момент начала перетаскивания
signal drag_continue ## Вызывается во время продолжения перетаскивания
signal drag_end ## Вызывается в момент завершения перетаскивания
signal full_screen ## Вызывается при смене режима окна полный экран - оконный
## Состояние перетаскивания
enum DRAG_FSM {
DRAG, ## В процессе
IDLE, ## Не активно, ожидание
OFF ## Выключено
}
## Переключант режим окна программы полный экран - обычный
func _on_full_screen(): toggle_full_screen(window_0_id)
func _ready():
## Обработчик сигнала изменения списка целей
func on_threats_changed(threats: Dictionary, th: Object): $count_all_pad/count_all.text = '%02d' % threats.size()
## Производит инициализацию
func _ready():
$btn_strobe.button_connect('pressed', Callable(self, 'on_button_strobe_pressed'))
$btn_off.set_pressed(true)
strob_center = $canvas.get_strob_center()
@@ -66,23 +57,16 @@ func _ready():
drag_fsm = DRAG_FSM.OFF
var nodes: = get_tree().get_nodes_in_group('группа-режим-помехи')
nodes.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_pressed').bind(btn, nodes)))
Threats.connect('threat_new', Callable(self, 'on_threat_new'))
Threats.connect('threat_update', Callable(self, 'on_threat_update'))
Threats.connect('threat_lost', Callable(self, 'on_threat_lost'))
Threats.connect('threat_new', Callable(self, 'on_threats_changed'))
Threats.connect('threat_lost', Callable(self, 'on_threats_changed'))
Threats.connect('threat_new', Callable(self, 'on_threat_new'))
Threats.connect('threat_new', Callable(self, 'on_threats_changed'))
Threats.connect('threat_update', Callable(self, 'on_threat_update'))
func pos_calc(freq: float, aoa: float, pos0: Vector2, r0: float, r1: float, f0: float, df: float):
var r = ((freq - f0) / df) * r1 + r0
var aoa_rad = Tools.radians(aoa) - PI / 2.0
var x = cos(aoa_rad) * r + pos0.x
var y = sin(aoa_rad) * r + pos0.y
return Vector2(x, y)
## Производит отображение цели на диаграмму
func map_threat_to_bip(th: Threats.Threat, bip: Sprite2D):
bip.position = pos_calc (
bip.position = Tools.pos_calc (
th.freq,
th.aoa,
$canvas.get_strob_center(),
@@ -92,11 +76,13 @@ func map_threat_to_bip(th: Threats.Threat, bip: Sprite2D):
REPSettings.ThreatParams.freq_max[0] - REPSettings.ThreatParams.freq_min[0])
## Обработчик сигнала обновления цели
func on_threat_update(threats: Dictionary, th: Object):
var bip = get_node('%d' % th.id)
map_threat_to_bip(th, bip)
## Обработчик сигнала обнаружения цели
func on_threat_new(threats: Dictionary, th: Object):
var bip = Bip.instantiate()
bip.name = '%d' % th.id
@@ -104,16 +90,14 @@ func on_threat_new(threats: Dictionary, th: Object):
add_child(bip)
## Обработчик сигнала потери цели
func on_threat_lost(threats: Dictionary, th: Object):
var bip = get_node('%d' % th.id)
remove_child(bip)
bip.free()
func on_threats_changed(threats: Dictionary, th: Object):
$count_all_pad/count_all.text = '%02d' % threats.size()
## Обработчик нажатия кнопки "Строб". Управляет отображением строба
func on_button_strobe_pressed():
if $btn_strobe.is_pressed():
$canvas.set_strob_visible(true)
@@ -123,30 +107,26 @@ func on_button_strobe_pressed():
drag_fsm = DRAG_FSM.OFF
## Поведение радиокнопок в группе. Управляет состоянием кнопок в радиогруппе
func on_button_pressed(btn_this, btn_others):
# поведение радиокнопок в группе
for btn_other in btn_others:
btn_other.set_pressed(btn_this == btn_other)
func clip_value(val, val_min, val_max):
if val < val_min: val = val_min
if val > val_max: val = val_max
return val
for btn_other in btn_others: btn_other.set_pressed(btn_this == btn_other)
## Возвращает ширину строба по направлению
func get_strob_width(pos: Vector2, prev: float) -> float:
var strob_dir_width: float = prev + (drag_pos_begin.y - pos.y) * drag_scale_width
strob_dir_width = clip_value(strob_dir_width, strob_min_width, strob_max_width)
strob_dir_width = Tools.clip_value(strob_dir_width, strob_min_width, strob_max_width)
return strob_dir_width
## Возвращает ширину строба по частоте
func get_strob_band(pos: Vector2, prev: float) -> float:
var strob_dir_band: float = prev - (drag_pos_begin.y - pos.y) * drag_scale_band
strob_dir_band = clip_value(strob_dir_band, strob_min_band, strob_max_band)
strob_dir_band = Tools.clip_value(strob_dir_band, strob_min_band, strob_max_band)
return strob_dir_band
## Устанавливает центр строба по частоте и направлению
func set_strob(pos: Vector2):
var radp: Vector2 = Tools.map_dec_to_rad(strob_center, pos)
if radp.y < $canvas.get_radius_max():
@@ -154,6 +134,7 @@ func set_strob(pos: Vector2):
$canvas.set_strob_radius(radp.y)
## Обработка движения мыши для управления стробом. Вызывается во время движения мыши
func _on_drag_continue(event):
if drag_button == MOUSE_BUTTON_RIGHT:
if shift_pressed:
@@ -166,6 +147,7 @@ func _on_drag_continue(event):
set_strob(event.position)
## Обработка движения мыши для управления стробом. Вызывается при нажатии мыши
func _on_drag_begin(event):
drag_pos_begin = event.position
if drag_button == MOUSE_BUTTON_LEFT:
@@ -175,6 +157,7 @@ func _on_drag_begin(event):
strob_band_begin = $canvas.get_strob_band()
## Обработчик событий вввода. Вызывается godot
func _input(event):
if event is InputEventMouseMotion:
if drag_fsm == DRAG_FSM.DRAG:
@@ -195,6 +178,7 @@ func _input(event):
shift_pressed = event.pressed
## Переключает режим окна программы полный - обычный экран
func toggle_full_screen(id: int):
var mode = DisplayServer.window_get_mode(id)
if mode == DisplayServer.WINDOW_MODE_FULLSCREEN:

View File

@@ -197,26 +197,6 @@ theme_override_colors/font_color = Color(0.729412, 0.729412, 0.729412, 1)
text = "128"
horizontal_alignment = 1
[node name="btn_add_thr" type="Button" parent="frm_threats"]
layout_mode = 0
offset_left = 6.0
offset_top = 4.0
offset_right = 24.0
offset_bottom = 31.0
scale = Vector2(1, 0.6)
tooltip_text = "Добавить имитационную цель"
text = "+"
[node name="btn_del_thr" type="Button" parent="frm_threats"]
layout_mode = 0
offset_left = 28.0
offset_top = 4.0
offset_right = 46.0
offset_bottom = 31.0
scale = Vector2(1, 0.6)
tooltip_text = "Удалить цель"
text = "-"
[node name="scrl_threats" type="ScrollContainer" parent="frm_threats"]
layout_mode = 0
offset_left = 8.0
@@ -725,5 +705,3 @@ text = "Опасных:"
[connection signal="drag_begin" from="." to="." method="_on_drag_begin"]
[connection signal="drag_continue" from="." to="." method="_on_drag_continue"]
[connection signal="full_screen" from="." to="." method="_on_full_screen" flags=3]
[connection signal="pressed" from="frm_threats/btn_add_thr" to="frm_threats" method="_on_btn_add_thr_pressed"]
[connection signal="pressed" from="frm_threats/btn_del_thr" to="frm_threats" method="_on_btn_del_thr_pressed"]

View File

@@ -24,13 +24,16 @@ extends Node
@export var ThreatParams = {
'time_lost': [5.0, 'Время после последнего обновления в с, через которое цель считается потерянной'],
'freq_min': [200.0, 'Нижняя рабочая частота, МГЦ'],
'freq_max': [6000.0, 'Нижняя рабочая частота, МГЦ'] }
'time_lost': [5.0, 'Время после последнего обновления в с, через которое цель считается потерянной'],
'freq_min': [200.0, 'Нижняя рабочая частота, МГЦ'],
'freq_max': [6000.0, 'Нижняя рабочая частота, МГЦ'],
'radius_inner': [100, 'Внутренний радиус в пикселях для отображения частота-пеленг'],
'radius_outter': [800, 'Наружний радиус в пикселях для отображения частота-пеленг'] }
func _ready() -> void: Log.info('Модуль настроек готов')
func get_unit_key(unit_name: String) -> Array:
assert(unit_name in UnitProfiles, 'ошибка: нет такого устройства "%s"' % unit_name)
var item = UnitProfiles[unit_name]

View File

@@ -55,6 +55,7 @@ func _ready() -> void:
func on_timer_check_lost(unit, time_lost: int):
""" Периодически проверяет приборы на связи """
for th in threats.values():
if (unit.tick - th.atick) >= time_lost:
threats.erase(th.id)
@@ -66,13 +67,13 @@ func on_data_capsrpb_received(unit: capsrpb.CapsRpb):
return
var mis = unit.json_dic['mis']
for dic_th in mis:
if 'id' in dic_th:
if dic_th.has('id'):
var id = int(dic_th['id'])
if id in threats:
if threats.has(id):
var th = threats[id]
th.set_from_dic(dic_th)
th.atick = unit.tick
call_deferred('emit_signal', 'threat_update', threats, th)
call_deferred('emit_signal', threat_update, threats, th)
else:
var th = Threat.new()
th.set_from_dic(dic_th)

View File

@@ -1,11 +1,40 @@
extends Node
## Простые часто используемые функции
## Производит преобразование из угла в радианы
func radians(val: float): return (val * PI) / 180.0
## Возвращает значение из байтового массива в 16 битное слово
func ibytes_to_word(buf: PackedByteArray, i: int) -> int: return buf[i] + (buf[i + 1] * 256)
## Возвращает расстояние от центра координат до точки
func hypot(x: float, y: float) -> float: return sqrt(x * x + y * y)
## Проверяет пересечение диапазона x1, x2 с диапазоном y1, y2 """
func is_overlap(x1, x2, y1, y2): return max(x1, y1) <= min(x2, y2)
## Производит преобразование из декартовой в полярную систему координат
func pos_calc(freq: float, aoa: float, pos0: Vector2, r0: float, r1: float, f0: float, df: float):
var r = ((freq - f0) / df) * r1 + r0
var aoa_rad = Tools.radians(aoa) - PI / 2.0
var x = cos(aoa_rad) * r + pos0.x
var y = sin(aoa_rad) * r + pos0.y
return Vector2(x, y)
## Отсекает значение до заданного диапазона
func clip_value(val, val_min, val_max):
if val < val_min: val = val_min
if val > val_max: val = val_max
return val
## Возвращает массив с именами членов класса
func get_members_names(obj: Object) -> Array:
var pl = obj.get_property_list()
var names: = Array()
@@ -13,6 +42,7 @@ func get_members_names(obj: Object) -> Array:
return names
## Проверяет, что заданный массив похож на ip-адрес
func assert_array_ipaddr(val: Array):
""" Выкидывает исключение, если массив не содержит ip-адрес """
assert(val.size() == 2)
@@ -21,29 +51,25 @@ func assert_array_ipaddr(val: Array):
assert((0 < val[1]) and (val[1] < 65536))
## Преобразует декартовые координаты в полярные
func map_dec_to_rad(pos0: Vector2, pos: Vector2) -> Vector2:
""" Преобразует декартовые координаты в полярные """
var x1: float = pos.x - pos0.x
var y1: float = pos.y - pos0.y
var ang: float = (atan2(y1, x1) * 180.0) / PI
return Vector2(ang + 360.0 * float(ang < 0.0), hypot(x1, y1))
func is_overlap(x1, x2, y1, y2):
""" Проверяет пересечение диапазона x1, x2 с диапазоном y1, y2 """
return max(x1, y1) <= min(x2, y2)
## Переводит значение val из диапазона a0...a1 в диапазон b0...b1
func map_range(val: float, a0: float, a1: float, b0: float, b1: float) -> float:
""" Переводит значение val из диапазона a0...a1 в диапазон b0...b1 """
return (((val - a0) * (b1 - b0)) / (a1 - a0)) + b0
## Возвращает true, если val число, false - если иначе
func type_is_num(val) -> bool:
""" Возвращает true, если val число, false - если иначе """
return (typeof(val) == TYPE_INT) or (typeof(val) == typeof(0.0))
## Возвращает true, если точка внутри заданного полигона
func is_point_in_polygon(pos: Vector2, p: PackedVector2Array) -> bool:
var j: int = len(p) - 1
var odd_nodes: int = 0
@@ -54,13 +80,11 @@ func is_point_in_polygon(pos: Vector2, p: PackedVector2Array) -> bool:
return odd_nodes > 0
## Устанавливает слово в байтовом массиве
## buf - Байтовый массив
## index - Индекс младшего байта слова в массиве
## val - Значение слова для записи в батовый массив
## return - Ничего
func set_wordi(buf: Array, index, val):
"""
Устанавливает слово в байтовом массиве
:param buf: Байтовый массив
:param index: Индекс младшего байта слова в массиве
:param val: Значение слова для записи в батовый массив
:return: None """
buf[index] = val & 0xff
buf[index + 1] = (val >> 8) & 0xff

View File

@@ -1,47 +1,50 @@
extends Node
# Протокол ячейки ЯУ-07
## Протокол ячейки ЯУ-07
const ONLINE_TIMEOUT = 5.0 # Время ожидания пакета от ячейки, секунды
const RESEND_TIMEOUT = 0.3 # Задержка для повторной отправки команды, секунды
const RETRY_COUNT = 5 # Количество повторных отправок
const BUFFER_SIZE = 2048
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды
const RESEND_TIMEOUT = 0.3 ## Задержка для повторной отправки команды, секунды
const RETRY_COUNT = 5 ## Количество повторных отправок
const BUFFER_SIZE = 2048 ## Размер буфера для приёма датаграмм
# Ячейка ЯУ-07
## Ячейка ЯУ-07
class YaU07:
## Коды выполняемых команд
enum CmdCode {
READ_ISA = 0, # Код команды "читать порт ISA" ячейки ЯУ-07
WRITE_ISA = 1 } # Код команды "записать порт ISA" ячейки ЯУ-07
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07
WRITE_ISA = 1 ## Код команды "записать порт ISA" ячейки ЯУ-07
}
## Состояние автомата выполнения команды
enum CmdState {
UNCK, # Номер команды не ининцирован
SEND, # Буфер готов для отправки
WAIT, # Ожидание выполнения
DONE, # Команда выполнена
FAIL } # Команда не выполнена
UNCK, ## Номер команды не ининцирован
SEND, ## Буфер готов для отправки
WAIT, ## Ожидание выполнения
DONE, ## Команда выполнена
FAIL ## Команда не выполнена
}
signal line_changed(unit: YaU07)
signal command_done(unit: YaU07)
signal command_fail(unit: YaU07)
signal line_changed(unit: YaU07) ## Вызывается когда меняется состояние связи с ячейкой
signal command_done(unit: YaU07) ## Вызывается после выполнения команды
signal command_fail(unit: YaU07) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена
var name: = String()
var cmd_num_rx: = 0 # Номер команды принятый
var cmd_num_tx: = 0 # Номер команды переданный
var cmd_state = CmdState.UNCK # Состояние выполнения команды
var cmd_result: = 1 # Результат выполнения команды. Устанавливается в ЯУ-07
var cmd_data: = PackedByteArray() # Данные команды. Устанавливается в ЯУ-07
var cmd_retry = 0
var tick = 0.0
var cmd_tick_tx = 0.0
var cmd_tick_rx = 0.0
var status: = PackedByteArray() # Поле "состояние прибора"
var tx_data: = [] # Буфер отправленный
var tx_len = 0
var isa_ports = {} # Результат выполнения команды "читать порт"
var online = false
var cmd_num_rx: = 0 ## Номер команды принятый
var cmd_num_tx: = 0 ## Номер команды переданный
var cmd_state = CmdState.UNCK ## Состояние выполнения команды
var cmd_result: = 1 ## Результат выполнения команды. Устанавливается в ЯУ-07
var cmd_data: = PackedByteArray() ## Данные команды. Устанавливается в ЯУ-07
var cmd_retry = 0 ## Счётчик оставшихся попыток выполнить команду
var tick = 0.0 ## Текущее тик-время в мс
var cmd_tick_tx = 0.0 ## Время последней отправки команды
var cmd_tick_rx = 0.0 ## Время последнего приёма команды
var status: = PackedByteArray() ## Поле "состояние прибора"
var tx_data: = [] ## Буфер отправленный
var tx_len = 0 ## Длина последнего отправленного пакета
var isa_ports = {} ## Результат выполнения команды "читать порт"
var online = false ## Состояние связи с ячейкой
func _to_string() -> String: return String('яу07: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
@@ -105,10 +108,10 @@ class YaU07:
return true
## Возвращает код команды ЯУ-07
## rx_data - Принятые данные
## Возвращает - Код команды не найден, 0...255 - код команды
func get_cmd_code(rx_data):
""" Возвращает код команды ЯУ-07
:param rx_data: Принятые данные
:return: None - Код команды не найден, 0...255 - код команды """
var rx_data_len = rx_data.size()
if rx_data_len < 7:
@@ -143,13 +146,12 @@ class YaU07:
return i > 0
## Заполняет состояние прибора данными прочитанными из портов ЯУ-07
## для команд "читать порты" или "записать порты"
## rx_data - Принятые данные
## Возвращает True - Данные обработаны успешно,
## Возвращает False - Данные не обработаны из за ошибки
func parse(rx_data: PackedByteArray) -> bool:
"""
Заполняет состояние прибора данными прочитанными из портов ЯУ-07
для команд "читать порты" или "записать порты"
:param rx_data: Принятые данные
:return: True - Данные обработаны успешно,
False - Данные не обработаны из за ошибки """
if not online:
online = true