Files
uarep-ctl/scripts/sch3.gd
2024-11-19 16:27:08 +03:00

129 lines
6.7 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class_name sch_3 extends Node
## Модуль Прибора Щ3
const ONLINE_TIMEOUT: int = 5000 ## Время ожидания данных
const REQUEST_PERIOD: int = 1000 ## Переиод запроса, мс
## Представление прибора Щ3
class Sch3 extends unit.Unit:
var mb_addr: = 0 ## Адрес устройства Modbus.
var cmd_state: = CmdState.DONE ## Состояние выполнения текущей команды.
var tick_rx: = 0 ## Время приёма крайнего сообщения.
var tick_tx: = 0 ## Время отправки крайнего сообщения.
static var json_conv: = JSON.new()
signal resp_input(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров входов.
signal resp_holding(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения.
signal resp_write() ## Вызывается при получении подтверждения, что команда записи выполнена
signal info_received(msg: String) ## Вызывается при получении информационного сообщения.
signal except_received(msg: String) ## Вызывается при получении сообщения об исключительной ситуации.
func _init(nm: String, u: int = 0):
mb_addr = u
name = nm
## Изменяет состояние. Вызывать периодически.[br]
## [param tick] - Текущщее время в мс.[br]
## Возвращает [b]Error.OK[/b] - если данные готовы для отправки.[br]
## Возвращает [b]Error.ERR_BUSY[/b] - если данных для отправки нет.[br]
func process(tick: int) -> Error:
if online and ((tick - rx_tick) > ONLINE_TIMEOUT):
online = false
emit_signal('line_changed', self)
if cmd_state == CmdState.WAIT:
if (tick - tx_tick) > ONLINE_TIMEOUT:
cmd_state = CmdState.FAIL
emit_signal('command_fail', self)
var rc = Error.ERR_BUSY
if cmd_state == CmdState.SEND:
tx_tick = tick
cmd_state = CmdState.WAIT
rc = Error.OK
return rc
## Производит разбор принятых данных. Вызывать при приёме данных на сокете.[br]
## [param data] - Данные принятые на сокете.[br]
## [param tick] - Текущщее время в мс.[br]
func parse(data: PackedByteArray, tick: int) -> bool:
rx_tick = tick
if not online:
online = true
emit_signal('line_changed', self)
var utf8_data = data.get_string_from_utf8()
if Error.OK == json_conv.parse(utf8_data):
emit_signal('data_received', data)
var message: Dictionary = json_conv.get_data()
if message.has('code') and message.has('data'):
var rc: = true
var message_code = message['code']
var message_data = message['data']
match message_code:
'resp_holding', 'resp_input':
var addr = int(message_data[0])
var regs = message_data.slice(1)
for i in regs.size():
regs[i] = int(regs[i])
emit_signal(message_code, addr, regs)
'resp_write':
emit_signal(message_code)
'info':
var msg = message['data']
emit_signal('info_received', msg)
'exception':
var msg = message['data']
cmd_state = CmdState.FAIL
emit_signal('except_received', msg)
rc = false
_:
var msg: String = 'код команды \"%s\" - не распознан' % message_code
cmd_state = CmdState.FAIL
emit_signal('parse_failed', msg)
rc = false
if (cmd_state == CmdState.WAIT) and rc:
cmd_state = CmdState.DONE
emit_signal('command_done')
elif (cmd_state == CmdState.WAIT) and (not rc):
cmd_state = CmdState.FAIL
emit_signal('command_fail', self)
else:
var message = json_conv.get_error_message()
emit_signal('parse_failed', message)
return true
## Отправляет команду "записать в регистры".[br]
## [param addr] - Начальный адрес регистров.[br]
## [param count] - Данные для записи в регистры от начального адреса.[br]
func write(addr: int, data: Array) -> bool:
if cmd_state != CmdState.DONE: return false
var json_dict: = {'code': 'write', 'data': [addr] + data, 'unit': mb_addr}
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
tx_len = len(tx_data)
cmd_state = CmdState.SEND
return true
## Отправляет команду "читать регистры хранения".[br]
## [param addr] - Начальный адрес регистров.[br]
## [param count] - Количество регистров от начального адреса.[br]
func read_holding(addr: int, count: int = 1) -> bool:
if cmd_state != CmdState.DONE: return false
var json_dict: = {'code': 'read_holding', 'data': [addr, count], 'unit': mb_addr}
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
tx_len = len(tx_data)
cmd_state = CmdState.SEND
return true
## Отправляет команду "читать регистры входов".[br]
## [param addr] - Начальный адрес регистров.[br]
## [param count] - Количество регистров от начального адреса.[br]
func read_input(addr: int, count: int = 1) -> bool:
if cmd_state != CmdState.DONE: return false
var json_dict: = {'code': 'read_input', 'data': [addr, count], 'unit': mb_addr}
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
tx_len = len(tx_data)
cmd_state = CmdState.SEND
return true