Merge remote-tracking branch 'sasha/master'

# Conflicts:
#	modbus/server-serial-modbus.py
#	scripts/yems-boards.gd
This commit is contained in:
MaD_CaT
2024-10-28 11:31:33 +03:00
49 changed files with 1668 additions and 323 deletions

View File

@@ -9,30 +9,30 @@ var FILES_ROWS_ALIGNMENT = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNM
func fill_files_table(tbl: table, folder: String, rows_types: Array):
var dir: = DirAccess.open(folder)
if dir == null:
return
var files: = []
var exclude_names: = ['.', '..']
dir.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
while true:
var file: = dir.get_next()
if file == '':
break
if file in exclude_names:
continue
var file_name = folder + '/' + file
var fd = FileAccess.open(file_name, FileAccess.READ)
if not fd:
continue
var glob_path = ProjectSettings.globalize_path(file_name)
var sz = fd.get_length()
var ut = fd.get_modified_time(file_name)
fd.close()
var mt = Time.get_datetime_dict_from_unix_time(ut)
var file_row = [file, '%d' % sz, '%d-%02d-%02d %02d:%02d' % [mt.year, mt.month, mt.day, mt.hour, mt.minute]]
tbl.add_row(rows_types)
var i_row = tbl.get_rows_count() - 1
tbl.set_row_text(i_row, file_row)
tbl.set_node_meta(0, i_row, 'file_path', glob_path)
dir.list_dir_end()
var dir: = DirAccess.open(folder)
if dir == null:
return
var files: = []
var exclude_names: = ['.', '..']
dir.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
while true:
var file: = dir.get_next()
if file == '':
break
if file in exclude_names:
continue
var file_name = folder + '/' + file
var fd = FileAccess.open(file_name, FileAccess.READ)
if not fd:
continue
var glob_path = ProjectSettings.globalize_path(file_name)
var sz = fd.get_length()
var ut = fd.get_modified_time(file_name)
fd.close()
var mt = Time.get_datetime_dict_from_unix_time(ut)
var file_row = [file, '%d' % sz, '%d-%02d-%02d %02d:%02d' % [mt.year, mt.month, mt.day, mt.hour, mt.minute]]
tbl.add_row(rows_types)
var i_row = tbl.get_rows_count() - 1
tbl.set_row_text(i_row, file_row)
tbl.set_node_meta(0, i_row, 'file_path', glob_path)
dir.list_dir_end()

View File

@@ -112,6 +112,9 @@ func _ready():
signaller.connect('interfer_rcv', Callable(self, 'on_interfer_rcv').bind(unit_5p28, ecms))
signaller.connect('interfer_new', Callable(self, 'send_ecm').bind(unit))
signaller.connect('interfer_off_all', Callable(self, 'on_interfer_off_all').bind(unit, ecms))
signaller.connect('th_aoa_update', Callable(self, 'on_th_aoa_update').bind(ecms, unit))
signaller.connect('interfer_off', Callable(self, 'on_interfer_off'))
threats.connect('threat_lost', Callable(self, 'on_threats_lost').bind(ecms, unit))
## Проверяет состояние отправки пакета и если не доставлен, повторяет отправку.
@@ -124,6 +127,18 @@ func on_timer_check_state(unit, ecms, resend_timeout):
ecm.tick_tx = tick
func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit):
for thr in threats.values():
var th_id = thr.id
for ecm_i in thrs.keys():
if thrs[ecm_i] == th_id:
var ecm = ecms[ecm_i]
ecm.params['freq'] = thr.freq
ecm.kni = thr.aoa
send_ecm(ecm, unit)
signaller.emit_signal('fs_update_color', ecms)
## Производит приём состояния помех. [param unit] -> [param ecms].
func on_data_capsrpb_received(unit: capsrpb.CapsRpb, ecms: Dictionary):
if not unit.json_dic.has('ts'): return
@@ -248,6 +263,16 @@ func on_interfer_off_all(unit, ecms):
send_ecm(ecm, unit)
signaller.emit_signal('interfer_off',ecm, ecms, thrs)
func on_threats_lost(th, ecms, unit):
for key in interfer.thrs:
if interfer.thrs[key] == th.id:
var ecm_id = key
var ecm = ecms[ecm_id]
ecm.krp = INTERFER_OFF
push_id(ecm.ispp)
send_ecm(ecm, unit)
signaller.emit_signal('interfer_off',ecm, ecms, thrs)
func pop_id():
var id = 0

View File

@@ -1,8 +1,22 @@
@tool
class_name rep_network extends Node
const PROTOCOL_TYPES: = {'yau07tx': yau07.YaU07, 'json-capsrpb': capsrpb.CapsRpb, 'udp-json-mbcs': modbus.ModbusClient}
const TCP_PROTO: = {'5p28': tcp5p28.TCP5P28}
const SERIAL_PROTO: = {'uart': spt25.SPT25 }
class Serial extends SerialPort:
func send_to(data: PackedByteArray):
write_raw(data)
func try_open(parsing_proc: Callable):
if not is_open():
open(port)
if is_open():
data_received.connect(parsing_proc)
start_monitoring(timeout)
class Socket extends PacketPeerUDP:
func send_to(addr, data):
@@ -14,7 +28,7 @@ class SocketTCP extends TCPServer:
const RX_TIMEOUT: int = 1000 ## Время сброса счётчика принятия части пакета.
var peerstream: = PacketPeerStream.new()
var unit_key: Array ## Ключ юнита.
var head_len: int = 8 ## Длинна заголовка команды.
var head_len: int = 8 ## Длина заголовка команды.
var len_place: int = 4 ## Номер начального байта с длинной блока данных.
var type_len: int = 4 ## Количество байт в размере длинны.
var rx_tick: int ## Время приёма последнего пакета.
@@ -31,7 +45,10 @@ class SocketTCP extends TCPServer:
var poll_sockets: Array[Socket]
var tcp_sockets: Array
var units: Dictionary
var units_udp: Dictionary
var units_tcp: Dictionary
var units_serial: Dictionary
var serials: Dictionary
var dst_ports: Dictionary
var unit_keys: Dictionary
var sock_unicast: Socket
@@ -62,6 +79,20 @@ func create_tcpsocket(nm) -> SocketTCP:
return sock
func create_serial(nm) -> Serial:
var port = repsettings.UnitProfiles[nm][1]
var baud = repsettings.UnitProfiles[nm][2][0]
var sp: = Serial.new()
sp.baudrate = baud
sp.timeout = 20000
var rc = sp.open(port)
if rc != Error.OK:
log.message(log.ERROR, 'Невозможно открыть порт \"%s\" для \"%s\"' % [port, nm])
else:
log.message(log.INFO, 'Последовательный порт \"%s\"@%d открыт для \"%s\"' % [port, baud, nm])
return sp
func _ready() -> void:
log.info('Модуль работы с сетью готов')
poll_sockets.append(create_socket('уарэп-яу07-частный'))
@@ -78,6 +109,7 @@ func _ready() -> void:
var unit = PROTOCOL_TYPES[proto].new(unit_name)
var unit_key = repsettings.get_unit_key(unit_name)
units[unit_key] = unit
units_udp[unit_key] = unit
if logger_page:
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
@@ -85,7 +117,7 @@ func _ready() -> void:
dst_ports[unit_key] = settings[2][1]
else:
dst_ports[unit_key] = settings[2][0]
if proto in TCP_PROTO:
var unit = TCP_PROTO[proto].new(unit_name)
var unit_key = repsettings.get_unit_key(unit_name)
@@ -94,12 +126,24 @@ func _ready() -> void:
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
if proto in SERIAL_PROTO:
var unit = SERIAL_PROTO[proto].new(unit_name)
var unit_key = repsettings.get_unit_key(unit_name)
if logger_page:
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
var serial = create_serial(unit_name)
units_serial[unit_key] = unit
units[unit_key] = unit
serials[unit_key] = serial
serial.try_open(unit.parse)
tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp[repsettings.get_unit_key('уарэп-5п28')]])
for key in units: log.info('%s %s:%d' % [units[key].name, key[0], key[1]])
for key in units: log.info('%s %s:%d' % [units[key].name, key[0], key[1]])
for key in units_tcp: log.info('%s %s:%d' % [units_tcp[key].name, key[0], key[1]])
for key in dst_ports:
unit_keys[dst_ports[key]] = key
for key in dst_ports: unit_keys[dst_ports[key]] = key
func poll_receive(sock: Socket, tick: int) -> bool:
while sock.get_available_packet_count() > 0:
@@ -119,7 +163,6 @@ func poll_receive_tcp(sock: SocketTCP, tick: int) -> bool:
if sock.is_connection_available(): # check if someone's trying to connect
var client = sock.take_connection() # accept connection
sock.peerstream.set_stream_peer(client) # bind peerstream to new client
print_debug('client_is_connected')
var peer = sock.peerstream.get_stream_peer()
if peer:
var peer_len_data = peer.get_available_bytes()
@@ -163,16 +206,22 @@ func get_tcp_data(sock: SocketTCP, peer, len_rx):
func _process(_delta: float) -> void:
var tick = Time.get_ticks_msec()
for addr in units:
for addr in units_udp:
var unit = units[addr]
match unit.process(tick):
Error.OK: sock_unicast.send_to([addr[0], dst_ports[addr]], unit.tx_data)
Error.FAILED: emit_signal('socket_error', 'ошибка: %s %s:%d' % [unit, addr[0], addr[1]])
for key in units_serial:
var unit = units_serial[key]
var serial = serials[key]
match unit.process(tick):
Error.OK: serial.send_to(unit.tx_data)
Error.FAILED: emit_signal('socket_error', 'ошибка: \"%s\"' % unit.name)
for sock_unit in tcp_sockets:
var sock = sock_unit[0]
var unit = sock_unit[1]
match unit.process(tick):
Error.OK: sock.send_to(unit.tx_data)
Error.FAILED: emit_signal('socket_error', 'ошибка: %s' %unit)
Error.FAILED: emit_signal('socket_error', 'ошибка: %s' % unit)
poll_receive_tcp(sock, tick)
poll_sockets.any(func(sock): poll_receive(sock, tick))

View File

@@ -1,3 +1,4 @@
@tool
class_name rep_settings extends Node
## Параметры.
@@ -21,15 +22,15 @@ class_name rep_settings extends Node
'уарэп-яу07-3н': ['yau07tx', '10.1.1.49', [50049], false, false, 'IP-адрес ЯУ-07 прибора ПРД-Н'],
'уарэп-яу07-3к': ['yau07tx', '10.1.1.51', [50051], false, false, 'IP-адрес ЯУ-07 прибора ПРД-Н'],
# Название | Протокол | Адрес | Порт получения | Комментарий
'уарэп-5п28': ['5p28', '127.0.0.1', [50000], 'IP-адрес комплекса 5П-28'],
# Название: [ Протокол, Адрес, Порт получения, Комментарий ]
'уарэп-5п28': [ '5p28', '127.0.0.1', [50000], 'IP-адрес комплекса 5П-28'],
# Название | Протокол | Адрес | Порт получения | Порт отправки | Комментарий
'уарэп-щ3': ['udp-json-mbcs', '127.0.0.1', [48000, 44100], false, true, 'IP-адрес и порты через которые производят обмен сообщения с драйвером клиента Modbus Serial'],
# Название | Протокол | Имя порта | Скорость, бод | Чётность | Комментарий
'уарэп-спт25-1': ['uart', '/dev/tty2', 115200, false, 'Адрес прибора СПТ-25 (G1)'],
'уарэп-спт25-2': ['uart', '/dev/tty3', 115200, false, 'Адрес прибора СПТ-25 (G2)'],
# Название: [ Протокол, Адрес, [ Порт получения, Порт отправки], ??, ??, Комментарий
'уарэп-щ3': ['udp-json-mbcs', '127.0.0.1', [48000, 44100], false, true, 'IP-адрес и порты через которые производят обмен сообщения с драйвером клиента Modbus Serial'],
# Название: [ Протокол, Имя порта, Скорость, Чётность, ??, Комментарий
'уарэп-спт25-1': ['uart', '/home/sasha/dev/tty0', [19200, false, false], 'Адрес прибора СПТ-25 (G1)'],
'уарэп-спт25-2': ['uart', '/home/sasha/dev/tty4', [19200, false, false], 'Адрес прибора СПТ-25 (G2)'],
}
## Параметры цели.

View File

@@ -1,10 +1,20 @@
class_name Signaller extends Node
## Обмен сигналами между узлами. Здесь объявлены сигналы, которые используют.
## Обмен сигналами между узлами. Здесь объявлены сигналы, которые используют
## два и более узла, из разных файлов. Должен быть помещён в автозагрузку.
## Подключает обработчик к событию по его определению
func conn(sgnl: Signal, clbl: Callable): connect(sgnl.get_name(), clbl)
## Вызывает сигнал по его определению
func emmit(sgnl: Signal): emit_signal(sgnl.get_name())
## Вызывается при обнаружение ошибки последовательного порта
signal serial_error()
## Вызывается при переходе в режим [b]Работа[/b].
signal режим_работа()
@@ -60,48 +70,48 @@ signal full_screen(id: int)
## Вызывается, когда пользователь выбирает цель.[br]
## [param th_id] - Отметка цели на экране.
signal rto_threat_sel (th_id: int)
signal rto_threat_sel(th_id: int)
## Вызывается, когда пользователь нажимает на значёк цели.[br]
## [param th_id] - Отметка цели на экране.
signal bip_pressed (th_id: int)
signal bip_pressed(th_id: int)
## Вызывается, когда пользователь снимает выделение с цели.[br]
## [param th_id] - Отметка цели на экране.
signal rto_threat_unsel (th_id: int)
signal rto_threat_unsel(th_id: int)
## Вызывается, когда пользователь снимает выделение со всех целей.
signal rto_threat_unsel_all ()
signal rto_threat_unsel_all()
## Вызывается, когда пользователь выбирает помеху.[br]
## [param btn] - Нажатая кнопка помехи.
signal interfer_init (btn: PanelContainer, fs_arr: Array)
signal interfer_init(btn: PanelContainer, fs_arr: Array)
## Вызывается, когда выбраны цели для постановки помех.[br]
## [param btn] - Нажатая кнопка помехи.[br]
## [param sel_threats] - Cписок целей.
signal interfer_create (btn: PanelContainer, sel_threats: Array, fs_arr: Array)
signal interfer_create(btn: PanelContainer, sel_threats: Array, fs_arr: Array)
## Вызывается, когда создалась новая помеха.[br]
## [param ecm] - Новая помеха.[br]
signal interfer_new (ecm: interfer.Interfer)
signal interfer_new(ecm: interfer.Interfer)
## Вызывается, когда отключается действующая помеха.[br]
## [param ecm] - Новая помеха.[br]
## [param ecms] - словарь помех.[br]
## [param thrs] - словарь id помех и связанных с ними целей.[br]
signal interfer_off (ecm: interfer.Interfer, ecms: Dictionary, thrs: Dictionary)
signal interfer_off(ecm: interfer.Interfer, ecms: Dictionary, thrs: Dictionary)
## Вызывается при нажатии отключить все помехи.
signal interfer_off_all ()
signal interfer_off_all()
## Вызывается при получении внешнего целеуказания.
@@ -111,7 +121,7 @@ signal interfer_rcv(interfer_params: Array)
## Вызывается, когда отключается действующая помеха.[br]
## [param ecm] - Выбранная помеха.
signal interfer_selected (ecm: interfer.Interfer)
signal interfer_selected(ecm: interfer.Interfer)
## Вызывается, когда отключается выбираем помеху по сектору в таблице.[br]
@@ -127,3 +137,8 @@ signal map_coords_changed(lan: float, lat: float)
## Вызывается при изменении размера изображения для отображения карты.[br]
## [param mode] - Вновь установленный режим.
signal map_mode_changed(mode: int)
## Вызывается при обновлении позиции(угла) цели.[br]
signal th_aoa_update(threats: Dictionary)
signal fs_update_color(ecms:Dictionary)

32
scripts/spt25.gd Normal file
View File

@@ -0,0 +1,32 @@
class_name spt25_unit extends Node
class SPT25 extends unit.Unit:
var tx_tick: int = 0
var req_period = 3000
func _to_string() -> String: return String('СПТ-25: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
func _init(nm) -> void:
self.name = nm
tx_data.resize(8)
tx_data[0] = 0x7e # Флаги синхронизации пакета
tx_data[1] = 0 # Адрес абонента, которому предназначен пакет
tx_data[2] = 4 # Тип пакета, КОД КОМАНДЫ - Получить информацию о состоянии преобразователя
tx_data[3] = 0 # Данные
tx_data[4] = 0 # Данные
tx_data[5] = 0 # Данные
tx_data[6] = 0 # Контрольная сумма
tx_data[7] = 0x7e # Флаги синхронизации пакета
func parse(rx_data: PackedByteArray):
if not self.online:
self.online = true
emit_signal('line_changed', self)
emit_signal('data_received', rx_data)
func process(delta: float):
tick += delta
if (tick - tx_tick) > req_period:
return Error.OK
return Error.ERR_BUSY

View File

@@ -34,28 +34,20 @@ const CU_STATE: Dictionary = {
4:9, # Неисправность
}
class TCP5P28:
class TCP5P28 extends unit.Unit:
const PACK_TYPE_CMD: int = 1
const PACK_TYPE_RES: int = 2
const CMD_TYPE_STATE: int = 1
const CMD_TYPE_TH: int = 2
const CMD_TYPE_IN: int = 3
signal line_changed(unit: TCP5P28) ## Сигнал состояние связи изменилось.
signal data_received(unit: TCP5P28) ## Сигнал данные приняты.
signal command_fail(unit: TCP5P28) ## Сигнал при не выполнении команды.
signal parse_error(unit: TCP5P28, msg: String) ## Сигнал ошибки разбора сообщения.
signal get_threats(unit: TCP5P28) ## Сигнал запрос целей.
signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания.
var online: = false ## Состояние связи с источником сообщений.
var name: String ## Имя экземпляра.
var rx_tick: = 0 ## Тик время последнего приёма, мс.
var tx_data: = PackedByteArray() ## Пакет для отправки.
var tx_stack: Array ## Массив пакетов для отправки.
func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]])
func _init(nm): self.name = nm
func parse(data: PackedByteArray, now_tick: int):
rx_tick = now_tick
@@ -87,12 +79,12 @@ class TCP5P28:
func pack_threats(ths):
var data = PackedByteArray()
var data_len = 4 + len(ths) * 80 # длинна блока данных в байтах
var tick = Time.get_ticks_msec()
var tick0 = Time.get_ticks_msec()
data.resize(4)
data.encode_u16(0, 0) # Код ошибки
data.encode_u16(2, len(ths)) # Количество целей
for th in ths.values():
data.append_array(get_threats_data(th, int(tick)))
data.append_array(get_threats_data(th, int(tick0)))
var data_to_send: PackedByteArray = create_header(data_len)
data_to_send.append_array(data)
tx_stack.append(data_to_send)
@@ -131,10 +123,10 @@ class TCP5P28:
head_data.encode_u32(4, data_len) # Длинна пакета данных
return head_data
func get_threats_data(th, tick):
func get_threats_data(th, tick0):
var th_data = PackedByteArray()
th_data.resize(80) # Количество байт в массиве
th_data.encode_u64(0, tick)
th_data.encode_u64(0, tick0)
var flags: int = 0 # с 0 по 7 бит рекомендованная помеха
flags |= 0 << 8 # Флаг рекомендуемой помехи
flags |= int(th.fflags['aoa']) << 9 # Флаг доставерности пеленга
@@ -190,4 +182,3 @@ class TCP5P28:
var data_to_send: PackedByteArray = create_header(data_len)
data_to_send.append_array(data_tx)
tx_stack.append(data_to_send)

View File

@@ -51,11 +51,15 @@ func _ready() -> void:
var unit_5p28_key = repsettings.get_unit_key('уарэп-5п28')
var unit_5p28 = repnetwork.units_tcp[unit_5p28_key]
var timer_check_lost: = Timer.new()
var timer_aoa_update: = Timer.new()
add_child(timer_check_lost)
add_child(timer_aoa_update)
unit.connect('data_received', Callable(self, 'on_data_capsrpb_received').bind(threats))
unit_5p28.connect('get_threats', Callable(self, 'on_get_threats').bind(unit_5p28, threats))
timer_check_lost.connect('timeout', Callable(self, 'on_timer_check_lost').bind(repsettings.ThreatParams.time_lost, threats))
timer_check_lost.start(repsettings.ThreatParams.time_lost / 1000.0)
timer_aoa_update.connect('timeout', Callable(self, 'on_timer_aoa_update').bind(threats))
timer_aoa_update.start(0.25)
signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(threats))
signaller.connect('rto_threat_unsel', Callable(self, 'on_rto_threat_unsel').bind(threats))
signaller.connect('rto_threat_unsel_all', Callable(self, 'on_rto_threat_unsel_all').bind(threats))
@@ -74,10 +78,12 @@ func on_timer_check_lost(time_lost: int, threats: Dictionary):
call_deferred('emit_signal', 'threats_resized', threats)
func on_timer_aoa_update(threats:Dictionary):
signaller.emit_signal('th_aoa_update', threats)
## отправляет словарь целей в юнит, для запаковки и отправки в 5П28.
func on_get_threats(unit, threats): unit.pack_threats(threats)
## Снимает выделение с цели, если нажать по отметке цели.
func on_rto_threat_unsel(th_id, threats): threats[th_id].selected = false

View File

@@ -72,8 +72,9 @@ func get_string_slice(s_in: String, s_out: Array, i0: int, i1: int):
## Производит преобразование из декартовой в полярную систему координат.
func pos_calc(freq: float, aoa: float, pos0: Vector2, r0: float, r1: float, f0: float, f1: float):
var r = ((freq - f0) / (f1 - f0)) * r1 + r0
var r = remap(freq, f0, f1, r0, r1)
var aoa_rad = radians(aoa) - PI / 2.0
return Vector2(cos(aoa_rad), sin(aoa_rad)) * r + pos0

18
scripts/unit.gd Normal file
View File

@@ -0,0 +1,18 @@
class_name base_unit extends Node
## Базовый класс для управления подключаемыми устройствами
class Unit:
signal line_changed(unit) ## Вызывается при изменение состояния связи
signal command_done(unit) ## Вызывается после выполнения команды.
signal command_fail(unit) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена.
signal parse_failed(unit) ## Вызывается при обнаружении ошибки во входных данных
signal data_received(unit) ## Вызывается по приёму данных
var tick = 0.0 ## Текущее тик-время в мс.
var tx_data: = PackedByteArray() ## Буфер отправленный.
var tx_len = 0 ## Длина последнего отправленного пакета.
var online: bool
var name: String
func _init(nm) -> void: self.name = nm
func _to_string() -> String: return String('устройство: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])

View File

@@ -9,13 +9,13 @@ const BUFFER_SIZE = 2048 ## Размер буфера для приёма д
## Ячейка ЯУ-07.
class YaU07:
class YaU07 extends unit.Unit:
## Коды выполняемых команд.
enum CmdCode {
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07.
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07.
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07.
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07.
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07.
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07.
READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07.
}
@@ -28,27 +28,18 @@ class YaU07:
FAIL ## Команда не выполнена.
}
signal line_changed(unit: YaU07) ## Вызывается когда меняется состояние связи с ячейкой.
signal command_done(unit: YaU07) ## Вызывается после выполнения команды.
signal command_fail(unit: YaU07) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена.
signal parse_failed(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: = PackedByteArray() ## Буфер отправленный.
var tx_len = 0 ## Длина последнего отправленного пакета.
var isa_ports = {} ## Результат выполнения команды "читать порт".
var isa_block = {} ## Результат выполнения команды "читать массив из порта".
var online = false ## Состояние связи с ячейкой.
func _to_string() -> String: return String('яу07: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])