Доработка. Добавлен класс для работы с Modbus
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
extends Node
|
||||
|
||||
|
||||
class ModbusClient:
|
||||
var name: String
|
||||
signal command_done(unit: ModbusClient) ## Вызывается при успешном выполнении команды
|
||||
signal command_fail(unit: ModbusClient) ## Вызывается при возникновении ошибки во время выполнения команды
|
||||
signal line_changed(unit: ModbusClient) ## Вызывается при смене состояния связи с ячейкой
|
||||
signal parse_failed(unit: ModbusClient) ## Вызывается при возникновении ошибки во время разбора пакета
|
||||
func process(tick): pass
|
||||
@@ -56,7 +56,7 @@ yemsconsts="*res://scripts/yems-consts.gd"
|
||||
interfer="*res://scripts/interfer.gd"
|
||||
hotkeys="*res://scripts/hotkeys.gd"
|
||||
mercator="*res://scripts/mercator.gd"
|
||||
modbus="*res://modbus/modbus.gd"
|
||||
modbus="*res://scripts/modbus.gd"
|
||||
tcp5p28="*res://scripts/tcp5p28.gd"
|
||||
|
||||
[debug]
|
||||
|
||||
130
scripts/modbus.gd
Normal file
130
scripts/modbus.gd
Normal file
@@ -0,0 +1,130 @@
|
||||
extends Node
|
||||
|
||||
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды
|
||||
|
||||
class ModbusClient:
|
||||
|
||||
## Состояние автомата выполнения команды
|
||||
enum CmdState {
|
||||
DONE, ## Команда выполнена
|
||||
FAIL, ## Команда не выполнена
|
||||
SEND, ## Буфер готов для отправки
|
||||
WAIT ## Ожидание выполнения
|
||||
}
|
||||
|
||||
var name: String
|
||||
var unit: = 1 ## Адрес устройства Modbus
|
||||
var cmd_state: = CmdState.DONE ## Код текущей команды
|
||||
var tx_data: PackedByteArray ## Данные для отправки
|
||||
var online: = false ## Флаг. Если установлен, устройство на связи. Активный уровень - [b]true[/b].
|
||||
var tick_rx: = 0 ## Время приёма крайнего сообщения
|
||||
var tick_tx: = 0 ## Время отправки крайнего сообщения
|
||||
|
||||
static var json_conv: = JSON.new()
|
||||
|
||||
signal command_done() ## Вызывается при успешном выполнении команды
|
||||
signal command_fail() ## Вызывается при возникновении ошибки во время выполнения команды
|
||||
signal line_changed() ## Вызывается при смене состояния связи с ячейкой
|
||||
signal data_received() ## Вызывается при приёме сообщения, до его разбора
|
||||
signal parse_failed(msg: String) ## Вызывается при возникновении ошибки во время разбора пакета. Передаёт сообщение об ошибке
|
||||
|
||||
signal holding_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения
|
||||
signal input_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров входов
|
||||
signal info_received(msg: String) ## Вызывается при получении информационного сообщения
|
||||
signal except_received(msg: String) ## Вызывается при получении сообщения об исключительной ситуации
|
||||
|
||||
func _init(nm: String, u: int = 1):
|
||||
unit = u
|
||||
name = nm
|
||||
|
||||
## Изменяет состояние. Вызывать периодически[br]
|
||||
## [param tick] - Текущщее время в мс[br]
|
||||
func process(tick: int):
|
||||
if online and ((tick - tick_rx) > ONLINE_TIMEOUT):
|
||||
online = false
|
||||
emit_signal('line_changed')
|
||||
if cmd_state == CmdState.WAIT:
|
||||
cmd_state = CmdState.FAIL
|
||||
emit_signal('command_fail')
|
||||
var rc = Error.ERR_BUSY
|
||||
if cmd_state == CmdState.SEND:
|
||||
rc = Error.OK
|
||||
tick_tx = tick
|
||||
cmd_state = CmdState.WAIT
|
||||
return rc
|
||||
|
||||
## Производит разбор принятых данных. Вызывать при приёме данных на сокете[br]
|
||||
## [param data] - Данные принятые на сокете[br]
|
||||
## [param tick] - Текущщее время в мс[br]
|
||||
func parse(data: PackedByteArray, tick: int) -> bool:
|
||||
tick_rx = tick
|
||||
if not online:
|
||||
online = true
|
||||
emit_signal('line_changed')
|
||||
var utf8_data = data.get_string_from_utf8()
|
||||
if Error.OK == json_conv.parse(utf8_data):
|
||||
emit_signal('data_received')
|
||||
var message: Dictionary = json_conv.get_data()
|
||||
if message.has('code') and message.has('data'):
|
||||
var rc: = true
|
||||
var message_data = message['data']
|
||||
match message['code']:
|
||||
'read_input':
|
||||
var addr = message_data[0]
|
||||
var regs = message_data.slice(1)
|
||||
emit_signal('input_received', addr, regs)
|
||||
'read_holding':
|
||||
var addr = message_data[0]
|
||||
var regs = message_data.slice(1)
|
||||
emit_signal('holding_received', addr, regs)
|
||||
'info':
|
||||
var msg = message['data']
|
||||
emit_signal('info_received', msg)
|
||||
'exception':
|
||||
var msg = message['data']
|
||||
emit_signal('except_received', msg)
|
||||
rc = false
|
||||
_:
|
||||
var msg: String = 'код команды \"%s\" - не распознан' % message['code']
|
||||
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')
|
||||
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}
|
||||
tx_data = json_conv.stringify(json_dict).to_utf8_buffer()
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
|
||||
## Отправляет команду "читать регистры хранения".[br]
|
||||
## [param addr] - Начальный адрес регистров.[br]
|
||||
## [param count] - Количество регистров от начального адреса.[br]
|
||||
func read_holdind(addr: int, count: int = 1) -> bool:
|
||||
if cmd_state != CmdState.DONE: return false
|
||||
var json_dict = {'code': 'read_holding', 'data': [addr, count]}
|
||||
tx_data = json_conv.stringify(json_dict).to_utf8_buffer()
|
||||
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]}
|
||||
tx_data = json_conv.stringify(json_dict).to_utf8_buffer()
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
Reference in New Issue
Block a user