Доработка. Улучшение документации.

This commit is contained in:
lepshiy
2024-07-25 16:10:22 +03:00
parent bae7a949e4
commit d826f8745c
47 changed files with 3607 additions and 3507 deletions

View File

@@ -1,6 +1,6 @@
extends Node
class_name yau_07 extends Node
## Протокол ячейки ЯУ-07
## Протокол ячейки ЯУ-07.
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды
const RESEND_TIMEOUT = 0.3 ## Задержка для повторной отправки команды, секунды
@@ -8,242 +8,242 @@ const RETRY_COUNT = 5 ## Количество повторных отпр
const BUFFER_SIZE = 2048 ## Размер буфера для приёма датаграмм
## Ячейка ЯУ-07
## Ячейка ЯУ-07.
class YaU07:
## Коды выполняемых команд
enum CmdCode {
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07
READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07
}
## Коды выполняемых команд.
enum CmdCode {
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07.
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07.
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07.
READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07.
}
## Состояние автомата выполнения команды
enum CmdState {
UNCK, ## Номер команды не ининциирован
SEND, ## Буфер готов для отправки
WAIT, ## Ожидание выполнения
DONE, ## Команда выполнена
FAIL ## Команда не выполнена
}
## Состояние автомата выполнения команды.
enum CmdState {
UNCK, ## Номер команды не ининциирован.
SEND, ## Буфер готов для отправки.
WAIT, ## Ожидание выполнения.
DONE, ## Команда выполнена.
FAIL ## Команда не выполнена.
}
signal line_changed(unit: YaU07) ## Вызывается когда меняется состояние связи с ячейкой
signal command_done(unit: YaU07) ## Вызывается после выполнения команды
signal command_fail(unit: YaU07) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена
signal parse_failed(unit: YaU07)
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 ## Состояние связи с ячейкой
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)]])
func _to_string() -> String: return String('яу07: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
func _init(nm):
self.name = nm
tx_data.resize(BUFFER_SIZE)
tx_data.fill(0)
tick = 0.0
func _init(nm):
self.name = nm
tx_data.resize(BUFFER_SIZE)
tx_data.fill(0)
tick = 0.0
func process(delta: float):
tick += delta
if online and ((tick - cmd_tick_rx) > ONLINE_TIMEOUT):
online = false
emit_signal('line_changed', self)
func process(delta: float):
tick += delta
if online and ((tick - cmd_tick_rx) > ONLINE_TIMEOUT):
online = false
emit_signal('line_changed', self)
var rc = Error.ERR_BUSY
if cmd_state == CmdState.SEND:
rc = Error.OK
cmd_tick_tx = tick
cmd_state = CmdState.WAIT
cmd_retry = RETRY_COUNT
elif cmd_state == CmdState.WAIT:
if cmd_retry:
if (tick - cmd_tick_tx) > RESEND_TIMEOUT:
rc = Error.OK
cmd_tick_tx = tick
cmd_retry -= 1
else:
cmd_state = CmdState.FAIL
emit_signal('command_fail', self)
rc = Error.FAILED
return rc
var rc = Error.ERR_BUSY
if cmd_state == CmdState.SEND:
rc = Error.OK
cmd_tick_tx = tick
cmd_state = CmdState.WAIT
cmd_retry = RETRY_COUNT
elif cmd_state == CmdState.WAIT:
if cmd_retry:
if (tick - cmd_tick_tx) > RESEND_TIMEOUT:
rc = Error.OK
cmd_tick_tx = tick
cmd_retry -= 1
else:
cmd_state = CmdState.FAIL
emit_signal('command_fail', self)
rc = Error.FAILED
return rc
func send_isa(cmd_code: int, ports_data: Array) -> bool:
if (cmd_state == CmdState.WAIT) \
or (cmd_state == CmdState.SEND) \
or (cmd_state == CmdState.UNCK):
return false
if not ((cmd_code == CmdCode.READ_ISA) or (cmd_code == CmdCode.WRITE_ISA)):
return false
func send_isa(cmd_code: int, ports_data: Array) -> bool:
if (cmd_state == CmdState.WAIT) \
or (cmd_state == CmdState.SEND) \
or (cmd_state == CmdState.UNCK):
return false
if not ((cmd_code == CmdCode.READ_ISA) or (cmd_code == CmdCode.WRITE_ISA)):
return false
cmd_num_tx = (cmd_num_rx + 1) % 0xffff
cmd_num_tx = (cmd_num_rx + 1) % 0xffff
var ports_count = ports_data.size()
tx_len = ports_count * 2 + 8
tx_data.encode_u16(0, cmd_retry) # Исправление для сетевого стека "nm-callback" процессоров STM
tx_data.encode_u16(2, cmd_num_tx)
var ports_count = ports_data.size()
tx_len = ports_count * 2 + 8
tx_data.encode_u16(0, cmd_retry) # Исправление для сетевого стека "nm-callback" процессоров STM
tx_data.encode_u16(2, cmd_num_tx)
if cmd_code == CmdCode.WRITE_ISA:
ports_count /= 2
tx_data[6] = cmd_code
tx_data[7] = ports_count
if cmd_code == CmdCode.WRITE_ISA:
ports_count /= 2
tx_data[6] = cmd_code
tx_data[7] = ports_count
var i: = 0
for word in ports_data:
tx_data.encode_u16(8 + i, word)
i += 2
cmd_state = CmdState.SEND
return true
var i: = 0
for word in ports_data:
tx_data.encode_u16(8 + i, word)
i += 2
cmd_state = CmdState.SEND
return true
func send_block(cmd_code: int, block_len: int, port: Array) -> bool:
if (cmd_state == CmdState.WAIT) \
or (cmd_state == CmdState.SEND) \
or (cmd_state == CmdState.UNCK):
return false
if not ((cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK)):
return false
func send_block(cmd_code: int, block_len: int, port: Array) -> bool:
if (cmd_state == CmdState.WAIT) \
or (cmd_state == CmdState.SEND) \
or (cmd_state == CmdState.UNCK):
return false
if not ((cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK)):
return false
cmd_num_tx = (cmd_num_rx + 1) % 0xffff
cmd_num_tx = (cmd_num_rx + 1) % 0xffff
tx_len = 11
tx_data.encode_u16(0, cmd_retry) # Исправление для сетевого стека "nm-callback" процессоров STM
tx_data.encode_u16(2, cmd_num_tx)
tx_len = 11
tx_data.encode_u16(0, cmd_retry) # Исправление для сетевого стека "nm-callback" процессоров STM
tx_data.encode_u16(2, cmd_num_tx)
if cmd_code == CmdCode.WRITE_BLOCK:
block_len /= 2
tx_data[6] = cmd_code
tx_data.encode_u16(7, block_len)
if cmd_code == CmdCode.WRITE_BLOCK:
block_len /= 2
tx_data[6] = cmd_code
tx_data.encode_u16(7, block_len)
tx_data.encode_u16(9, int(port[0]))
cmd_state = CmdState.SEND
return true
## Возвращает код команды ЯУ-07
## rx_data - Принятые данные
## Возвращает - Код команды не найден, 0...255 - код команды
func get_cmd_code(rx_data: PackedByteArray):
tx_data.encode_u16(9, int(port[0]))
cmd_state = CmdState.SEND
return true
## Возвращает код команды ЯУ-07.
## rx_data - Принятые данные.
## Возвращает - Код команды не найден, 0...255 - код команды.
func get_cmd_code(rx_data: PackedByteArray):
var rx_data_len = rx_data.size()
if rx_data_len < 7:
return null
var status_len = rx_data.decode_u16(6) # Длина массива байтового "состояние прибора"
if rx_data_len <= (status_len + 6): # Нет поля "ответ на команду", разбор пакета завершить
return null
var cmd_code_pos = status_len + 8 # Положение в приёмном буфере "кода команды"
if rx_data_len <= cmd_code_pos:
return null
return rx_data[cmd_code_pos] # "код команды"
var rx_data_len = rx_data.size()
if rx_data_len < 7:
return null
var status_len = rx_data.decode_u16(6) # Длина массива байтового "состояние прибора"
if rx_data_len <= (status_len + 6): # Нет поля "ответ на команду", разбор пакета завершить
return null
var cmd_code_pos = status_len + 8 # Положение в приёмном буфере "кода команды"
if rx_data_len <= cmd_code_pos:
return null
return rx_data[cmd_code_pos] # "код команды"
func parse_isa(rx_data: PackedByteArray, status_len) -> bool:
var ports_count_pos = status_len + 10 # Положение в приёмном буфере количества портов
if rx_data.size() < ports_count_pos:
return false
var ports_count = rx_data[ports_count_pos] # Количество портов
var counted_len = status_len + (ports_count * 4) + 11 # Вычисленная длина пакета
if rx_data.size() < counted_len:
return false
var addr_pos = status_len + 11 # Смещение положения адреса в приёмном буфере
var data_pos = status_len + 13 # Смещение положения данных в приёмном буфере
var i: = 0
while i < ports_count:
var shift: = i * 4
var isa_addr = rx_data.decode_u16(addr_pos + shift) # Адрес порта ISA яу-07
var isa_data = rx_data.decode_u16(data_pos + shift) # Данные порта ISA яу-07
isa_ports[isa_addr] = isa_data
i += 1
cmd_data = rx_data.slice(addr_pos, (addr_pos + ports_count * 4) - 1)
return i > 0
func parse_isa(rx_data: PackedByteArray, status_len) -> bool:
var ports_count_pos = status_len + 10 # Положение в приёмном буфере количества портов
if rx_data.size() < ports_count_pos:
return false
var ports_count = rx_data[ports_count_pos] # Количество портов
var counted_len = status_len + (ports_count * 4) + 11 # Вычисленная длина пакета
if rx_data.size() < counted_len:
return false
var addr_pos = status_len + 11 # Смещение положения адреса в приёмном буфере
var data_pos = status_len + 13 # Смещение положения данных в приёмном буфере
var i: = 0
while i < ports_count:
var shift: = i * 4
var isa_addr = rx_data.decode_u16(addr_pos + shift) # Адрес порта ISA яу-07
var isa_data = rx_data.decode_u16(data_pos + shift) # Данные порта ISA яу-07
isa_ports[isa_addr] = isa_data
i += 1
cmd_data = rx_data.slice(addr_pos, (addr_pos + ports_count * 4) - 1)
return i > 0
func parse_block(rx_data: PackedByteArray, status_len) -> bool:
var ports_count_pos = status_len + 7 # Положение в приёмном буфере количества портов
if rx_data.size() < ports_count_pos:
return false
var block_len = rx_data.decode_u16(ports_count_pos + 3)
var block_adr = rx_data.decode_u16(ports_count_pos + 5)
var block_data = []
for i in block_len:
var shift: int = i * 2
block_data.append(rx_data.decode_u16(ports_count_pos + 7 + shift))
isa_block[block_adr] = block_data
return true
func parse_block(rx_data: PackedByteArray, status_len) -> bool:
var ports_count_pos = status_len + 7 # Положение в приёмном буфере количества портов
if rx_data.size() < ports_count_pos:
return false
var block_len = rx_data.decode_u16(ports_count_pos + 3)
var block_adr = rx_data.decode_u16(ports_count_pos + 5)
var block_data = []
for i in block_len:
var shift: int = i * 2
block_data.append(rx_data.decode_u16(ports_count_pos + 7 + shift))
isa_block[block_adr] = block_data
return true
## Заполняет состояние прибора данными прочитанными из портов ЯУ-07
## для команд "читать порты" или "записать порты"[br]
## [param rx_data] - Принятые данные[br]
## Возвращает [b]true[/b] - Данные обработаны успешно[br]
## Возвращает [b]false[/b] - Данные не обработаны из за ошибки[br]
func parse(rx_data: PackedByteArray) -> bool:
## Заполняет состояние прибора данными прочитанными из портов ЯУ-07.
## для команд "читать порты" или "записать порты".[br]
## [param rx_data] - Принятые данные.[br]
## Возвращает [b]true[/b] - Данные обработаны успешно.[br]
## Возвращает [b]false[/b] - Данные не обработаны из за ошибки.[br]
func parse(rx_data: PackedByteArray) -> bool:
cmd_tick_rx = tick
cmd_tick_rx = tick
if not online:
online = true
emit_signal('line_changed', self)
if not online:
online = true
emit_signal('line_changed', self)
var rx_data_len = rx_data.size()
if rx_data_len < 10:
return false
var rx_data_len = rx_data.size()
if rx_data_len < 10:
return false
cmd_num_rx = rx_data.decode_u16(2)
if cmd_state == CmdState.UNCK:
cmd_state = CmdState.DONE
cmd_num_rx = rx_data.decode_u16(2)
if cmd_state == CmdState.UNCK:
cmd_state = CmdState.DONE
var status_len = rx_data.decode_u16(6) # Длина массива байтового "состояние прибора"
if rx_data_len < (status_len + 6):
return false
var i: = 0
var len_rx_data: = rx_data.size()
status.resize(status_len)
while i < status_len:
var byte_i = i + 8
if byte_i < len_rx_data:
status[i] = rx_data[byte_i] # Массив байтовый "состояние прибора"
i += 1
var status_len = rx_data.decode_u16(6) # Длина массива байтового "состояние прибора"
if rx_data_len < (status_len + 6):
return false
var i: = 0
var len_rx_data: = rx_data.size()
status.resize(status_len)
while i < status_len:
var byte_i = i + 8
if byte_i < len_rx_data:
status[i] = rx_data[byte_i] # Массив байтовый "состояние прибора"
i += 1
if rx_data_len == (status_len + 6):
return true # Нет поля "ответ на команду", разбор пакета завершить
if rx_data_len == (status_len + 6):
return true # Нет поля "ответ на команду", разбор пакета завершить
var cmd_code_pos = status_len + 8 # Положение в приёмном буфере "код команды"
if rx_data_len <= cmd_code_pos:
return false
var cmd_code_pos = status_len + 8 # Положение в приёмном буфере "код команды"
if rx_data_len <= cmd_code_pos:
return false
var cmd_status_pos = status_len + 9 # Положение в приёмном буфере "состояния выполнения команды"
if rx_data_len <= cmd_status_pos:
return false
cmd_result = rx_data[cmd_status_pos]
if cmd_result != 1: # Команда не выполнена
return false
var cmd_status_pos = status_len + 9 # Положение в приёмном буфере "состояния выполнения команды"
if rx_data_len <= cmd_status_pos:
return false
cmd_result = rx_data[cmd_status_pos]
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: 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)
elif (cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK):
rc = parse_block(rx_data, status_len)
elif (cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK):
rc = parse_block(rx_data, status_len)
if rc:
if (cmd_state == CmdState.WAIT) and (cmd_num_rx == cmd_num_tx):
cmd_state = CmdState.DONE
emit_signal('command_done', self)
else:
emit_signal('parse_failed', self)
return true
if rc:
if (cmd_state == CmdState.WAIT) and (cmd_num_rx == cmd_num_tx):
cmd_state = CmdState.DONE
emit_signal('command_done', self)
else:
emit_signal('parse_failed', self)
return true