Files
uarep-ctl/scripts/sch3.gd

163 lines
8.2 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 mb_data: Dictionary = {} ## Буфер для записи в регистры модбас
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(message: Dictionary) -> bool:
if not online and (message['code'] != 'exception'):
online = true
emit_signal('line_changed', self)
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':
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)
return true
## Отправляет команду "записать в регистры".[br]
## [param addr] - Начальный адрес регистров.[br]
## [param count] - Данные для записи в регистры от начального адреса.[br]
func write(addr: int, data: Array) -> bool:
if cmd_state != CmdState.DONE: return false
mb_data = {'code': 'write', 'data': [addr] + data, 'unit': mb_addr}
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
mb_data = {'code': 'read_holding', 'data': [addr, count], 'unit': mb_addr}
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
mb_data = {'code': 'read_input', 'data': [addr, count], 'unit': mb_addr}
cmd_state = CmdState.SEND
return true
## Принимает результат команды "читать регистры хранения".[br]
## [param return_code] - Код выполнения команды.[br]
## [param base_addr] - Начальный адрес регистров.[br]
## [param data] - Данные прочитанные из регистров.[br]
## [param tick] - Время приёма пакета.[br]
func on_read(return_code, base_addr, data):
var msg: Dictionary
if return_code == Error.OK:
rx_tick = Time.get_ticks_msec()
msg['code'] = 'resp_holding'
msg['data'] = [base_addr] + data
else:
msg['code'] = 'exception'
msg['data'] = 'операция чтения входных регистров не выполнена (%d)' % base_addr
parse(msg)
## Принимает результат команды "читать регистры входов".[br]
## [param return_code] - Код выполнения команды.[br]
## [param base_addr] - Начальный адрес регистров.[br]
## [param data] - Данные прочитанные из регистров.[br]
## [param tick] - Время приёма пакета.[br]
func on_read_input(return_code, base_addr, data):
var msg: Dictionary
if return_code == Error.OK:
rx_tick = Time.get_ticks_msec()
msg['code'] = 'resp_input'
msg['data'] = [base_addr] + data
else:
msg['code'] = 'exception'
msg['data'] = 'операция чтения входных регистров не выполнена (%d)' % base_addr
parse(msg)
## Принимает результат команды "записать в регистры".[br]
## [param return_code] - Код выполнения команды.[br]
## [param base_addr] - Начальный адрес регистров.[br]
## [param data] - Данные прочитанные из регистров.[br]
## [param tick] - Время приёма пакета.[br]
func on_write(return_code, base_addr, data):
var msg: Dictionary
if return_code == Error.OK:
rx_tick = Time.get_ticks_msec()
msg['data'] = []
msg['code'] = 'resp_write'
else:
msg['data'] = 'операция записи в регистры не выполнена (%d, %s)' % [base_addr, data]
msg['code'] = 'except_received'
parse(msg)