Доработан контроль

This commit is contained in:
danil_tim
2024-12-11 09:03:10 +03:00
parent d3a4ae4eec
commit 34284c0988
13 changed files with 838 additions and 745 deletions

View File

@@ -15,6 +15,7 @@ dest_files=["res://.godot/imported/DSEG7Classic-Regular.ttf-32df8fc6f2e5584d5a5b
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48

View File

@@ -15,6 +15,7 @@ dest_files=["res://.godot/imported/DejaVuSans.ttf-b4085dde282b5d503d6a56e258b526
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48

View File

@@ -15,6 +15,7 @@ dest_files=["res://.godot/imported/DejaVuSansCondensed.ttf-7a8251b7291db131ffa4e
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48

View File

@@ -1,20 +1,20 @@
[gd_scene load_steps=4 format=3 uid="uid://dwxn2puh462nl"]
[ext_resource type="Script" path="res://scenes/контроль/прибор.gd" id="1_2qyst"]
[ext_resource type="Script" path="res://scenes/pribor-uf/pribor_uf.gd" id="1_7gtpa"]
[ext_resource type="Texture2D" uid="uid://c4mdrmk7h638f" path="res://data/nine-patch-round.png" id="2_ho0da"]
[ext_resource type="PackedScene" uid="uid://p2suppildvq0" path="res://scenes/контроль/элемент-в.tscn" id="3_dp78y"]
[node name="pribor_uf" type="Control"]
layout_mode = 3
anchors_preset = 0
script = ExtResource("1_2qyst")
script = ExtResource("1_7gtpa")
[node name="ref_uf" type="NinePatchRect" parent="."]
layout_mode = 0
offset_left = 98.0
offset_left = 187.0
offset_top = 247.0
offset_right = 708.0
offset_bottom = 1121.0
offset_bottom = 955.0
texture = ExtResource("2_ho0da")
patch_margin_left = 16
patch_margin_top = 16
@@ -23,17 +23,17 @@ patch_margin_bottom = 16
[node name="ref_bu1" type="NinePatchRect" parent="ref_uf"]
layout_mode = 0
offset_left = 282.0
offset_top = 138.0
offset_right = 591.0
offset_bottom = 468.0
offset_left = 199.0
offset_top = 14.0
offset_right = 508.0
offset_bottom = 344.0
texture = ExtResource("2_ho0da")
patch_margin_left = 16
patch_margin_top = 16
patch_margin_right = 16
patch_margin_bottom = 16
[node name="ref_A13" parent="ref_uf/ref_bu1" instance=ExtResource("3_dp78y")]
[node name="ref_A13_MKEG" parent="ref_uf/ref_bu1" instance=ExtResource("3_dp78y")]
offset_left = 7.0
offset_top = 60.0
offset_right = 59.0
@@ -42,21 +42,14 @@ self_size = Vector2i(52, 262)
fname = "MKEG/C"
rname = "A13"
[node name="ref_A" parent="ref_uf/ref_bu1" instance=ExtResource("3_dp78y")]
[node name="ref_A8_BU" parent="ref_uf/ref_bu1" instance=ExtResource("3_dp78y")]
offset_left = 59.0
offset_top = 60.0
offset_right = 302.0
offset_bottom = 322.0
self_size = Vector2i(243, 262)
fname = "ВК-110"
[node name="А8" type="Label" parent="ref_uf/ref_bu1"]
layout_mode = 0
offset_left = 21.0
offset_top = 12.0
offset_right = 39.0
offset_bottom = 31.0
text = "А8"
rname = "A8"
[node name="А1" type="Label" parent="ref_uf/ref_bu1"]
layout_mode = 0
@@ -68,83 +61,74 @@ text = "БУ-1"
[node name="ref_kassetav13" type="NinePatchRect" parent="ref_uf"]
layout_mode = 0
offset_left = 12.0
offset_top = 513.0
offset_right = 601.0
offset_bottom = 852.0
offset_left = 11.0
offset_top = 353.0
offset_right = 509.0
offset_bottom = 692.0
texture = ExtResource("2_ho0da")
patch_margin_left = 16
patch_margin_top = 16
patch_margin_right = 16
patch_margin_bottom = 16
[node name="ref_A18" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 6.0
[node name="ref_A9_ESW" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 62.0
offset_top = 65.0
offset_right = 165.0
offset_right = 170.0
offset_bottom = 325.0
self_size = Vector2i(159, 260)
self_size = Vector2i(108, 260)
fname = "ESW-6U16TP"
rname = "A18"
rname = "A9"
[node name="ref_A7" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 166.0
[node name="ref_A7_YAU07" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 438.0
offset_top = 65.0
offset_right = 218.0
offset_right = 490.0
offset_bottom = 325.0
self_size = Vector2i(52, 260)
fname = "ЯУ-07Б"
rname = "A7"
[node name="ref_A2" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 218.0
[node name="ref_A4_KEMS" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 279.0
offset_top = 65.0
offset_right = 270.0
offset_bottom = 325.0
self_size = Vector2i(52, 260)
fname = "КЭМС-Б"
rname = "A2"
[node name="ref_A4" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 269.0
offset_top = 65.0
offset_right = 321.0
offset_right = 331.0
offset_bottom = 325.0
self_size = Vector2i(52, 260)
fname = "КЭМС-Б1"
rname = "A4"
[node name="ref_A5" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 322.0
[node name="ref_A5_EMS" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 225.0
offset_top = 65.0
offset_right = 374.0
offset_right = 277.0
offset_bottom = 325.0
self_size = Vector2i(52, 260)
fname = "ЭМС-Б"
rname = "A5"
[node name="ref_A6" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 374.0
[node name="ref_A6_EMS" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 171.0
offset_top = 65.0
offset_right = 426.0
offset_right = 223.0
offset_bottom = 325.0
self_size = Vector2i(52, 260)
fname = "ЭМС-Б"
rname = "A6"
[node name="ref_A3" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 427.0
[node name="ref_A3_IP5B" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 332.0
offset_top = 65.0
offset_right = 532.0
offset_right = 437.0
offset_bottom = 325.0
self_size = Vector2i(105, 260)
fname = "ИП-220-5Б"
rname = "A3"
[node name="ref_A8" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 531.0
[node name="ref_A12_IP27B" parent="ref_uf/ref_kassetav13" instance=ExtResource("3_dp78y")]
offset_left = 9.0
offset_top = 65.0
offset_right = 582.0
offset_right = 60.0
offset_bottom = 325.0
self_size = Vector2i(51, 260)
fname = "ИП220-27Б"
@@ -168,7 +152,7 @@ text = "Кассета В-13"
[node name="lbl_header" type="Label" parent="."]
layout_mode = 0
offset_left = 105.0
offset_left = 199.0
offset_top = 225.0
offset_right = 704.0
offset_bottom = 251.0
@@ -177,3 +161,16 @@ text = "Контроль исправности прибора УФ
"
horizontal_alignment = 1
vertical_alignment = 1
[node name="lbl_header2" type="Label" parent="."]
visible = false
layout_mode = 0
offset_left = 199.0
offset_top = 974.0
offset_right = 704.0
offset_bottom = 1000.0
theme_override_font_sizes/font_size = 22
text = "Прибор не исправен
"
horizontal_alignment = 1
vertical_alignment = 1

View File

@@ -1,14 +1,106 @@
extends "res://scenes/контроль/прибор.gd"
# Called when the node enters the scene tree for the first time.
enum STATE_VAL {
NONE = 0,
GOOD = 1,
ERROR = 2 }
var timer = Timer.new()
var DEV_LIST = ['00:1f.6', '07:00.0', '08:00.0', '0b:00.0']
var USB_TRACKERBALL = '046d:c31c'
var REVFF = '(rev ff)'
func _ready() -> void:
var unit_key = settings.get_unit_key('уарэп-эмс')
var unit_uf = network.units[unit_key]
unit_uf.connect('data_received', on_data_received.bind(unit_uf))
func on_data_received(data, unit_uf):
print_debug(data)
var unit_key_5p28 = settings.get_unit_key('уарэп-5п28')
var unit_5p28 = network.units[unit_key_5p28]
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
self.add_child(timer)
timer.connect('timeout', Callable(self, 'on_timer').bind(unit_uf, unit_5p28))
timer.start(1)
func on_timer(unit_uf, unit_5p28):
Control_VK() # проверка трекбола и pci
if unit_5p28.online: # проверка внешнего коммутатора
$ref_uf/ref_bu1/ref_A13_MKEG.state = STATE_VAL.GOOD
else:
$ref_uf/ref_bu1/ref_A13_MKEG.state = STATE_VAL.NONE
if unit_uf.online: # проверка ЯУ, внутреннего коммутатора и ИП-5Б
$ref_uf/ref_kassetav13/ref_A7_YAU07.state = STATE_VAL.GOOD
$ref_uf/ref_kassetav13/ref_A3_IP5B.state = STATE_VAL.GOOD
$ref_uf/ref_kassetav13/ref_A9_ESW.state = STATE_VAL.GOOD
Control_EMS(unit_uf.status) # проверка ЭМС ячеек
else:
$ref_uf/ref_kassetav13/ref_A7_YAU07.state = STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A5_EMS.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A6_EMS.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A3_IP5B.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A9_ESW.state = STATE_VAL.NONE
$ref_uf/ref_kassetav13/ref_A12_IP27B.state = STATE_VAL.NONE
status_uf() # отслеживание состояния прибора
func Control_VK() -> void:
var out_usb_str = ''
var out_pci_str = ''
var out_usb = []
var out_pci = []
OS.execute('lsusb', [], out_usb)
for element in out_usb:
out_usb_str += element
OS.execute('lspci', [], out_pci)
for element in out_pci:
out_pci_str += element
out_usb_str = out_usb_str.split("\n")
out_pci_str = out_pci_str.split("\n")
var i: int = 0
for string in out_usb_str:
if USB_TRACKERBALL in string:
i += 1
break
for string in out_pci_str:
for item in DEV_LIST:
if item in string:
i += 1
if REVFF in string:
i -= 1
break
if i == (len(DEV_LIST) + 1):
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD
else:
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.ERROR
func Control_EMS(status:Array) -> void:
$ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.GOOD if ((status[0] >> 0) & 1) and ((status[0] >> 3) & 1) else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A5_EMS.state = STATE_VAL.GOOD if ((status[0] >> 1) & 1) and ((status[0] >> 4) & 1) else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A6_EMS.state = STATE_VAL.GOOD if ((status[0] >> 2) & 1) and ((status[0] >> 5) & 1) else STATE_VAL.ERROR
$ref_uf/ref_kassetav13/ref_A12_IP27B.state = STATE_VAL.GOOD if ((status[2] >> 6) & 1) else STATE_VAL.ERROR
func status_uf() -> void:
var status_bu:int = $ref_uf/ref_bu1/ref_A8_BU.state
var status_yay:int = $ref_uf/ref_kassetav13/ref_A7_YAU07.state
var status_kems:int = $ref_uf/ref_kassetav13/ref_A4_KEMS.state
var status_ems0:int = $ref_uf/ref_kassetav13/ref_A5_EMS.state
var status_ems1:int = $ref_uf/ref_kassetav13/ref_A6_EMS.state
if (status_yay == 1) and (status_bu == 1) and (status_kems == 1) and (status_ems0 == 1) and (status_ems1 == 1):
$lbl_header2.text = "Прибор исправен"
$lbl_header2.modulate = Color(0,1,0,1)
else:
$lbl_header2.text = "Прибор не исправен"
$lbl_header2.modulate = Color(1,0,0,1)
$lbl_header2.visible = true

View File

@@ -26,10 +26,10 @@ var timer = Timer.new()
class StackItem:
var addr: = 0
var data = null
func _init(a: int, d): addr = a; data = d
func _to_string() -> String: return '%s: %s' % [addr, data]
var addr: = 0
var data = null
func _init(a: int, d): addr = a; data = d
func _to_string() -> String: return '%s: %s' % [addr, data]
func on_data_received(_data: PackedByteArray): pass
@@ -37,147 +37,147 @@ func on_data_received(_data: PackedByteArray): pass
## Обработчик таймера
func _on_timeout(unit_sch3) -> void:
if write_stack.size():
var ad = write_stack.pop_front()
if not unit_sch3.write(ad.addr, ad.data):
write_stack.push_back(ad)
if (read_step == 0) and (input_stack.size() == 0):
var ad = StackItem.new(base_input_address, regs_input_count)
input_stack.push_back(ad)
elif (read_step == 1) and (holding_stack.size() == 0):
var ad = StackItem.new(base_holding_address, regs_holding_count)
holding_stack.push_back(ad)
if input_stack.size():
var ad = input_stack.pop_front()
if not unit_sch3.read_input(ad.addr, ad.data):
input_stack.push_back(ad)
if holding_stack.size():
var ad = holding_stack.pop_front()
if not unit_sch3.read_holding(ad.addr, ad.data):
holding_stack.push_back(ad)
read_step += 1
read_step %= 2
if write_stack.size():
var ad = write_stack.pop_front()
if not unit_sch3.write(ad.addr, ad.data):
write_stack.push_back(ad)
if (read_step == 0) and (input_stack.size() == 0):
var ad = StackItem.new(base_input_address, regs_input_count)
input_stack.push_back(ad)
elif (read_step == 1) and (holding_stack.size() == 0):
var ad = StackItem.new(base_holding_address, regs_holding_count)
holding_stack.push_back(ad)
if input_stack.size():
var ad = input_stack.pop_front()
if not unit_sch3.read_input(ad.addr, ad.data):
input_stack.push_back(ad)
if holding_stack.size():
var ad = holding_stack.pop_front()
if not unit_sch3.read_holding(ad.addr, ad.data):
holding_stack.push_back(ad)
read_step += 1
read_step %= 2
## Вызывается при изменении состояния выключателя[br]
## [param val] - Состояние выключателя[br]
## [param meta] - Адреса регистров и индексы битов назначенных выключателю[br]
func on_toggled_switch(val: bool, meta: Array):
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)
push_write_holding()
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)
push_write_holding()
## Заносит в очередь команду чтения регистров хранения
func push_write_holding():
var regs_data: = []
var keys = regs_holding.keys()
keys.sort() # Ключи в словаре хранятся не упорядочено
for addr in keys:
regs_data.append(regs_holding[addr])
write_stack.push_back(StackItem.new(keys[0], regs_data))
var regs_data: = []
var keys = regs_holding.keys()
keys.sort() # Ключи в словаре хранятся не упорядочено
for addr in keys:
regs_data.append(regs_holding[addr])
write_stack.push_back(StackItem.new(keys[0], regs_data))
func _ready() -> 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.mb_addr = modbus_address
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))
item.disabled = true
unit_sch3.connect('resp_input', on_resp_input)
unit_sch3.connect('resp_holding', on_resp_holding)
unit_sch3.connect('command_fail', on_command_fail)
timer.connect('timeout', _on_timeout.bind(unit_sch3))
add_child(timer)
timer.start(request_period)
if Engine.is_editor_hint(): return
var unit_key = settings.get_unit_key(unit_name)
var unit_sch3 = network.units[unit_key]
unit_sch3.mb_addr = modbus_address
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))
item.disabled = true
unit_sch3.connect('resp_input', on_resp_input)
unit_sch3.connect('resp_holding', on_resp_holding)
unit_sch3.connect('command_fail', on_command_fail)
timer.connect('timeout', _on_timeout.bind(unit_sch3))
add_child(timer)
timer.start(request_period)
func on_command_fail(unit_sch3):
unit_sch3.cmd_state = unit.Unit.CmdState.DONE
timer.stop()
unit_sch3.cmd_state = unit.Unit.CmdState.DONE
timer.stop()
## Вызывается, когда состояния прибора Щ3 "на связи" изменяется[br]
## [param unit_sch3] - Экземпляр представления прибора Щ3
func on_line_changed(unit_sch3: sch_3.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()
write_stack.clear()
input_stack.clear()
holding_stack.clear()
switches_sync = false
$margin/vbox/grid1/lbl_freq.text = '<нет данных>'
$margin/vbox/grid1/state_freq.texture = textures[STATE_VAL.NONE]
else:
timer.start(request_period)
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()
write_stack.clear()
input_stack.clear()
holding_stack.clear()
switches_sync = false
$margin/vbox/grid1/lbl_freq.text = '<нет данных>'
$margin/vbox/grid1/state_freq.texture = textures[STATE_VAL.NONE]
else:
timer.start(request_period)
## Вызывается по сигналу "приняты данные чтения регистров хранения"[br]
## [param base_addr] - Начальный адрес регистров.[br]
## [param data] - Массив значений прочитанных из регистров.
func on_resp_holding(base_addr: int, data: Array):
if (base_addr != base_holding_address) or (data.size() < regs_holding_count):
return
for i in data.size():
regs_holding[base_addr + i] = data[i]
# Разрешить работу выключателей только когда прочитано их реальное состояние
if not switches_sync:
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.button_pressed = val0
item.disabled = false
regs_holding[byte1] = tools.set_bit(regs_holding[byte1], bit1, not val0)
push_write_holding()
if (base_addr != base_holding_address) or (data.size() < regs_holding_count):
return
for i in data.size():
regs_holding[base_addr + i] = data[i]
# Разрешить работу выключателей только когда прочитано их реальное состояние
if not switches_sync:
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.button_pressed = val0
item.disabled = false
regs_holding[byte1] = tools.set_bit(regs_holding[byte1], bit1, not val0)
push_write_holding()
## Вызывается по сигналу "приняты данные чтения регистров входов".[br]
## [param base_addr] - Начальный адрес регистров.[br]
## [param data] - Массив значений прочитанных из регистров.[br]
func on_resp_input(base_addr: int, data: Array):
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]
# Таблица 3.15, Регистр PowerState
$margin/vbox/grid1/lbl_freq.text = '%d' % (regs_input[4] & 0x1ff)
$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
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]
# Таблица 3.15, Регистр PowerState
$margin/vbox/grid1/lbl_freq.text = '%d' % (regs_input[4] & 0x1ff)
$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

View File

@@ -7,12 +7,12 @@ extends NinePatchRect
"""
@export var fname: String:
set(v):
fname = v
if is_inside_tree():
$lbl_fname.text = v
set(v):
fname = v
if is_inside_tree():
$lbl_fname.text = v
@export var rname: String:
set(v):
rname = v
set(v):
rname = v

View File

@@ -7,7 +7,7 @@ extends Node
func _on_toggled(toggled_on): $frame.visible = toggled_on
@export var state: int:
set(v):
v = 0 if v < 0 else v % state_colors.size()
state = v
$label.self_modulate = state_colors[v]
set(v):
v = 0 if v < 0 else v % state_colors.size()
state = v
$label.self_modulate = state_colors[v]

View File

@@ -6,50 +6,50 @@ extends Panel
const PRIBORS_RES = \
{
'pribor_afsp_l': ['res://scenes/pribor-afsp/pribor-afsp.tscn', 'Контроль исправности прибора АФСП левый'],
'pribor_afsp_r': ['res://scenes/pribor-afsp/pribor-afsp.tscn', 'Контроль исправности прибора АФСП правый'],
'pribor_prd_k_1': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 1'],
'pribor_prd_k_2': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 2'],
'pribor_prd_k_3': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 3'],
'pribor_prd_k_4': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 4'],
'pribor_prd_n_1': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 1'],
'pribor_prd_n_2': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 2'],
'pribor_prd_n_3': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 3'],
'pribor_prd_n_4': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 4'],
'pribor_prd_v_1': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 1'],
'pribor_prd_v_2': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 2'],
'pribor_prd_v_3': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 3'],
'pribor_prd_v_4': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 4'],
'pribor_rtr': ['res://scenes/pribor-rtr/pribor-rtr.tscn', 'Контроль исправности прибора РТР'],
'pribor_uf': ['res://scenes/pribor-uf/pribor-uf.tscn', 'Контроль исправности прибора УФ'],
'pribor_uyep': ['res://scenes/pribor-uyep/pribor-uyep.tscn', 'Контроль исправности прибора УЭП'],
}
'pribor_afsp_l': ['res://scenes/pribor-afsp/pribor-afsp.tscn', 'Контроль исправности прибора АФСП левый'],
'pribor_afsp_r': ['res://scenes/pribor-afsp/pribor-afsp.tscn', 'Контроль исправности прибора АФСП правый'],
'pribor_prd_k_1': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 1'],
'pribor_prd_k_2': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 2'],
'pribor_prd_k_3': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 3'],
'pribor_prd_k_4': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 4'],
'pribor_prd_n_1': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 1'],
'pribor_prd_n_2': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 2'],
'pribor_prd_n_3': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 3'],
'pribor_prd_n_4': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 4'],
'pribor_prd_v_1': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 1'],
'pribor_prd_v_2': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 2'],
'pribor_prd_v_3': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 3'],
'pribor_prd_v_4': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 4'],
'pribor_rtr': ['res://scenes/pribor-rtr/pribor-rtr.tscn', 'Контроль исправности прибора РТР'],
'pribor_uf': ['res://scenes/pribor-uf/pribor-uf.tscn', 'Контроль исправности прибора УФ'],
'pribor_uyep': ['res://scenes/pribor-uyep/pribor-uyep.tscn', 'Контроль исправности прибора УЭП'],
}
func _ready():
var group = ButtonGroup.new()
for k in PRIBORS_RES:
var pribor_node = get_node(k)
assert(pribor_node)
var pribor_path = PRIBORS_RES[k][0]
var header_text = PRIBORS_RES[k][1]
pribor_node.set_button_group(group)
pribor_node.connect('button_down', Callable(self, 'on_pribor_press').bind(pribor_path, header_text))
log.info('Модуль контроля работы готов')
var group = ButtonGroup.new()
for k in PRIBORS_RES:
var pribor_node = get_node(k)
assert(pribor_node)
var pribor_path = PRIBORS_RES[k][0]
var header_text = PRIBORS_RES[k][1]
pribor_node.set_button_group(group)
pribor_node.connect('button_down', Callable(self, 'on_pribor_press').bind(pribor_path, header_text))
log.info('Модуль контроля работы готов')
func on_pribor_press(pribor_path, header_text):
clear_obj($mnemo_container)
var pribor_obj = load(pribor_path)
assert(pribor_obj)
var pribor = pribor_obj.instantiate()
assert(pribor)
pribor.set_header_text(header_text)
$mnemo_container.add_child(pribor)
clear_obj($mnemo_container)
var pribor_obj = load(pribor_path)
assert(pribor_obj)
var pribor = pribor_obj.instantiate()
assert(pribor)
pribor.set_header_text(header_text)
$mnemo_container.add_child(pribor)
func clear_obj(obj: Object):
var items = obj.get_children()
for item in items:
obj.remove_child(item)
item.queue_free()
var items = obj.get_children()
for item in items:
obj.remove_child(item)
item.queue_free()

View File

@@ -18,55 +18,55 @@ extends Control
@export var self_size: Vector2i = Vector2i(50, 150):
set(v):
self_size = v
size = v
$np_rect.size = v
_resize_children()
get: return size
set(v):
self_size = v
size = v
$np_rect.size = v
_resize_children()
get: return size
@export var fname: String:
set(v):
fname = v
$lbl_fname.text = v
set(v):
fname = v
$lbl_fname.text = v
@export var rname: String:
set(v):
rname = v
$lbl_rname.text = v
set(v):
rname = v
$lbl_rname.text = v
func _resize_children() -> void:
$lbl_rname.size.x = size.x
$lbl_rname.position.y = margins[0]
$lbl_fname.size.y = size.x
$lbl_fname.position.y = size.y / 2 + $lbl_fname.size.x / 2
$txr_state.position.x = size.x / 2 - ($txr_state.size.x * $txr_state.scale.x) / 2
$txr_state.position.y = size.y - $txr_state.size.y * $txr_state.scale.x - margins[2]
$lbl_rname.size.x = size.x
$lbl_rname.position.y = margins[0]
$lbl_fname.size.y = size.x
$lbl_fname.position.y = size.y / 2 + $lbl_fname.size.x / 2
$txr_state.position.x = size.x / 2 - ($txr_state.size.x * $txr_state.scale.x) / 2
$txr_state.position.y = size.y - $txr_state.size.y * $txr_state.scale.x - margins[2]
func _on_nine_patch_rect_resized() -> void:
size = $np_rect.size
self_size = $np_rect.size
_resize_children()
size = $np_rect.size
self_size = $np_rect.size
_resize_children()
func _on_resized() -> void:
$np_rect.size = size
self_size = size
_resize_children()
$np_rect.size = size
self_size = size
_resize_children()
@export var state: int:
set(v):
v = 0 if v < 0 else v
v %= textures.size()
state = v
$txr_state.texture = textures[v]
get:
return state
set(v):
v = 0 if v < 0 else v
v %= textures.size()
state = v
$txr_state.texture = textures[v]
get:
return state
"
[node name="yelement_v" type="Control"]

File diff suppressed because it is too large Load Diff

View File

@@ -122,12 +122,13 @@ func _ready() -> void:
dst_ports[unit_key] = st[2][0]
if proto in TCP_PROTO:
var unit = TCP_PROTO[proto].new(unit_name)
var unit_tcp = TCP_PROTO[proto].new(unit_name)
var unit_key = settings.get_unit_key(unit_name)
units_tcp[unit_key] = unit
units_tcp[unit_key] = unit_tcp
units[unit_key] = unit_tcp
if logger_page:
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
unit_tcp.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
unit_tcp.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
if proto in SERIAL_PROTO:
var unit_serial = SERIAL_PROTO[proto].new(unit_name)

View File

@@ -3,26 +3,26 @@ class_name base_unit extends Node
## Базовый класс для управления подключаемыми устройствами
class Unit extends Object:
## Состояние автомата выполнения команды.
enum CmdState {
UNCK, ## Номер команды не ининциирован.
SEND, ## Буфер готов для отправки.
WAIT, ## Ожидание выполнения.
DONE, ## Команда выполнена.
FAIL ## Команда не выполнена.
}
## Состояние автомата выполнения команды.
enum CmdState {
UNCK, ## Номер команды не ининциирован.
SEND, ## Буфер готов для отправки.
WAIT, ## Ожидание выполнения.
DONE, ## Команда выполнена.
FAIL ## Команда не выполнена.
}
signal line_changed(unit) ## Вызывается при изменении состояния связи
signal command_done(unit) ## Вызывается после успешного выполнения команды.
signal command_fail(unit) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена.
signal parse_failed(unit) ## Вызывается при обнаружении ошибки во входных данных
signal data_received(data: PackedByteArray) ## Вызывается по приёму данных
signal line_changed(unit) ## Вызывается при изменении состояния связи
signal command_done(unit) ## Вызывается после успешного выполнения команды.
signal command_fail(unit) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена.
signal parse_failed(unit) ## Вызывается при обнаружении ошибки во входных данных
signal data_received(data: PackedByteArray) ## Вызывается по приёму данных
var tx_data: = PackedByteArray() ## Буфер для отправки.
var tx_len: int = 0 ## Длина последнего отправленного пакета.
var tx_tick: int = 0 ## Тик-время отправки буфера
var rx_tick: int = 0 ## Тик-время последнего приёма данных
var online: bool = false ## Состояние подключения устройства
var name: String = '<без имени>' ## Уникальное имя устройства
func _init(nm) -> void: self.name = nm
func _to_string() -> String: return String('устройство: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
var tx_data: = PackedByteArray() ## Буфер для отправки.
var tx_len: int = 0 ## Длина последнего отправленного пакета.
var tx_tick: int = 0 ## Тик-время отправки буфера
var rx_tick: int = 0 ## Тик-время последнего приёма данных
var online: bool = false ## Состояние подключения устройства
var name: String = '<без имени>' ## Уникальное имя устройства
func _init(nm) -> void: self.name = nm
func _to_string() -> String: return String('устройство: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])