Files
uarep-ctl/scripts/sch3.gd

149 lines
6.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
const ONLINE_TIMEOUT = 5000
## Представление прибора Щ3
class Sch3 extends unit.Unit:
enum Sch3Fsm {
READ_INPUT,
READ_HOLDING,
WRITE,
CONNECT }
var step_fsm: Sch3Fsm = Sch3Fsm.CONNECT
var base_input_address: int = 0
var regs_input_count: int = 0
var base_holding_address: int = 0
var regs_holding_count: int = 0
var request_period: int = 300
var reconnect_period: int = ONLINE_TIMEOUT
var write_stack: Array
var tick_fsm: int = 0
var mbc: = ModbusClientRtu.new()
var tick_fsm_delta: = reconnect_period
func try_connect() -> bool:
var port = settings.UnitProfiles[name][1]
var params = settings.UnitProfiles[name][2]
mbc.thread_stop()
mbc.queue_clear()
mbc.flush()
mbc.close()
var rc = mbc.open(port, params[0], params[1], params[2], params[3], params[4])
if rc != Error.OK:
push_error('%s:%s %s' % [name, port, params])
return false
mbc.set_response_timeout(params[5])
mbc.thread_run()
return true
func push_write_holding(regs: Dictionary):
var keys = regs.keys()
keys.sort()
var data: = []
for k in keys:
data.append(regs[k])
write_stack.append([keys[0], data])
func _on_timeout(tick: int) -> void:
push_warning(tick_fsm_delta)
if step_fsm == Sch3Fsm.WRITE:
while write_stack.size():
var write_command = write_stack.pop_front()
mbc.request_write(write_command[0], write_command[1])
cmd_state = CmdState.WAIT
tx_tick = tick
step_fsm = Sch3Fsm.READ_INPUT
elif step_fsm == Sch3Fsm.READ_INPUT:
mbc.request_read_input(base_input_address, regs_input_count)
cmd_state = CmdState.WAIT
tx_tick = tick
step_fsm = Sch3Fsm.READ_HOLDING
elif step_fsm == Sch3Fsm.READ_HOLDING:
mbc.request_read(base_holding_address, regs_holding_count)
cmd_state = CmdState.WAIT
tx_tick = tick
step_fsm = Sch3Fsm.WRITE
elif step_fsm == Sch3Fsm.CONNECT:
try_connect()
mbc.request_read(base_input_address, regs_input_count)
cmd_state = CmdState.WAIT
tx_tick = tick
signal write (addr: int, data: Array) ## Вызывается при получении сообщения подтверждения записи
signal read (addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров входов.
signal read_input (addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения.
signal error(msg: String) ## Вызывается при получении сообщения об исключительной ситуации.
func _init(nm: String):
name = nm
mbc.connect('read', on_read)
mbc.connect('read_input', on_read_input)
mbc.connect('write', on_write)
func parse(return_code: Error, base_addr: int, data: Array, code: String):
if return_code == Error.OK:
rx_tick = Time.get_ticks_msec()
if cmd_state == CmdState.WAIT:
cmd_state = CmdState.DONE
emit_signal(code, base_addr, data)
if not online:
online = true
emit_signal('line_changed', online)
step_fsm = Sch3Fsm.WRITE
tick_fsm_delta = request_period
else:
if cmd_state == CmdState.WAIT:
cmd_state = CmdState.FAIL
emit_signal('error', [code, return_code, base_addr, data])
## Изменяет состояние. Вызывается периодически.[br]
## [param tick] - Текущщее время в мс.[br]
## Возвращает [b]Error.OK[/b] - если данные готовы для отправки.[br]
## Возвращает [b]Error.ERR_BUSY[/b] - если данных для отправки нет.[br]
func process(tick: int) -> Error:
if online:
if (tick - rx_tick) > ONLINE_TIMEOUT:
online = false
if cmd_state == CmdState.WAIT:
cmd_state = CmdState.FAIL
emit_signal('command_fail', name)
emit_signal('line_changed', online)
step_fsm = Sch3Fsm.CONNECT
tick_fsm_delta = reconnect_period
if (tick - tick_fsm) > tick_fsm_delta:
tick_fsm = tick
_on_timeout(tick)
return Error.ERR_BUSY
## Принимает результат команды "читать регистры хранения".[br]
## [param return_code] - Код выполнения команды.[br]
## [param base_addr] - Начальный адрес регистров.[br]
## [param data] - Данные прочитанные из регистров.[br]
func on_read(return_code: Error, base_addr: int, data: Array):
parse(return_code, base_addr, data, 'read')
## Принимает результат команды "читать регистры входов".[br]
## [param return_code] - Код выполнения команды.[br]
## [param base_addr] - Начальный адрес регистров.[br]
## [param data] - Данные прочитанные из регистров.[br]
func on_read_input(return_code: Error, base_addr: int, data: Array):
parse(return_code, base_addr, data, 'read_input')
## Принимает результат команды "записать в регистры".[br]
## [param return_code] - Код выполнения команды.[br]
## [param base_addr] - Начальный адрес регистров.[br]
## [param data] - Данные прочитанные из регистров.[br]
func on_write(return_code: Error, base_addr: int, data: Array):
parse(return_code, base_addr, data, 'write')