Files
uarep-ctl/scenes/pribor-uyep/sch3-view.gd
2025-08-28 09:19:10 +03:00

160 lines
8.4 KiB
GDScript
Raw Permalink 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 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.CADET_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_sch3: = network.get_unit_instance(unit_name)
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_sch3: = network.get_unit_instance(unit_name)
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_sch3 = network.get_unit_instance(unit_name)
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