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