143 lines
4.9 KiB
GDScript
143 lines
4.9 KiB
GDScript
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: Array
|
||
var tx_stack: Array[PackedByteArray] = []
|
||
var _msg_counter: int = 0
|
||
var ecms: Dictionary = {} # Словарь всех активных помех
|
||
var srn = 0
|
||
var jtids = 0
|
||
|
||
func _init(nm: StringName) -> void:
|
||
self.name = nm
|
||
tx_data.resize(WORDS_TOTAL)
|
||
tx_data.fill(NOINFO)
|
||
interfer.connect("interfer_update", Callable(self, "_on_interfer_update"))
|
||
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 spb := StreamPeerBuffer.new()
|
||
spb.big_endian = true
|
||
spb.data_array = rx_data
|
||
var words: Array[int] = []
|
||
while spb.get_position() < spb.data_array.size():
|
||
words.append(spb.get_u32())
|
||
if words.size() < 10:
|
||
emit_signal('parse_failed', self)
|
||
return
|
||
_msg_counter += 1
|
||
tx_data.fill(NOINFO)
|
||
tx_data[0] = words[0] # ID
|
||
tx_data[1] = _msg_counter # Nc
|
||
tx_data[2] = 0x01 # Nб
|
||
tx_data[3] = 0x00 # Ск
|
||
tx_data[4] = 0x0194 # НТС
|
||
tx_data[5] = (0x0001 << 16) | 0x0080 # Ии
|
||
tx_data[6] = 0x01 # РКС
|
||
srn = words[7] # SRN
|
||
jtids = words[8] # JTIDS
|
||
|
||
btn_trassa_pressed()
|
||
|
||
tx_data[74] = _calc_crc(tx_data)
|
||
emit_signal("data_received", self)
|
||
|
||
|
||
# Проверка активности помехи
|
||
func _is_interfer_active(interfer_name: String) -> bool:
|
||
for ecm in ecms.values():
|
||
if ecm.krp and ecm.krp == interfer_name:
|
||
return ecm.svk == 1
|
||
return false
|
||
|
||
|
||
# Основной процесс отправки
|
||
func process(tick: int) -> int:
|
||
var rc := Error.ERR_BUSY
|
||
if (tick - tx_tick) > REQUEST_PERIOD:
|
||
tx_tick = tick
|
||
rc = Error.OK
|
||
var packet := PackedByteArray()
|
||
packet.resize(WORDS_TOTAL * 4)
|
||
for i in range(WORDS_TOTAL):
|
||
packet.encode_u32(i * 4, tx_data[i])
|
||
tx_stack.append(packet)
|
||
|
||
print(packet)
|
||
return rc
|
||
if online and (tick - rx_tick) > ONLINE_TIMEOUT:
|
||
online = false
|
||
emit_signal("line_changed", self)
|
||
return rc
|
||
|
||
|
||
# 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_update(ecm_object: Object) -> void:
|
||
var ecm_data = {
|
||
"krp": ecm_object.krp,
|
||
"svk": ecm_object.svk,
|
||
"nmfs": ecm_object.nmfs
|
||
}
|
||
#prd.fs_caps_id[]
|
||
if ecm_data.krp:
|
||
ecms[ecm_data.krp] = ecm_data
|
||
print("Обновление krp:", ecm_data.krp, "svk:", ecm_data.svk, "fs:", ecm_data.nmfs)
|
||
|
||
|
||
# Обновление всех активных помех при изменении размера
|
||
func _on_interfer_resized(ecms_objects: Dictionary) -> void:
|
||
ecms.clear()
|
||
for ecm_id in ecms_objects:
|
||
var ecm_object = ecms_objects[ecm_id]
|
||
var ecm_data = {
|
||
"krp": ecm_object.krp,
|
||
"svk": ecm_object.svk,
|
||
"nmfs": ecm_object.nmfs
|
||
}
|
||
if ecm_data.krp:
|
||
ecms[ecm_data.krp] = ecm_data
|
||
print("Обновлен список: ")
|
||
for ecm_key in ecms:
|
||
var ecm = ecms[ecm_key]
|
||
if ecm.krp:
|
||
print("krp:", ecm.krp, "svk:", ecm.svk, "fs:", ecm.nmfs)
|
||
|
||
|
||
func btn_trassa_pressed() -> void:
|
||
var state = ProjectSettings.get_setting('application/config/Внешнее указание Трасса', false)
|
||
if state == true:
|
||
if srn == 1:
|
||
tx_data[65] = 1
|
||
signaller.emit_signal('interfer_prinuditelno', frm_ecm_list.srn_sectors)
|
||
else:
|
||
tx_data[65] = 0
|
||
|
||
if jtids == 1:
|
||
tx_data[66] = 1
|
||
signaller.emit_signal('interfer_prinuditelno', frm_ecm_list.jtids_sectors)
|
||
else:
|
||
tx_data[66] = 0
|