class_name trassa_unit extends Node const ONLINE_TIMEOUT: int = 5000 # Время ожидания данных const REQUEST_PERIOD: int = 3000 # Период отправки, мс const WORDS_TOTAL: int = 75 const NOINFO: int = 0x80000000 class Trassa extends unit.Unit: var source_addr: = [] var unit_caps = network.get_unit_instance('уарэп-капсрпб') var tx_stack: Array[int] = [] var msg_counter: int = 0 var ecms: Dictionary = {} # Словарь всех активных помех var srn = 0 var jtids = 0 var prinud_but: Array = [] var forced_buttons: Array = [] # Храним ссылки на кнопки # Инициализация func _init(nm: StringName, buttons: Array = []) -> void: self.name = nm self.forced_buttons = buttons tx_stack.resize(WORDS_TOTAL) tx_stack.fill(NOINFO) interfer.connect("interfer_resized", Callable(self, "on_interfer_resized")) # Обработка полученного пакета func parse(rx_data: PackedByteArray, tick: int): rx_tick = tick if not online: online = true emit_signal("line_changed", self) var words: Array[int] = [] var offset: int = 0 while offset < rx_data.size(): if offset + 4 <= rx_data.size(): var word = rx_data.decode_u32(offset) words.append(word) offset += 4 else: break if words.size() < 10: emit_signal('parse_failed', self) tx_stack.fill(NOINFO) tx_stack[0] = words[0] # ID tx_stack[1] = msg_counter # Nc tx_stack[2] = 0x01 # Nб tx_stack[3] = 0x00 # Ск tx_stack[4] = 0x0194 # НТС tx_stack[5] = (0x0001 << 16) | 0x0080 # Ии tx_stack[6] = 0x01 # РКС srn = words[7] # SRN jtids = words[8] # JTIDS btn_trassa_pressed() interfer_data() tx_stack[74] = _calc_crc(tx_stack) emit_signal("data_received", self) func interfer_data() -> void: for i in range(67, 74): tx_stack[i] = 0 for ecm in ecms.values(): if ecm.svk == 1: var nmfs_value = ecm.nmfs var fs_key = get_fs_key(nmfs_value) if fs_key != NOINFO: var string_index = fs_key / 4 var bit_position = fs_key % 4 if string_index >= 0 and string_index < 7: var target_string = 67 + string_index tx_stack[target_string] |= (1 << bit_position) func get_fs_key(nmfs_value: int) -> int: if prd.fs_caps_id.has(nmfs_value): return prd.fs_caps_id[nmfs_value] return NOINFO # Отправка пакета от uarep-ctl func process(now_tick: int) -> int: if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT): online = false emit_signal("line_changed", self) if (now_tick - tx_tick) > REQUEST_PERIOD: tx_tick = now_tick msg_counter += 1 interfer_uarep() interfer_data() var data = PackedByteArray() data.resize(WORDS_TOTAL * 4) for i in range(WORDS_TOTAL): data.encode_u32(i * 4, tx_stack[i]) tx_data = data tx_len = WORDS_TOTAL * 4 return Error.OK return Error.ERR_BUSY # CRC вычисление func _calc_crc(data: Array) -> int: var acc: int = 0 for i in range(data.size() - 1): # кроме CRC if i in [0, 1]: continue acc = (acc + (data[i] & 0xFFFFFFFF)) & 0xFFFFFFFF return acc # Обновление всех активных помех func on_interfer_resized(ecms_dic: Dictionary) -> void: ecms = ecms_dic func interfer_uarep() -> void: tx_stack[65] = 0 tx_stack[66] = 0 for ecm in ecms.values(): if ecm.krp == "srni1" and ecm.svk == 1: tx_stack[65] = 1 if ecm.krp == "svi1" and ecm.svk == 1: tx_stack[66] = 1 tx_stack[1] = msg_counter # Обработка указаний от Трассы по кнопке func btn_trassa_pressed() -> void: var state = ProjectSettings.get_setting('application/config/Внешнее указание Трасса', false) if state == true: var tree: SceneTree = Engine.get_main_loop() if tree is SceneTree: var nodes: Array = tree.get_nodes_in_group('группа-принудительно') for btn in nodes: if btn.name == 'btn_srn': btn.pressed = (srn == 1) elif btn.name == 'btn_jtids': btn.pressed = (jtids == 1) if srn == 1: tx_stack[65] = 1 signaller.emit_signal('interfer_prinuditelno', frm_ecm_list.srn_sectors) else: tx_stack[65] = 0 for ecm in ecms.values(): if ecm.krp == "srni1" and ecm.svk == 1: ecm.krp = interfer.INTERFER_OFF interfer.send_ecm(ecm, unit_caps) signaller.emit_signal('interfer_off', ecm) if jtids == 1: tx_stack[66] = 1 signaller.emit_signal('interfer_prinuditelno', frm_ecm_list.jtids_sectors) else: tx_stack[66] = 0 for ecm in ecms.values(): if ecm.krp == "svi1" and ecm.svk == 1: ecm.krp = interfer.INTERFER_OFF interfer.send_ecm(ecm, unit_caps) signaller.emit_signal('interfer_off', ecm) for ecm in ecms.values(): if ecm.krp == "svi1" and ecm.svk == 1: ecm.krp = interfer.INTERFER_OFF interfer.send_ecm(ecm, unit_caps) signaller.emit_signal('interfer_off', ecm)