Доработка. Запись в регистры хранения Modbus для управления питанием прибора Щ3
This commit is contained in:
@@ -6,44 +6,137 @@ 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: = 3 ## Адрес устройства на шине Modbus
|
||||
|
||||
var regs_input: = {} ## Регистры входные
|
||||
var regs_holding: = {} ## Регистры хранения
|
||||
var write_stack: = [] ## Стек команд для записи
|
||||
var holding_stack: = [] ## Стек команд для чтения регистров хранения
|
||||
var input_stack: = [] ## Стек команд для чтения регистров входов
|
||||
var read_step: = 0
|
||||
var switches_sync: = false
|
||||
|
||||
|
||||
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 _enter_tree() -> void:
|
||||
func _on_timeout(unit_sch3) -> void:
|
||||
if write_stack.size():
|
||||
var ad = write_stack.pop_front()
|
||||
if not unit_sch3.write(ad.addr, ad.data):
|
||||
write_stack.push_back(ad)
|
||||
if (read_step == 0) and (input_stack.size() == 0):
|
||||
var ad = StackItem.new(base_input_address, regs_input_count)
|
||||
input_stack.push_back(ad)
|
||||
elif read_step == 1 and (holding_stack.size() == 0):
|
||||
var ad = StackItem.new(base_holding_address, regs_holding_count)
|
||||
holding_stack.push_back(ad)
|
||||
if input_stack.size():
|
||||
var ad = input_stack.pop_front()
|
||||
if not unit_sch3.read_input(ad.addr, ad.data):
|
||||
input_stack.push_back(ad)
|
||||
if holding_stack.size():
|
||||
var ad = holding_stack.pop_front()
|
||||
if not unit_sch3.read_holding(ad.addr, ad.data):
|
||||
holding_stack.push_back(ad)
|
||||
read_step += 1
|
||||
read_step %= 2
|
||||
|
||||
|
||||
func on_toggled_switch(val: bool, unit_sch3: sch_3.Sch3, meta: Array):
|
||||
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[off_addr] = tools.set_bit(regs_holding[off_addr], off_bit, not val)
|
||||
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:
|
||||
if Engine.is_editor_hint(): return
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
var unit = network.units[unit_key]
|
||||
unit.connect('resp_input', on_resp_input)
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if Engine.is_editor_hint(): return
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
var unit = network.units[unit_key]
|
||||
unit.disconnect('resp_input', on_resp_input)
|
||||
|
||||
|
||||
func on_line_changed(_unit):
|
||||
var items = get_tree().get_nodes_in_group('bits_items_good')
|
||||
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:
|
||||
item.texture = textures[STATE_VAL.ERROR]
|
||||
var meta = item.get_meta('bits')
|
||||
item.connect('toggled', on_toggled_switch.bind(unit_sch3, meta))
|
||||
item.disabled = true
|
||||
unit_sch3.connect('resp_input', on_resp_input)
|
||||
unit_sch3.connect('resp_holding', on_resp_holding)
|
||||
var timer = Timer.new()
|
||||
timer.connect('timeout', _on_timeout.bind(unit_sch3))
|
||||
add_child(timer)
|
||||
timer.start(1.0)
|
||||
|
||||
|
||||
func on_resp_input(addr: int, data: PackedByteArray):
|
||||
if (addr != 0) or (data.size() < 4):
|
||||
func on_line_changed(unit_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()
|
||||
input_stack.clear()
|
||||
holding_stack.clear()
|
||||
switches_sync = false
|
||||
|
||||
|
||||
func on_resp_holding(base_addr: int, data: Array):
|
||||
if (base_addr != base_holding_address) or (data.size() < regs_holding_count):
|
||||
return
|
||||
for i in data.size():
|
||||
regs_holding[base_addr + i] = data[i]
|
||||
if not switches_sync:
|
||||
for item in get_tree().get_nodes_in_group('bits_items_switch'):
|
||||
var bits = item.get_meta('bits')
|
||||
var byte: int = bits[0]
|
||||
var bit: int = bits[1]
|
||||
item.button_pressed = regs_holding[byte] & (1 << bit) > 0
|
||||
item.disabled = false
|
||||
switches_sync = true
|
||||
$margin/vbox/grid1/lbl_freq.text = '<нет данных>'
|
||||
|
||||
|
||||
func on_resp_input(base_addr: int, data: Array):
|
||||
if (base_addr != base_input_address) or (data.size() < regs_input_count):
|
||||
return
|
||||
# "Для контроля состояния управляющего элемента подачи электроэнергии на приборы ..."
|
||||
# "Для контроля подачи электроэнергии на приборы ..."
|
||||
# Таблицы 3.13 и 3.14. Ecли значения соответствующих битов в этих
|
||||
# регистрах равны, то "исправно".
|
||||
var items = get_tree().get_nodes_in_group('bits_items_good')
|
||||
for i in data.size():
|
||||
regs_input[base_addr + i] = data[i]
|
||||
# Таблица 3.15, Регистр PowerState
|
||||
$margin/vbox/grid1/lbl_freq.text = '%d' % (regs_input[4] & 0x1ff)
|
||||
var cnt_good: int = 0
|
||||
for item in items:
|
||||
var bits: Array = item.get_meta('bits')
|
||||
var byte0: int = bits[0]
|
||||
var bit0: int = bits[1]
|
||||
var byte1: int = bits[2]
|
||||
var bit1: int = bits[3]
|
||||
var byte0: int = bits[0] # Индекс байта в данных "состояния управляющего элемента"
|
||||
var bit0: int = bits[1] # Индекс бита в данных "состояния управляющего элемента"
|
||||
var byte1: int = bits[2] # Индекс байта в данных "подачи электроэнергии на приборы"
|
||||
var bit1: int = bits[3] # Индекс бита в данных "подачи электроэнергии на приборы"
|
||||
var v = STATE_VAL.GOOD \
|
||||
if (data[byte0] & (1 << bit0)) \
|
||||
== (data[byte1] & (1 << bit1)) \
|
||||
|
||||
Reference in New Issue
Block a user