Рефактор. Чистка от udp-json протокола на python-драйвере modbus
This commit is contained in:
@@ -8,132 +8,88 @@ extends 'res://scenes/контроль/элемент-я.gd'
|
||||
## информационного взаимодействия изделия 5П-28
|
||||
## с аппаратурой УА-РЭП на кораблях проекта 23900
|
||||
|
||||
@export var base_input_address: = 0 ## Базовый адрес регистров входов
|
||||
@export var base_holding_address: = 0 ## Базовый адрес регистров хранения
|
||||
@export var regs_input_count: = 5 ## Количество регистров входов
|
||||
@export var regs_holding_count: = 4 ## Количество регистров хранения
|
||||
@export var modbus_address: = 7 ## Адрес устройства на шине Modbus
|
||||
@export var request_period: = 0.2 ## Период в секундах отправки команд на шину Modbus
|
||||
@export var reconnect_period: = 3.0 ## Период в секундах
|
||||
@export var base_input_address: = 0 ## Базовый адрес регистров входов
|
||||
@export var base_holding_address: = 0 ## Базовый адрес регистров хранения
|
||||
@export var regs_input_count: = 5 ## Количество регистров входов
|
||||
@export var regs_holding_count: = 4 ## Количество регистров хранения
|
||||
@export var modbus_address: = 7 ## Адрес устройства на шине Modbus
|
||||
@export var request_period: = 200 ## Период в секундах отправки команд на шину Modbus
|
||||
@export var reconnect_period: = 3000 ## Период переподключения в секундах
|
||||
|
||||
var regs_input: = {} ## Регистры входные
|
||||
var regs_holding: = {} ## Регистры хранения
|
||||
var write_stack: = [] ## Стек команд для записи
|
||||
var switches_sync: = false
|
||||
var timer = Timer.new()
|
||||
var timer_reconnect = Timer.new()
|
||||
var step_fsm: = Sch3Fsm.CONNECT
|
||||
var regs_input: = {} ## Регистры входные
|
||||
var regs_holding: = {} ## Регистры хранения
|
||||
var switches_sync: = false ## Флаг. Если установлен, то можно переключать
|
||||
|
||||
|
||||
enum Sch3Fsm {
|
||||
READ_INPUT,
|
||||
READ_HOLDING,
|
||||
WRITE,
|
||||
CONNECT }
|
||||
func on_error(msg): push_error(msg)
|
||||
|
||||
|
||||
class StackItem:
|
||||
var addr: = 0
|
||||
var data = null
|
||||
func _init(a: int, d): addr = a; data = d
|
||||
func _to_string() -> String: return '%s: %s' % [addr, data]
|
||||
|
||||
|
||||
func on_data_received(_data: PackedByteArray): pass
|
||||
|
||||
|
||||
func _on_timeout(unit_sch3, mbc: ModbusClientRtu) -> void:
|
||||
push_warning(step_fsm)
|
||||
if step_fsm == Sch3Fsm.WRITE:
|
||||
timer.wait_time = request_period
|
||||
if write_stack.size():
|
||||
var ad = write_stack.pop_front()
|
||||
mbc.write(ad.addr, ad.data)
|
||||
step_fsm = Sch3Fsm.READ_INPUT
|
||||
elif step_fsm == Sch3Fsm.READ_INPUT:
|
||||
unit_sch3.read_input(base_input_address, regs_input_count)
|
||||
elif step_fsm == Sch3Fsm.READ_HOLDING:
|
||||
unit_sch3.read_holding(base_holding_address, regs_holding_count)
|
||||
elif step_fsm == Sch3Fsm.CONNECT:
|
||||
timer.wait_time = reconnect_period
|
||||
mbc.queue_clear()
|
||||
mbc.flush()
|
||||
mbc.try_reconnect()
|
||||
mbc.request_read(base_input_address, regs_input_count)
|
||||
## Вызывается, когда состояния прибора Щ3 "на связи" изменяется[br]
|
||||
## [param unit_sch3] - Экземпляр представления прибора Щ3
|
||||
func on_line_changed_sch3(online: bool):
|
||||
for item in get_tree().get_nodes_in_group('bits_items_good'):
|
||||
item.texture = textures[STATE_VAL.NONE]
|
||||
if not online:
|
||||
for item in get_tree().get_nodes_in_group('bits_items_switch'):
|
||||
item.disabled = true
|
||||
regs_holding.clear()
|
||||
regs_input.clear()
|
||||
switches_sync = false
|
||||
$margin/vbox/grid1/lbl_freq.text = '<нет данных>'
|
||||
$margin/vbox/grid1/state_freq.texture = textures[STATE_VAL.NONE]
|
||||
$margin/vbox/grid/state.texture = textures[STATE_VAL.NONE]
|
||||
|
||||
|
||||
## Вызывается при изменении состояния выключателя[br]
|
||||
## [param val] - Состояние выключателя[br]
|
||||
## [param meta] - Адреса регистров и индексы битов назначенных выключателю[br]
|
||||
func on_toggled_switch(val: bool, meta: Array):
|
||||
func on_toggled_switch(val: bool, meta: Array, unit_sch3):
|
||||
var on_addr = meta[0]
|
||||
var on_bit = meta[1]
|
||||
var off_addr = meta[2]
|
||||
var off_bit = meta[3]
|
||||
if regs_holding.has(on_addr) and regs_holding.has(off_addr):
|
||||
regs_holding[on_addr] = tools.set_bit(regs_holding[on_addr], on_bit, val)
|
||||
regs_holding[on_addr] = tools.set_bit(regs_holding[on_addr], on_bit, val)
|
||||
regs_holding[off_addr] = tools.set_bit(regs_holding[off_addr], off_bit, not val)
|
||||
push_write_holding()
|
||||
unit_sch3.push_write_holding(regs_holding)
|
||||
|
||||
|
||||
## Заносит в очередь команду чтения регистров хранения
|
||||
func push_write_holding():
|
||||
var regs_data: = []
|
||||
var keys = regs_holding.keys()
|
||||
keys.sort() # Ключи в словаре хранятся не упорядочено
|
||||
for addr in keys:
|
||||
regs_data.append(regs_holding[addr])
|
||||
write_stack.push_back(StackItem.new(keys[0], regs_data))
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
func _enter_tree() -> void:
|
||||
super._enter_tree()
|
||||
if Engine.is_editor_hint(): return
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
var unit_sch3 = network.units[unit_key]
|
||||
unit_sch3.mb_addr = modbus_address
|
||||
var items = get_tree().get_nodes_in_group('bits_items_switch')
|
||||
for item in items:
|
||||
var meta = item.get_meta('bits')
|
||||
item.connect('toggled', on_toggled_switch.bind(meta))
|
||||
item.connect('toggled', on_toggled_switch.bind(meta, unit_sch3))
|
||||
item.disabled = true
|
||||
unit_sch3.connect('resp_input', on_resp_input)
|
||||
unit_sch3.connect('resp_holding', on_resp_holding)
|
||||
unit_sch3.connect('command_fail', on_command_fail)
|
||||
var mbc = network.mbcs[unit_key]
|
||||
timer.connect('timeout', _on_timeout.bind(unit_sch3, mbc))
|
||||
add_child(timer)
|
||||
timer.start(request_period)
|
||||
unit_sch3.base_holding_address = base_holding_address
|
||||
unit_sch3.regs_holding_count = regs_holding_count
|
||||
unit_sch3.base_input_address = base_input_address
|
||||
unit_sch3.regs_input_count = regs_input_count
|
||||
unit_sch3.request_period = request_period
|
||||
unit_sch3.reconnect_period = reconnect_period
|
||||
unit_sch3.connect('read', on_read.bind(unit_sch3))
|
||||
unit_sch3.connect('read_input', on_input)
|
||||
unit_sch3.connect('error', on_error)
|
||||
unit_sch3.connect('line_changed', on_line_changed_sch3)
|
||||
|
||||
|
||||
func on_command_fail(unit_sch3):
|
||||
unit_sch3.cmd_state = unit.Unit.CmdState.DONE
|
||||
|
||||
|
||||
## Вызывается, когда состояния прибора Щ3 "на связи" изменяется[br]
|
||||
## [param unit_sch3] - Экземпляр представления прибора Щ3
|
||||
func on_line_changed(unit_sch3: sch_3.Sch3):
|
||||
for item in get_tree().get_nodes_in_group('bits_items_good'):
|
||||
item.texture = textures[STATE_VAL.NONE]
|
||||
if not unit_sch3.online:
|
||||
for item in get_tree().get_nodes_in_group('bits_items_switch'):
|
||||
item.disabled = true
|
||||
regs_holding.clear()
|
||||
regs_input.clear()
|
||||
write_stack.clear()
|
||||
switches_sync = false
|
||||
$margin/vbox/grid1/lbl_freq.text = '<нет данных>'
|
||||
$margin/vbox/grid1/state_freq.texture = textures[STATE_VAL.NONE]
|
||||
$margin/vbox/grid/state.texture = textures[STATE_VAL.NONE]
|
||||
step_fsm = Sch3Fsm.CONNECT
|
||||
else:
|
||||
timer.wait_time = request_period
|
||||
func _exit_tree() -> void:
|
||||
if Engine.is_editor_hint(): return
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
var unit_sch3 = network.units[unit_key]
|
||||
unit_sch3.disconnect('read', on_read.bind(unit_sch3))
|
||||
unit_sch3.disconnect('read_input', on_input.bind(unit_sch3))
|
||||
unit_sch3.disconnect('error', on_error)
|
||||
unit_sch3.disconnect('line_changed', on_line_changed_sch3)
|
||||
|
||||
|
||||
## Вызывается по сигналу "приняты данные чтения регистров хранения"[br]
|
||||
## [param base_addr] - Начальный адрес регистров.[br]
|
||||
## [param data] - Массив значений прочитанных из регистров.
|
||||
func on_resp_holding(base_addr: int, data: Array):
|
||||
step_fsm = Sch3Fsm.WRITE
|
||||
func on_read(base_addr: int, data: Array, unit_sch3):
|
||||
if (base_addr != base_holding_address) or (data.size() < regs_holding_count):
|
||||
return
|
||||
for i in data.size():
|
||||
@@ -151,14 +107,13 @@ func on_resp_holding(base_addr: int, data: Array):
|
||||
item.button_pressed = val0
|
||||
item.disabled = false
|
||||
regs_holding[byte1] = tools.set_bit(regs_holding[byte1], bit1, not val0)
|
||||
push_write_holding()
|
||||
unit_sch3.push_write_holding(regs_holding)
|
||||
|
||||
|
||||
## Вызывается по сигналу "приняты данные чтения регистров входов".[br]
|
||||
## [param base_addr] - Начальный адрес регистров.[br]
|
||||
## [param data] - Массив значений прочитанных из регистров.[br]
|
||||
func on_resp_input(base_addr: int, data: Array):
|
||||
step_fsm = Sch3Fsm.READ_HOLDING
|
||||
func on_input(base_addr: int, data: Array):
|
||||
if !is_inside_tree():
|
||||
return
|
||||
if (base_addr != base_input_address) or (data.size() < regs_input_count):
|
||||
|
||||
@@ -48,32 +48,6 @@ class SocketTCP extends TCPServer:
|
||||
peer.put_data(data)
|
||||
|
||||
|
||||
class Modbus extends ModbusClientRtu:
|
||||
var unit_name
|
||||
func send_to(data):
|
||||
if data['code'] == 'write':
|
||||
var addr = data['data'].pop_at(0)
|
||||
request_write(addr, data['data'])
|
||||
elif data['code'] == 'read_holding':
|
||||
request_read(data['data'][0], data['data'][1])
|
||||
elif data['code'] == 'read_input':
|
||||
request_read_input(data['data'][0], data['data'][1])
|
||||
|
||||
func try_reconnect():
|
||||
var port = settings.UnitProfiles[unit_name][1]
|
||||
var params = settings.UnitProfiles[unit_name][2]
|
||||
thread_stop()
|
||||
close()
|
||||
var rc = open(port, params[0], params[1], params[2], params[3], params[4])
|
||||
if rc != Error.OK:
|
||||
push_error('%s:%s %s' % [unit_name, port, params])
|
||||
return false
|
||||
set_response_timeout(params[5])
|
||||
set_indication_timeout(params[5])
|
||||
thread_run()
|
||||
return true
|
||||
|
||||
|
||||
var poll_sockets: Array[Socket]
|
||||
var tcp_sockets: Array
|
||||
var units: Dictionary
|
||||
@@ -127,15 +101,9 @@ func create_serial(nm) -> Serial:
|
||||
return sp
|
||||
|
||||
|
||||
func create_modbus(nm, mbc_unit) -> Modbus:
|
||||
var mbc: = Modbus.new()
|
||||
mbc.connect('read', mbc_unit.on_read)
|
||||
mbc.connect('read_input', mbc_unit.on_read_input)
|
||||
mbc.connect('write', mbc_unit.on_write)
|
||||
mbc.unit_name = nm
|
||||
mbc.try_reconnect()
|
||||
mbc.thread_run()
|
||||
return mbc
|
||||
func create_modbus(nm) -> sch_3.Sch3:
|
||||
var unit_sch3: = sch_3.Sch3.new(nm)
|
||||
return unit_sch3
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -193,10 +161,8 @@ func _ready() -> void:
|
||||
if logger_page:
|
||||
unit_modbus.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
unit_modbus.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
|
||||
var mbc = create_modbus(unit_name, unit_modbus)
|
||||
units_modbus[unit_key] = unit_modbus
|
||||
units[unit_key] = unit_modbus
|
||||
mbcs[unit_key] = mbc
|
||||
|
||||
if proto in SERIAL_PROTO:
|
||||
var unit_serial = SERIAL_PROTO[proto].new(unit_name)
|
||||
@@ -299,10 +265,7 @@ func _process(_delta: float) -> void:
|
||||
Error.FAILED: emit_signal('socket_error', [unit_serial, serial])
|
||||
for key in units_modbus:
|
||||
var unit_modbus = units_modbus[key]
|
||||
var mbc = mbcs[key]
|
||||
match unit_modbus.process(tick):
|
||||
Error.OK: mbc.send_to(unit_modbus.mb_data)
|
||||
Error.FAILED: emit_signal('socket_error', [unit_modbus, mbc])
|
||||
unit_modbus.process(tick)
|
||||
for sock_unit in tcp_sockets:
|
||||
var sock = sock_unit[0]
|
||||
var unit_tcp = sock_unit[1]
|
||||
|
||||
242
scripts/sch3.gd
242
scripts/sch3.gd
@@ -1,162 +1,148 @@
|
||||
class_name sch_3 extends Node
|
||||
|
||||
## Модуль Прибора Щ3
|
||||
|
||||
const ONLINE_TIMEOUT: int = 5000 ## Время ожидания данных
|
||||
const REQUEST_PERIOD: int = 1000 ## Переиод запроса, мс
|
||||
const ONLINE_TIMEOUT = 5000
|
||||
|
||||
|
||||
## Представление прибора Щ3
|
||||
class Sch3 extends unit.Unit:
|
||||
enum Sch3Fsm {
|
||||
READ_INPUT,
|
||||
READ_HOLDING,
|
||||
WRITE,
|
||||
CONNECT }
|
||||
|
||||
var mb_addr: = 0 ## Адрес устройства Modbus.
|
||||
var cmd_state: = CmdState.DONE ## Состояние выполнения текущей команды.
|
||||
var mb_data: Dictionary = {} ## Буфер для записи в регистры модбас
|
||||
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
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
## Изменяет состояние. Вызывать периодически.[br]
|
||||
|
||||
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 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
|
||||
if online:
|
||||
if (tick - rx_tick) > ONLINE_TIMEOUT:
|
||||
online = false
|
||||
if cmd_state == CmdState.WAIT:
|
||||
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
|
||||
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]
|
||||
## [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)
|
||||
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]
|
||||
## [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)
|
||||
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]
|
||||
## [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)
|
||||
func on_write(return_code: Error, base_addr: int, data: Array):
|
||||
parse(return_code, base_addr, data, 'write')
|
||||
|
||||
Reference in New Issue
Block a user