164 lines
8.5 KiB
GDScript
164 lines
8.5 KiB
GDScript
class_name sch3_view
|
||
|
||
extends 'res://scenes/контроль/элемент-я.gd'
|
||
|
||
## Дополнение №1 к протоколу №120-23900-18
|
||
## информационного взаимодействия изделия 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: = 200 ## Период в секундах отправки команд на шину Modbus
|
||
@export var reconnect_period: = 3000 ## Период переподключения в секундах
|
||
|
||
var regs_input: = {} ## Регистры входные
|
||
var regs_holding: = {} ## Регистры хранения
|
||
var switches_sync: = false ## Флаг. Если установлен, то можно переключать
|
||
var external_ctl: = false ## Флаг внешнего управления
|
||
|
||
func on_error(msg, unit_sch3):
|
||
if unit_sch3.online:
|
||
push_error(msg)
|
||
|
||
|
||
## Вызывается, когда состояния прибора Щ3 "на связи" изменяется[br]
|
||
## [param unit_sch3] - Экземпляр представления прибора Щ3
|
||
func on_line_changed_sch3(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()
|
||
switches_sync = false
|
||
$margin/vbox/grid1/lbl_freq.text = '<нет данных>'
|
||
$margin/vbox/grid1/lbl_freq.self_modulate = Color(settings.C_BLUE)
|
||
$margin/vbox/grid1/state_freq.texture = textures[STATE_VAL.NONE]
|
||
$margin/vbox/grid/state.texture = textures[STATE_VAL.NONE]
|
||
|
||
|
||
func on_settings_changed():
|
||
external_ctl = ProjectSettings.get_setting('application/config/Внешнее управление', false)
|
||
if not external_ctl:
|
||
return
|
||
var items = get_tree().get_nodes_in_group('bits_items_switch')
|
||
for item in items:
|
||
item.disabled = external_ctl
|
||
items = get_tree().get_nodes_in_group('bits_items_good')
|
||
for item in items:
|
||
item.texture = textures[STATE_VAL.NONE]
|
||
|
||
## Вызывается при изменении состояния выключателя[br]
|
||
## [param val] - Состояние выключателя[br]
|
||
## [param meta] - Адреса регистров и индексы битов назначенных выключателю[br]
|
||
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[off_addr] = tools.set_bit(regs_holding[off_addr], off_bit, not val)
|
||
unit_sch3.push_write_holding(regs_holding)
|
||
|
||
|
||
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.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_input', on_input.bind(unit_sch3))
|
||
unit_sch3.connect('error', on_error.bind(unit_sch3))
|
||
unit_sch3.connect('line_changed', on_line_changed_sch3)
|
||
|
||
|
||
func _ready() -> void:
|
||
var unit_key = settings.get_unit_key(unit_name)
|
||
var a = network.units
|
||
var unit_sch3 = network.units[unit_key]
|
||
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, unit_sch3))
|
||
item.disabled = true
|
||
|
||
|
||
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_input', on_input.bind(unit_sch3))
|
||
external_ctl = ProjectSettings.get_setting('application/config/Внешнее управление', false)
|
||
unit_sch3.disconnect('error', on_error)
|
||
unit_sch3.disconnect('line_changed', on_line_changed_sch3)
|
||
|
||
|
||
## Вызывается по сигналу "приняты данные чтения регистров входов".[br]
|
||
## [param base_addr] - Начальный адрес регистров.[br]
|
||
## [param data] - Массив значений прочитанных из регистров.[br]
|
||
func on_input(base_addr: int, data: Array, unit_sch3):
|
||
if !is_inside_tree():
|
||
return
|
||
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]
|
||
# Разрешить работу выключателей только когда прочитано их реальное состояние
|
||
if not switches_sync:
|
||
regs_holding[0] = regs_input[0]
|
||
regs_holding[1] = regs_input[1]
|
||
for i in 16:
|
||
regs_holding[2] = tools.set_bit(regs_holding[0], i, not ((regs_holding[0] >> i) & 1))
|
||
regs_holding[3] = tools.set_bit(regs_holding[1], i, not ((regs_holding[1] >> i) & 1))
|
||
if not external_ctl:
|
||
if regs_holding.has(0) and regs_holding.has(2):
|
||
regs_holding[0] = regs_holding[0] | 1
|
||
regs_holding[2] = regs_holding[2] & 0xffe
|
||
switches_sync = true
|
||
for item in get_tree().get_nodes_in_group('bits_items_switch'):
|
||
var bits = 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 val0: bool = regs_holding[byte0] & (1 << bit0) > 0
|
||
item.set_pressed_no_signal(val0)
|
||
item.disabled = false
|
||
regs_holding[byte1] = tools.set_bit(regs_holding[byte1], bit1, not val0)
|
||
unit_sch3.push_write_holding(regs_holding)
|
||
# Таблица 3.15, Регистр PowerState
|
||
$margin/vbox/grid1/lbl_freq.text = '%d' % (regs_input[4] & 0x1ff)
|
||
$margin/vbox/grid1/lbl_freq.self_modulate = Color.WHITE
|
||
$margin/vbox/grid1/state_freq.texture \
|
||
= textures[STATE_VAL.GOOD] if regs_input[4] & (1 << 15) \
|
||
else textures[STATE_VAL.ERROR]
|
||
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 v = STATE_VAL.GOOD \
|
||
if (data[byte0] & (1 << bit0)) \
|
||
== (data[byte1] & (1 << bit1)) \
|
||
else STATE_VAL.ERROR
|
||
cnt_good += int(v == STATE_VAL.GOOD)
|
||
item.texture = textures[v]
|
||
state = STATE_VAL.GOOD if cnt_good == items.size() else STATE_VAL.ERROR
|