Merge remote-tracking branch 'refs/remotes/Cat/master'
# Conflicts: # scripts/tools.gd
This commit is contained in:
20
.gitignore
vendored
20
.gitignore
vendored
@@ -15,15 +15,21 @@ mono_crash.*.json
|
||||
# System/tool-specific ignores
|
||||
.directory
|
||||
*~
|
||||
/.idea/
|
||||
/build/
|
||||
/html/
|
||||
/commit.gd
|
||||
.idea/
|
||||
build/
|
||||
html/
|
||||
commit.gd
|
||||
|
||||
.fuse_hidden*
|
||||
/bin/
|
||||
bin/
|
||||
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
/override.cfg
|
||||
/scripts/commit.gd
|
||||
override.cfg
|
||||
|
||||
# контроль версий
|
||||
scripts/commit.gd
|
||||
|
||||
# python специфичное
|
||||
modbus/pymodbus/__pycache__
|
||||
modbus/serial/__pycache__
|
||||
|
||||
10
build.sh
10
build.sh
@@ -3,13 +3,13 @@
|
||||
# ** Описание **
|
||||
#
|
||||
# - Этот скрипт создаёт исполняемый файл (загружаемый модуль) из файла проекта Godot.
|
||||
# - Путь к шаблонам экспорта прописан в файле "export_presets.cfg".
|
||||
# Параметр "--export-release" должен иметь имя указанное в поле "name"
|
||||
# - Путь к шаблонам экспорта должен быть указан в файле "export_presets.cfg".
|
||||
# - Параметр "--export-release" должен иметь значение указанное в поле "name" файла "export_presets.cfg".
|
||||
|
||||
# Имя выходного исполняемого файла (загружаемый модуль)
|
||||
TARGET_BIN="uarep-ctl.linux.x86_64"
|
||||
|
||||
# Целевой путь папки в которой будет расположен исполняемый файл (загружаемый модуль)
|
||||
# Путь к папке в которой будет расположен исполняемый файл (загружаемый модуль)
|
||||
TARGET_PATH="./bin"
|
||||
|
||||
# Путь к исполняемому файлу редактора Godot
|
||||
@@ -18,4 +18,8 @@ EDITOR="/opt/godot/godot.linuxbsd.editor.x86_64.llvm"
|
||||
# Путь к файлу проекта Godot
|
||||
PROJECT_PATH="$(pwd)"
|
||||
|
||||
# Обновление данных контроля версий
|
||||
./git-hook.sh
|
||||
|
||||
# Вызов редактора для сборки исполняемого файла
|
||||
${EDITOR} --headless --path "${PROJECT_PATH}" --export-release "Linux-X11" "${TARGET_PATH}/${TARGET_BIN}"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dd60btbqnpiqw"
|
||||
uid="uid://nm7cpjw6rs51"
|
||||
path="res://.godot/imported/document-new-0.png-4076926ba4469926b76b7d685aad96aa.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
importer="font_data_dynamic"
|
||||
type="FontFile"
|
||||
uid="uid://b8xqbrj2ontxe"
|
||||
uid="uid://dvf4iwl08c1lt"
|
||||
path="res://.godot/imported/ofont.ru_Franklin Gothic Book.ttf-52f1dac05bf20c0c7af86c6e9cfad8fc.fontdata"
|
||||
|
||||
[deps]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b6p0ndxcng02k"
|
||||
uid="uid://cl8h2vaibabyi"
|
||||
path="res://.godot/imported/кнопка-квадрат-1.png-3e8f354c4e789ff37e9c072bb90aa353.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bq67yytxgoopq"
|
||||
uid="uid://b4oau2xgcka77"
|
||||
path="res://.godot/imported/мп550-работа-эскиз.png-7af57230feae7557e482f8923843a550.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://83m8t7nj4a60"
|
||||
uid="uid://gkbvsypul1qg"
|
||||
path="res://.godot/imported/отметка-самолёт.png-bb46afb23fe946fe2230cd3d30c66dca.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cqu18m05sdl5w"
|
||||
uid="uid://bq6biyc0nxjv4"
|
||||
path="res://.godot/imported/прицел-табличка.png-45ba36412555fb1cbc42d6445071f6cd.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
|
||||
GDSCRIPT_FILE="scripts/commit.gd"
|
||||
HEAD="$(git rev-parse --abbrev-ref HEAD) $(git rev-parse --short HEAD) $(git log -1 --format=%cd)"
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
HEAD="Изменённый ${HEAD}"
|
||||
fi
|
||||
echo "extends Node" > ${GDSCRIPT_FILE}
|
||||
echo "# Файл сгенерирован автоматически! Не изменять вручную!" >> ${GDSCRIPT_FILE}
|
||||
echo "const VCS_HEAD = '${HEAD}'" >> ${GDSCRIPT_FILE}
|
||||
|
||||
|
||||
@@ -87,14 +87,14 @@ def run_sync_client(udp_addr, udp_port_rx, udp_port_tx, serial_port, serial_baud
|
||||
rq = client.read_holding_registers(data[0], data[1], unit=unit_num)
|
||||
rc = rq.isError()
|
||||
if not rc:
|
||||
tx_data = json_encoder.encode({'code': 'response', 'data': rq.registers})
|
||||
tx_data = json_encoder.encode({'code': 'response', 'data': [data[0]] + rq.registers})
|
||||
sock.sendto(bytes(tx_data, 'utf-8'), (udp_addr, udp_port_tx))
|
||||
elif message['code'] == 'read_input':
|
||||
data = message['data']
|
||||
rq = client.read_input_registers(data[0], data[1], unit=unit_num)
|
||||
rc = rq.isError()
|
||||
if not rc:
|
||||
tx_data = json_encoder.encode({'code': 'response', 'data': rq.registers})
|
||||
tx_data = json_encoder.encode({'code': 'response', 'data': [data[0]] + rq.registers})
|
||||
sock.sendto(bytes(tx_data, 'utf-8'), (udp_addr, udp_port_tx))
|
||||
elif message['code'] == '<unknown>':
|
||||
rc = False
|
||||
|
||||
@@ -13,6 +13,7 @@ config_version=5
|
||||
config/name="uarep-ctl"
|
||||
run/main_scene="res://scenes/tabs-switch/tab-switch.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
run/flush_stdout_on_print=true
|
||||
run/low_processor_mode=true
|
||||
run/delta_smoothing=false
|
||||
boot_splash/show_image=false
|
||||
@@ -29,12 +30,8 @@ interfer/default_color0=Vector3(0.38, 0.47, 0.51)
|
||||
interfer/default_color1=Vector3(0.39, 0.44, 0.5)
|
||||
interfer/select_color=Vector3(1, 1, 1)
|
||||
interfer/interfer_color=Vector3(0.58, 0.47, 0.51)
|
||||
config/mod_bus_driver="client-serial-modbus.py"
|
||||
config/mod_bus_driver_port="48000"
|
||||
config/mod_bus_driver_address="localhost"
|
||||
config/mod_bus_interpreter="python"
|
||||
config/mod_bus_serial_baud="9600"
|
||||
config/mod_bus_serial_port="/dev/pts/3"
|
||||
interfer/resend_timeout=1000.0
|
||||
config/external_cu=false
|
||||
config/unit_rr_left_bort="http://127.0.0.1:8080/reports/left_SelfTestReport.json"
|
||||
@@ -48,8 +45,8 @@ log="*res://addons/godot-logger/scripts/logger.gd"
|
||||
unit="*res://scripts/unit.gd"
|
||||
tools="*res://scripts/tools.gd"
|
||||
signaller="*res://scripts/signaller.gd"
|
||||
repsettings="*res://scripts/settings.gd"
|
||||
repnetwork="*res://scripts/network.gd"
|
||||
settings="*res://scripts/settings.gd"
|
||||
network="*res://scripts/network.gd"
|
||||
yau07="*res://scripts/yau07.gd"
|
||||
capsrpb="*res://scripts/capsrpb.gd"
|
||||
table="*res://table/table.gd"
|
||||
@@ -60,7 +57,6 @@ yemsconsts="*res://scripts/yems-consts.gd"
|
||||
interfer="*res://scripts/interfer.gd"
|
||||
hotkeys="*res://scripts/hotkeys.gd"
|
||||
mercator="*res://scripts/mercator.gd"
|
||||
modbus="*res://scripts/modbus.gd"
|
||||
tcp5p28="*res://scripts/tcp5p28.gd"
|
||||
sch3="*res://scripts/sch3.gd"
|
||||
spt25="*res://scripts/spt25.gd"
|
||||
|
||||
@@ -65,7 +65,11 @@ func _enter_tree() -> void:
|
||||
$back.scale = size
|
||||
$back.material.set('shader_parameter/scale', size / Vector2(20.0, 20.0))
|
||||
$button.set_toggle_mode(true)
|
||||
$button.connect('toggled', Callable(self, '_on_button_toggled'))
|
||||
$button.connect('toggled', _on_button_toggled)
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
$button.disconnect('toggled', _on_button_toggled)
|
||||
|
||||
|
||||
func set_toggle_mode(val: bool):
|
||||
|
||||
@@ -47,6 +47,9 @@ const COLUMN_AOA = 3
|
||||
const COLUMN_STATE = 4
|
||||
|
||||
|
||||
func on_rto_threat_unsel(_th_id): $table.clear_rows_selected()
|
||||
|
||||
|
||||
## Вызывается при нажатии указателем мыши на выбранный ряд.
|
||||
func on_row_pressed(i_row: int):
|
||||
$table.clear_rows_selected()
|
||||
@@ -148,5 +151,3 @@ func map_th_to_row(ecm) -> Array:
|
||||
row[COLUMN_STATE] = '%s' % INTERFER_STATE[ecm.svk]
|
||||
return row
|
||||
|
||||
|
||||
func on_rto_threat_unsel(_th_id): $table.clear_rows_selected()
|
||||
|
||||
@@ -12,7 +12,7 @@ patch_margin_top = 30
|
||||
patch_margin_right = 15
|
||||
patch_margin_bottom = 10
|
||||
script = ExtResource("2_ki0kf")
|
||||
text = ""
|
||||
text = "заголовок"
|
||||
|
||||
[node name="header" type="Label" parent="."]
|
||||
clip_contents = true
|
||||
@@ -22,6 +22,6 @@ anchor_right = 1.0
|
||||
offset_bottom = 22.0
|
||||
grow_horizontal = 2
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
text = "caption text"
|
||||
text = "заголовок"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
@@ -21,6 +21,19 @@ signal pressed(control: PanelContainer)
|
||||
fname = v
|
||||
$margin/vbox/title/fname.text = v
|
||||
|
||||
@export var state: int:
|
||||
set(v):
|
||||
state = v
|
||||
if v == 0:
|
||||
$margin/vbox/title/lbl_using.text = 'неизвестно'
|
||||
$margin/vbox/title/lbl_using.self_modulate = Color.CADET_BLUE
|
||||
elif v == 1:
|
||||
$margin/vbox/title/lbl_using.text = 'используется'
|
||||
$margin/vbox/title/lbl_using.self_modulate = Color.GREEN
|
||||
elif v == 2:
|
||||
$margin/vbox/title/lbl_using.text = 'отключено'
|
||||
$margin/vbox/title/lbl_using.self_modulate = Color.WHITE
|
||||
|
||||
|
||||
@export var state0: int:
|
||||
set(v):
|
||||
@@ -114,16 +127,23 @@ alignment = -1
|
||||
|
||||
[node name="title" type="GridContainer" parent="margin/vbox"]
|
||||
layout_mode = 2
|
||||
columns = 2
|
||||
|
||||
[node name="fname" type="Label" parent="margin/vbox/title"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 6
|
||||
size_flags_horizontal = 6
|
||||
theme_override_font_sizes/font_size = 17
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="lbl_using" type="Label" parent="margin/vbox/title"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
text = "неизвестно"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="table" type="GridContainer" parent="margin/vbox"]
|
||||
layout_mode = 2
|
||||
columns = 2
|
||||
|
||||
@@ -43,7 +43,7 @@ signal pressed(control: PanelContainer)
|
||||
|
||||
@export var state2: int:
|
||||
set(v):
|
||||
state1 = tools.clip_value(v, 0, textures.size() - 1)
|
||||
state2 = tools.clip_value(v, 0, textures.size() - 1)
|
||||
$margin/vbox/table/state2.texture = textures[v]
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://bs7h65e7bodp3"]
|
||||
[gd_scene load_steps=9 format=3 uid="uid://bs7h65e7bodp3"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://c4mdrmk7h638f" path="res://data/nine-patch-round.png" id="1_6olof"]
|
||||
[ext_resource type="Script" path="res://scenes/контроль/прибор.gd" id="1_46rp6"]
|
||||
[ext_resource type="PackedScene" uid="uid://ku8rdjoyscai" path="res://scenes/pribor-uyep/block-input.tscn" id="4_mrvir"]
|
||||
[ext_resource type="Script" path="res://scenes/pribor-uyep/spt25_view.gd" id="4_v0lil"]
|
||||
[ext_resource type="Script" path="res://scenes/pribor-uyep/spt25-view.gd" id="4_v0lil"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsixhjfesq6r4" path="res://scenes/pribor-uyep/block-output.tscn" id="5_x74mk"]
|
||||
[ext_resource type="PackedScene" uid="uid://btpc78gucr57f" path="res://scenes/контроль/элемент-я.tscn" id="6_60xs3"]
|
||||
[ext_resource type="PackedScene" uid="uid://5c24lfvp72en" path="res://scenes/pribor-uyep/sch3.tscn" id="7_13r50"]
|
||||
[ext_resource type="Script" path="res://scenes/pribor-uyep/sch3-view.gd" id="8_4t3jv"]
|
||||
|
||||
[node name="pribor_uyep" type="Control"]
|
||||
layout_mode = 3
|
||||
@@ -39,20 +41,20 @@ vertical_alignment = 1
|
||||
[node name="Label" type="Label" parent="."]
|
||||
self_modulate = Color(0.835294, 0.141176, 0.286275, 1)
|
||||
layout_mode = 0
|
||||
offset_left = 135.0
|
||||
offset_top = 990.0
|
||||
offset_right = 665.0
|
||||
offset_bottom = 1009.0
|
||||
offset_left = 145.0
|
||||
offset_top = 1055.0
|
||||
offset_right = 675.0
|
||||
offset_bottom = 1074.0
|
||||
text = "** Позиционные обозначения требуют уточнения **"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="spt25_A1" parent="." instance=ExtResource("6_60xs3")]
|
||||
layout_mode = 0
|
||||
offset_left = 135.0
|
||||
offset_top = 485.0
|
||||
offset_right = 375.0
|
||||
offset_bottom = 895.0
|
||||
offset_left = 175.0
|
||||
offset_top = 275.0
|
||||
offset_right = 415.0
|
||||
offset_bottom = 685.0
|
||||
script = ExtResource("4_v0lil")
|
||||
unit_name = "уарэп-спт25-1"
|
||||
fname = "СПТ-25-230-400"
|
||||
@@ -83,10 +85,10 @@ offset_bottom = 367.0
|
||||
|
||||
[node name="spt25_A2" parent="." instance=ExtResource("6_60xs3")]
|
||||
layout_mode = 0
|
||||
offset_left = 435.0
|
||||
offset_top = 485.0
|
||||
offset_right = 675.0
|
||||
offset_bottom = 895.0
|
||||
offset_left = 440.0
|
||||
offset_top = 275.0
|
||||
offset_right = 680.0
|
||||
offset_bottom = 685.0
|
||||
script = ExtResource("4_v0lil")
|
||||
unit_name = "уарэп-спт25-2"
|
||||
fname = "СПТ-25-230-400"
|
||||
@@ -114,3 +116,12 @@ offset_left = 15.0
|
||||
offset_top = 275.0
|
||||
offset_right = 225.0
|
||||
offset_bottom = 367.0
|
||||
|
||||
[node name="sch3" parent="." instance=ExtResource("7_13r50")]
|
||||
offset_left = 175.0
|
||||
offset_top = 714.0
|
||||
offset_right = 680.0
|
||||
offset_bottom = 929.0
|
||||
script = ExtResource("8_4t3jv")
|
||||
fname = "Щ3"
|
||||
rname = "A3"
|
||||
|
||||
47
scenes/pribor-uyep/sch3-view.gd
Normal file
47
scenes/pribor-uyep/sch3-view.gd
Normal file
@@ -0,0 +1,47 @@
|
||||
@tool
|
||||
|
||||
extends "res://scenes/контроль/элемент-я.gd"
|
||||
|
||||
|
||||
func on_data_received(data): pass
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
if Engine.is_editor_hint(): return
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
var unit = network.units[unit_key]
|
||||
unit.connect('responce_received', Callable(self, 'on_responce_received'))
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if Engine.is_editor_hint(): return
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
var unit = network.units[unit_key]
|
||||
unit.disconnect('responce_received', Callable(self, 'responce_received'))
|
||||
|
||||
|
||||
func on_line_changed(_unit):
|
||||
var items = get_tree().get_nodes_in_group('bits_items')
|
||||
for item in items:
|
||||
item.texture = textures[STATE_VAL.ERROR]
|
||||
|
||||
|
||||
func on_responce_received(addr: int, data: PackedByteArray):
|
||||
print_debug([addr, data])
|
||||
if (addr != 0) or (data.size() != 4):
|
||||
return
|
||||
var items = get_tree().get_nodes_in_group('bits_items')
|
||||
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
|
||||
427
scenes/pribor-uyep/sch3.tscn
Normal file
427
scenes/pribor-uyep/sch3.tscn
Normal file
@@ -0,0 +1,427 @@
|
||||
[gd_scene load_steps=12 format=3 uid="uid://5c24lfvp72en"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/контроль/элемент-я.gd" id="1_mb0l2"]
|
||||
[ext_resource type="Texture2D" uid="uid://c6nve6f8sfyj2" path="res://data/состояние-исправности-0.png" id="2_qglal"]
|
||||
[ext_resource type="Texture2D" uid="uid://dnreyfh3cd1k2" path="res://data/состояние-исправности-1.png" id="3_gqvwf"]
|
||||
[ext_resource type="Texture2D" uid="uid://c6booa8753u5t" path="res://data/состояние-исправности-2.png" id="4_2lj00"]
|
||||
[ext_resource type="Texture2D" uid="uid://c4mdrmk7h638f" path="res://data/nine-patch-round.png" id="5_eanbw"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_45hqb"]
|
||||
script/source = "@tool
|
||||
|
||||
extends MarginContainer
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
margins = [8, 8, 8, 8]
|
||||
|
||||
|
||||
@export var margins: Array:
|
||||
set(vals):
|
||||
add_theme_constant_override('margin_top', vals[0])
|
||||
add_theme_constant_override('margin_left', vals[1])
|
||||
add_theme_constant_override('margin_bottom', vals[2])
|
||||
add_theme_constant_override('margin_right', vals[3])
|
||||
get:
|
||||
var vals = [0, 0, 0, 0]
|
||||
vals[0] = get_theme_constant('margin_top')
|
||||
vals[1] = get_theme_constant('margin_left')
|
||||
vals[2] = get_theme_constant('margin_bottom')
|
||||
vals[3] = get_theme_constant('margin_right')
|
||||
return vals
|
||||
|
||||
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ox0yw"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_xxyaa"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_cd4fw"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_emtms"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_evx06"]
|
||||
|
||||
[node name="sch3" type="Control"]
|
||||
editor_description = "Элемент замены из ЗИП"
|
||||
custom_minimum_size = Vector2(32, 32)
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_left = 125.0
|
||||
offset_top = 635.0
|
||||
offset_right = 635.0
|
||||
offset_bottom = 865.0
|
||||
script = ExtResource("1_mb0l2")
|
||||
textures = [ExtResource("2_qglal"), ExtResource("3_gqvwf"), ExtResource("4_2lj00")]
|
||||
unit_name = "уарэп-щ3"
|
||||
|
||||
[node name="rect" type="NinePatchRect" parent="."]
|
||||
layout_mode = 2
|
||||
offset_right = 510.0
|
||||
offset_bottom = 230.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
texture = ExtResource("5_eanbw")
|
||||
draw_center = false
|
||||
region_rect = Rect2(0, 0, 63, 63)
|
||||
patch_margin_left = 17
|
||||
patch_margin_top = 17
|
||||
patch_margin_right = 17
|
||||
patch_margin_bottom = 15
|
||||
|
||||
[node name="margin" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
offset_right = 510.0
|
||||
offset_bottom = 230.0
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
script = SubResource("GDScript_45hqb")
|
||||
margins = [8, 8, 8, 8]
|
||||
|
||||
[node name="vbox" type="VBoxContainer" parent="margin"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="grid" type="GridContainer" parent="margin/vbox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 2
|
||||
columns = 3
|
||||
|
||||
[node name="state" type="TextureRect" parent="margin/vbox/grid"]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="fname" type="Label" parent="margin/vbox/grid"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 6
|
||||
theme_override_font_sizes/font_size = 17
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="rname" type="Label" parent="margin/vbox/grid"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 6
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 2
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="table" type="GridContainer" parent="margin/vbox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 6
|
||||
columns = 8
|
||||
|
||||
[node name="state0" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 0, 2, 0]
|
||||
|
||||
[node name="name0" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "УФ"
|
||||
|
||||
[node name="state1" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 1, 2, 1]
|
||||
|
||||
[node name="name1" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "РТР"
|
||||
|
||||
[node name="state2" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 2, 2, 2]
|
||||
|
||||
[node name="name2" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-Н.1"
|
||||
|
||||
[node name="state3" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 3, 2, 3]
|
||||
|
||||
[node name="name3" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-Н.2"
|
||||
|
||||
[node name="state4" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 4, 2, 4]
|
||||
|
||||
[node name="name4" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-Н.3"
|
||||
|
||||
[node name="state5" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 5, 2, 5]
|
||||
|
||||
[node name="name5" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-Н.4"
|
||||
|
||||
[node name="state6" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 6, 2, 6]
|
||||
|
||||
[node name="name6" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-В.1"
|
||||
|
||||
[node name="state7" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 7, 2, 7]
|
||||
|
||||
[node name="name7" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-В.2"
|
||||
|
||||
[node name="state8" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 8, 2, 8]
|
||||
|
||||
[node name="name8" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-В.3"
|
||||
|
||||
[node name="state9" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 9, 2, 9]
|
||||
|
||||
[node name="name9" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-В.4"
|
||||
|
||||
[node name="state10" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 10, 2, 10]
|
||||
|
||||
[node name="name10" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-К.1"
|
||||
|
||||
[node name="state11" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [0, 11, 2, 11]
|
||||
|
||||
[node name="name11" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-К.2"
|
||||
|
||||
[node name="state12" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 0, 3, 0]
|
||||
|
||||
[node name="name12" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-К.3"
|
||||
|
||||
[node name="state13" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 1, 3, 1]
|
||||
|
||||
[node name="name13" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ПРД-К.4"
|
||||
|
||||
[node name="state14" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 2, 3, 2]
|
||||
|
||||
[node name="name14" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "Бл. по вент."
|
||||
|
||||
[node name="state15" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 3, 3, 3]
|
||||
|
||||
[node name="name15" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "ДУ"
|
||||
|
||||
[node name="state16" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 7, 3, 7]
|
||||
|
||||
[node name="name16" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "Вент. РТР"
|
||||
|
||||
[node name="state17" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 8, 3, 8]
|
||||
|
||||
[node name="name17" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "Вент. ПРД.1"
|
||||
|
||||
[node name="state18" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 9, 3, 9]
|
||||
|
||||
[node name="name18" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "Вент. ПРД.2"
|
||||
|
||||
[node name="state19" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 10, 3, 10]
|
||||
|
||||
[node name="name19" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "Вент. ПРД.3"
|
||||
|
||||
[node name="state20" type="TextureRect" parent="margin/vbox/table" groups=["bits_items"]]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_qglal")
|
||||
expand_mode = 1
|
||||
metadata/bits = [1, 11, 3, 11]
|
||||
|
||||
[node name="name20" type="Label" parent="margin/vbox/table"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 17
|
||||
text = "Вент. ПРД.4"
|
||||
|
||||
[node name="button" type="Button" parent="."]
|
||||
layout_mode = 2
|
||||
offset_right = 510.0
|
||||
offset_bottom = 230.0
|
||||
theme_override_styles/normal = SubResource("StyleBoxEmpty_ox0yw")
|
||||
theme_override_styles/hover = SubResource("StyleBoxEmpty_xxyaa")
|
||||
theme_override_styles/pressed = SubResource("StyleBoxEmpty_cd4fw")
|
||||
theme_override_styles/disabled = SubResource("StyleBoxEmpty_emtms")
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_evx06")
|
||||
|
||||
[connection signal="resized" from="." to="." method="_on_resized"]
|
||||
[connection signal="pressed" from="button" to="." method="_on_button_pressed"]
|
||||
59
scenes/pribor-uyep/spt25-view.gd
Normal file
59
scenes/pribor-uyep/spt25-view.gd
Normal file
@@ -0,0 +1,59 @@
|
||||
@tool
|
||||
|
||||
extends "res://scenes/контроль/элемент-я.gd"
|
||||
|
||||
|
||||
func on_line_changed(unit):
|
||||
if not unit.online:
|
||||
state = STATE_VAL.NONE
|
||||
$block_output.state0 = STATE_VAL.NONE
|
||||
$block_output.state1 = STATE_VAL.NONE
|
||||
$block_output.state2 = STATE_VAL.NONE
|
||||
$block_input1.state = STATE_VAL.NONE
|
||||
$block_input1.state0 = STATE_VAL.NONE
|
||||
$block_input1.state1 = STATE_VAL.NONE
|
||||
$block_input1.state2 = STATE_VAL.NONE
|
||||
$block_input2.state = STATE_VAL.NONE
|
||||
$block_input2.state0 = STATE_VAL.NONE
|
||||
$block_input2.state1 = STATE_VAL.NONE
|
||||
$block_input2.state2 = STATE_VAL.NONE
|
||||
|
||||
|
||||
func on_data_received(data: PackedByteArray):
|
||||
|
||||
# Сеть 1. Использование
|
||||
$block_input1.state = STATE_VAL.GOOD if data[4] & (1 << 5) else STATE_VAL.ERROR
|
||||
# Сеть 1. Вход
|
||||
$block_input1.state0 = STATE_VAL.GOOD if ((data[4] & (1 << 1)) == 0) and ((data[4] & (1 << 3)) == 0) else STATE_VAL.ERROR
|
||||
# Сеть 1. Неисправность блока инвертора 1 канала
|
||||
$block_input1.state1 = STATE_VAL.GOOD if (data[6] & (1 << 2)) == 0 else STATE_VAL.ERROR
|
||||
# Сеть 1. Перегрев 1 канала
|
||||
$block_input1.state2 = STATE_VAL.GOOD if (data[5] & (1 << 3)) == 0 else STATE_VAL.ERROR
|
||||
|
||||
# Сеть 2. Использование
|
||||
$block_input2.state = STATE_VAL.GOOD if data[4] & (1 << 6) else STATE_VAL.ERROR
|
||||
# Сеть 2. Вход
|
||||
$block_input2.state0 = STATE_VAL.GOOD if ((data[4] & (1 << 2)) == 0) and ((data[4] & (1 << 4)) == 0) else STATE_VAL.ERROR
|
||||
# Сеть 2. Неисправность блока инвертора 2 канала
|
||||
$block_input2.state1 = STATE_VAL.GOOD if (data[6] & (1 << 3)) == 0 else STATE_VAL.ERROR
|
||||
# Сеть 2. Перегрев 2 канала
|
||||
$block_input2.state2 = STATE_VAL.GOOD if (data[5] & (1 << 4)) == 0 else STATE_VAL.ERROR
|
||||
|
||||
# Неисправность, напряжение меньше номинального, напряжение выше номинального
|
||||
$block_output.state0 = STATE_VAL.GOOD if ((data[4] & (1 << 0)) == 0) and ((data[4] & (1 << 7)) == 0) and ((data[5] & (1 << 2)) == 0) else STATE_VAL.ERROR
|
||||
# Перегрузка и короткое замыкание по выходу
|
||||
$block_output.state1 = STATE_VAL.GOOD if ((data[5] & (1 << 0)) == 0) and ((data[5] & (1 << 1)) == 0) else STATE_VAL.ERROR
|
||||
# Критическая температура
|
||||
$block_output.state2 = STATE_VAL.GOOD if ((data[5] & (1 << 5)) == 0) else STATE_VAL.ERROR
|
||||
|
||||
# Обобщённое состояние
|
||||
state = STATE_VAL.GOOD \
|
||||
if $block_input1.state1 == STATE_VAL.GOOD \
|
||||
and $block_input1.state2 == STATE_VAL.GOOD \
|
||||
and $block_input2.state0 == STATE_VAL.GOOD \
|
||||
and $block_input2.state1 == STATE_VAL.GOOD \
|
||||
and $block_input2.state2 == STATE_VAL.GOOD \
|
||||
and $block_output.state0 == STATE_VAL.GOOD \
|
||||
and $block_output.state1 == STATE_VAL.GOOD \
|
||||
and $block_output.state2 == STATE_VAL.GOOD \
|
||||
else STATE_VAL.ERROR
|
||||
@@ -1,45 +0,0 @@
|
||||
@tool
|
||||
|
||||
extends "res://scenes/контроль/элемент-я.gd"
|
||||
|
||||
@export var unit_name: String = ''
|
||||
|
||||
enum STATE_VAL
|
||||
{
|
||||
NONE = 0,
|
||||
GOOD = 1,
|
||||
ERROR = 2
|
||||
}
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
var unit = repnetwork.units[unit_key]
|
||||
unit.connect('data_received', on_data_received.bind(unit))
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
var unit = repnetwork.units[unit_key]
|
||||
unit.disconnect('data_received', on_data_received)
|
||||
|
||||
|
||||
func on_data_received(data, unit):
|
||||
# Неисправность, напряжение на выходе меньше номинального
|
||||
$block_output.state0 = STATE_VAL.GOOD if (data[4] & (1 << 0)) == 0 else STATE_VAL.ERROR
|
||||
# Перегрузка и короткое замыкание по выходу
|
||||
$block_output.state1 = STATE_VAL.GOOD if ((data[5] & (1 << 0)) == 0) or ((data[5] & (1 << 1)) == 0) else STATE_VAL.ERROR
|
||||
# Критическая температура
|
||||
$block_output.state2 = STATE_VAL.GOOD if ((data[5] & (1 << 5)) == 0) else STATE_VAL.ERROR
|
||||
# Сеть 1. Вход
|
||||
$block_input1.state0 = STATE_VAL.GOOD if ((data[4] & (1 << 1)) == 0) or ((data[4] & (1 << 3)) == 0) else STATE_VAL.ERROR
|
||||
# Сеть 2. Вход
|
||||
$block_input2.state0 = STATE_VAL.GOOD if ((data[4] & (1 << 2)) == 0) or ((data[4] & (1 << 4)) == 0) else STATE_VAL.ERROR
|
||||
# Неисправность блока инвертора 1 канала
|
||||
$block_input1.state1 = STATE_VAL.GOOD if (data[6] & (1 << 2)) == 0 else STATE_VAL.ERROR
|
||||
# Неисправность блока инвертора 2 канала
|
||||
$block_input2.state1 = STATE_VAL.GOOD if (data[6] & (1 << 3)) == 0 else STATE_VAL.ERROR
|
||||
# Перегрев 1 канала
|
||||
$block_input1.state2 = STATE_VAL.GOOD if (data[5] & (1 << 3)) == 0 else STATE_VAL.ERROR
|
||||
# Перегрев 2 канала
|
||||
$block_input1.state2 = STATE_VAL.GOOD if (data[5] & (1 << 4)) == 0 else STATE_VAL.ERROR
|
||||
@@ -4,7 +4,7 @@ const TAB_TOSIGNAL_NAME = {0: 'режим_работа', 1: 'режим_конт
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
repnetwork.logger_page = $Журнал
|
||||
network.logger_page = $Журнал
|
||||
|
||||
|
||||
func _on_tab_changed(tab) -> void:
|
||||
|
||||
@@ -9,14 +9,11 @@ extends Control
|
||||
@export var fname: String:
|
||||
set(v):
|
||||
fname = v
|
||||
get:
|
||||
return fname
|
||||
|
||||
|
||||
@export var rname: String:
|
||||
set(v):
|
||||
rname = v
|
||||
get:
|
||||
return rname
|
||||
|
||||
|
||||
func set_header_text(header_text: String):
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
|
||||
extends Control
|
||||
|
||||
@export var textures: Array
|
||||
@export var unit_name: String = ''
|
||||
|
||||
|
||||
enum STATE_VAL {
|
||||
NONE = 0,
|
||||
GOOD = 1,
|
||||
ERROR = 2 }
|
||||
|
||||
|
||||
signal pressed(control: PanelContainer)
|
||||
|
||||
|
||||
@@ -9,6 +19,12 @@ func _on_button_pressed():
|
||||
emit_signal('pressed', self)
|
||||
|
||||
|
||||
@export var state: int:
|
||||
set(v):
|
||||
state = tools.clip_value(v, 0, textures.size() - 1)
|
||||
$margin/vbox/grid/state.texture = textures[v]
|
||||
|
||||
|
||||
@export var fname: String:
|
||||
set(v):
|
||||
fname = v
|
||||
@@ -26,9 +42,26 @@ func _on_button_pressed():
|
||||
$margin/vbox.alignment = v
|
||||
|
||||
|
||||
func _enter_tree() -> void: _on_resized()
|
||||
func _ready() -> void: call_deferred('_on_resized')
|
||||
|
||||
|
||||
func _on_resized() -> void:
|
||||
$rect.size = size
|
||||
$margin.size = size
|
||||
$button.size = size
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
if Engine.is_editor_hint(): return
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
var unit = network.units[unit_key]
|
||||
unit.connect('data_received', Callable(self, 'on_data_received'))
|
||||
unit.connect('line_changed', Callable(self, 'on_line_changed'))
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if Engine.is_editor_hint(): return
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
var unit = network.units[unit_key]
|
||||
unit.disconnect('data_received', Callable(self, 'on_data_received'))
|
||||
unit.disconnect('line_changed', Callable(self, 'on_line_changed'))
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
[gd_scene load_steps=9 format=3 uid="uid://btpc78gucr57f"]
|
||||
[gd_scene load_steps=12 format=3 uid="uid://btpc78gucr57f"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/контроль/элемент-я.gd" id="1_fwxi0"]
|
||||
[ext_resource type="Texture2D" uid="uid://c6nve6f8sfyj2" path="res://data/состояние-исправности-0.png" id="3_dktys"]
|
||||
[ext_resource type="Texture2D" uid="uid://dnreyfh3cd1k2" path="res://data/состояние-исправности-1.png" id="3_t4y6r"]
|
||||
[ext_resource type="Texture2D" uid="uid://c6booa8753u5t" path="res://data/состояние-исправности-2.png" id="4_bdhnj"]
|
||||
[ext_resource type="Texture2D" uid="uid://c4mdrmk7h638f" path="res://data/nine-patch-round.png" id="4_or1kj"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_45hqb"]
|
||||
@@ -48,6 +51,7 @@ anchors_preset = 0
|
||||
offset_right = 180.0
|
||||
offset_bottom = 155.0
|
||||
script = ExtResource("1_fwxi0")
|
||||
textures = [ExtResource("3_dktys"), ExtResource("3_t4y6r"), ExtResource("4_bdhnj")]
|
||||
|
||||
[node name="rect" type="NinePatchRect" parent="."]
|
||||
layout_mode = 2
|
||||
@@ -79,7 +83,13 @@ layout_mode = 2
|
||||
|
||||
[node name="grid" type="GridContainer" parent="margin/vbox"]
|
||||
layout_mode = 2
|
||||
columns = 2
|
||||
columns = 3
|
||||
|
||||
[node name="state" type="TextureRect" parent="margin/vbox/grid"]
|
||||
custom_minimum_size = Vector2(24, 24)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("3_dktys")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="fname" type="Label" parent="margin/vbox/grid"]
|
||||
self_modulate = Color(1, 1, 1, 0.627451)
|
||||
@@ -92,7 +102,7 @@ vertical_alignment = 1
|
||||
|
||||
[node name="rname" type="Label" parent="margin/vbox/grid"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_horizontal = 10
|
||||
size_flags_vertical = 6
|
||||
theme_override_font_sizes/font_size = 22
|
||||
horizontal_alignment = 2
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
@tool
|
||||
|
||||
class_name work extends Panel
|
||||
|
||||
## Основной скрипт для режима "Работа".
|
||||
|
||||
@@ -19,6 +19,7 @@ const IN_SET_ROW: Array = [CellLineEdit, CellLEEmpty, CellLEEmpty, CellLEEmpty,
|
||||
|
||||
|
||||
var g_boards: Dictionary ## Словарь плат ЭМС.
|
||||
var active_board = null ## Активная плата ЭМС
|
||||
var posx: int = 125 ## Позиция элементов по x.
|
||||
var posy: int = 70 ## Позиция элементов по y.
|
||||
|
||||
@@ -29,6 +30,9 @@ func _ready() -> void:
|
||||
|
||||
## Инициализация основных элементов экрана ЭМС.
|
||||
func init_boards():
|
||||
var unit_key = settings.get_unit_key('уарэп-эмс')
|
||||
var unit_ems = network.units[unit_key]
|
||||
|
||||
# Выставление позиций элементов ЭМС на экране
|
||||
$scrollin.set_position(Vector2(posx,posy))
|
||||
$scrollout.set_position(Vector2(posx + 650,posy))
|
||||
@@ -40,10 +44,12 @@ func init_boards():
|
||||
$btn_connect.set_position(Vector2(posx + 590,posy - 25))
|
||||
$btn_disconnect.set_position(Vector2(posx + 587,posy + 675))
|
||||
|
||||
g_boards['КЭМС-Б'] = yemsboards.EmsBoard.new(0, 0x130, yemsconsts.INPUT_KEMS, yemsconsts.OUTPUT_KEMS)
|
||||
g_boards['ЭМС-Б1'] = yemsboards.EmsBoard.new(1, 0x110, yemsconsts.INPUT_EMS1, yemsconsts.OUTPUT_EMS1)
|
||||
g_boards['ЭМС-Б2'] = yemsboards.EmsBoard.new(2, 0x120, yemsconsts.INPUT_EMS2, yemsconsts.OUTPUT_EMS2)
|
||||
|
||||
g_boards['КЭМС-Б'] = yemsboards.EmsBoard.new(0, 0x130, yemsconsts.INPUT_KEMS, yemsconsts.OUTPUT_KEMS, unit_ems)
|
||||
g_boards['ЭМС-Б1'] = yemsboards.EmsBoard.new(1, 0x110, yemsconsts.INPUT_EMS1, yemsconsts.OUTPUT_EMS1, unit_ems)
|
||||
g_boards['ЭМС-Б2'] = yemsboards.EmsBoard.new(2, 0x120, yemsconsts.INPUT_EMS2, yemsconsts.OUTPUT_EMS2, unit_ems)
|
||||
|
||||
active_board = g_boards['КЭМС-Б']
|
||||
|
||||
init_tbl_in()
|
||||
$scrollin/tbl_in.pin_header($scrollin, self)
|
||||
init_tbl_out()
|
||||
@@ -52,15 +58,14 @@ func init_boards():
|
||||
$scrl_out_set/tbl_out_set.pin_header($scrl_out_set, self)
|
||||
init_tbl_files()
|
||||
$scrl_files/tbl_files.pin_header($scrl_files, self)
|
||||
|
||||
var unit_key = repsettings.get_unit_key('уарэп-эмс')
|
||||
var unit = repnetwork.units[unit_key]
|
||||
unit.connect('data_received', Callable(self, 'on_data_ems_received'))
|
||||
|
||||
unit_ems.connect('data_received', Callable(self, 'on_data_ems_received'))
|
||||
unit_ems.connect('command_done', Callable(self, 'on_command_done'))
|
||||
$btn_connect.connect('pressed', Callable(self, 'on_btn_connect'))
|
||||
$btn_disconnect.connect('pressed', Callable(self, 'on_btn_disconnect'))
|
||||
$btn_flash_read.button_connect('pressed', Callable(self, 'on_btn_flash_read').bind($btn_flash_read))
|
||||
$btn_flash_write.button_connect('pressed', Callable(self, 'on_btn_flash_write').bind($btn_flash_write))
|
||||
|
||||
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки disconnect.
|
||||
@@ -126,9 +131,9 @@ func init_tbl_in():
|
||||
$scrollin/tbl_in.add_row(row_type)
|
||||
var row_index : int = $scrollin/tbl_in.get_rows_count() - 1
|
||||
var params : Array = item[1]
|
||||
var in_dev: yemsdevs.InDev = yemsdevs.InDev.new(item[0], params, row_index)
|
||||
var in_dev: yemsdevs.InDev = yemsdevs.InDev.new(item[0], params, row_index, g_boards[board].base_addr_isa)
|
||||
g_boards[board].in_devs[in_dev.id] = in_dev
|
||||
in_dev.board = board
|
||||
in_dev.isa_addr = g_boards[board].base_addr_isa
|
||||
for i in range(len(row_type)):
|
||||
if i < len(params):
|
||||
var node = $scrollin/tbl_in.get_node2(i, row_index)
|
||||
@@ -209,9 +214,10 @@ func init_tbl_out():
|
||||
$scrollout/tbl_out.add_row([CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState, CellLineEdit])
|
||||
var row_index : int = $scrollout/tbl_out.get_rows_count() - 1
|
||||
var params : Array = item[1]
|
||||
var out_dev = yemsdevs.OutDev.new(item[0], params, row_index)
|
||||
var out_dev = yemsdevs.OutDev.new(item[0], params, row_index, g_boards[board].base_addr_isa)
|
||||
g_boards[board].out_devs[out_dev.id] = out_dev
|
||||
out_dev.set_default_mode()
|
||||
out_dev.board = board
|
||||
out_dev.isa_addr = g_boards[board].base_addr_isa
|
||||
for i in range(len(header_text)):
|
||||
var cell = $scrollout/tbl_out.get_node2(i, row_index)
|
||||
if i < len(params):
|
||||
@@ -219,7 +225,7 @@ func init_tbl_out():
|
||||
cell.editable = false
|
||||
$scrollout/tbl_out.set_node_user_data(i, row_index, [out_dev, board])
|
||||
if i in COLUMN_OPTS_BTN:
|
||||
cell.text = out_dev.mode
|
||||
cell.text = OUT_MODE[out_dev.mode]
|
||||
$scrollout/tbl_out.set_columns_min_size([250, 100, 70, 70, 70, 100])
|
||||
$scrollout/tbl_out.set_columns_alignments(yams_alligment_out)
|
||||
$scrollout/tbl_out.connect('row_pressed', Callable(self, 'on_row_pressed_out'))
|
||||
@@ -277,9 +283,7 @@ func set_out_dev(dev):
|
||||
var mode = $scrl_out_set/tbl_out_set.get_node2(5, 0)
|
||||
for opt in OUT_MODE:
|
||||
mode.add_item(opt)
|
||||
var mode_index: int = OUT_MODE.find(dev.mode)
|
||||
if mode_index != -1:
|
||||
mode.select(mode_index)
|
||||
mode.select(dev.mode)
|
||||
|
||||
|
||||
## Выбор входного или выходного устройства.[br]
|
||||
@@ -373,5 +377,22 @@ func on_row_pressed(i_row: int, tbl):
|
||||
|
||||
|
||||
func on_data_ems_received(unit):
|
||||
print_debug(unit.status)
|
||||
|
||||
for board in g_boards.values():
|
||||
board.set_status(unit.status)
|
||||
if active_board.state_read == active_board.WAIT:
|
||||
if board.online and not board.read_done:
|
||||
active_board = board
|
||||
active_board.state_read = active_board.READ
|
||||
active_board.start_rw_kems(true)
|
||||
for i_row in range($scrollin/tbl_in.get_rows_count()):
|
||||
var state_pic = ($scrollin/tbl_in.get_node2(4, i_row))
|
||||
var dev = $scrollin/tbl_in.get_node_user_data(4, i_row)[0]
|
||||
state_pic.set_frame(dev.state)
|
||||
for i_row in range($scrollout/tbl_out.get_rows_count()):
|
||||
var state_pic = ($scrollout/tbl_out.get_node2(4, i_row))
|
||||
var dev = $scrollout/tbl_out.get_node_user_data(4, i_row)[0]
|
||||
state_pic.set_frame(dev.state)
|
||||
|
||||
|
||||
func on_command_done(unit_ems):
|
||||
active_board.on_command_done(unit_ems)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/эмс/эмс.gd" id="1_mk57x"]
|
||||
[ext_resource type="PackedScene" uid="uid://da7w3vkhadfwe" path="res://scenes/button-flat/button-flat.tscn" id="2_eju8r"]
|
||||
[ext_resource type="Texture2D" uid="uid://dd60btbqnpiqw" path="res://data/document-new-0.png" id="3_w7rqa"]
|
||||
[ext_resource type="Texture2D" uid="uid://nm7cpjw6rs51" path="res://data/document-new-0.png" id="3_w7rqa"]
|
||||
[ext_resource type="Texture2D" uid="uid://coqg6wsftvtxr" path="res://data/document-save-0.png" id="4_gyaoq"]
|
||||
[ext_resource type="Texture2D" uid="uid://cywuevvpkxl7v" path="res://data/edit-copy-0.png" id="5_dxpqo"]
|
||||
[ext_resource type="Texture2D" uid="uid://7h55yvh84cve" path="res://data/connect.png" id="6_axj2m"]
|
||||
|
||||
@@ -8,18 +8,11 @@ const ONLINE_TIMEOUT = 3000 ## Время ожидания пакета от К
|
||||
const BUFFER_SIZE = 2048 ## Размер приёмного буфера для датаграмм.
|
||||
|
||||
|
||||
class CapsRpb:
|
||||
signal line_changed(unit: CapsRpb) ## Сигнал состояние связи изменилось.
|
||||
signal data_received(unit: CapsRpb) ## Сигнал данные приняты.
|
||||
signal command_fail(unit: CapsRpb) ## Сигнал при не выполнении команды.
|
||||
signal parse_error(unit: CapsRpb, msg: String) ## Сигнал ошибки разбора сообщения.
|
||||
class CapsRpb extends unit.Unit:
|
||||
|
||||
static var json_conv: = JSON.new()
|
||||
var online: = false ## Состояние связи с источником сообщений.
|
||||
var name: String ## Имя экземпляра.
|
||||
var json_dic: Dictionary ## Аппарат для разбора сообщений.
|
||||
var tick: = 0 ## Тик время последнего обновления, мс.
|
||||
var tx_data: = PackedByteArray() ## Пакет для отправки.
|
||||
var tx_stack: Array ## Массив пакетов для отправки.
|
||||
|
||||
func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
@@ -44,6 +37,7 @@ class CapsRpb:
|
||||
emit_signal('line_changed', self)
|
||||
if len(tx_stack):
|
||||
tx_data = tx_stack[0]
|
||||
tx_len = len(tx_data)
|
||||
tx_stack.remove_at(0)
|
||||
return Error.OK
|
||||
else:
|
||||
|
||||
@@ -97,10 +97,10 @@ func _ready():
|
||||
var ecms: Dictionary = {} ## Словарь помех.
|
||||
for i in range(ID_INTERFERS_LEN): # Заполняет массив ID целей
|
||||
id_array.append(i + 1)
|
||||
var unit_key = repsettings.get_unit_key('уарэп-капсрпб')
|
||||
var unit = repnetwork.units[unit_key]
|
||||
var unit_5p28_key = repsettings.get_unit_key('уарэп-5п28')
|
||||
var unit_5p28 = repnetwork.units_tcp[unit_5p28_key]
|
||||
var unit_key = settings.get_unit_key('уарэп-капсрпб')
|
||||
var unit = network.units[unit_key]
|
||||
var unit_5p28_key = settings.get_unit_key('уарэп-5п28')
|
||||
var unit_5p28 = network.units_tcp[unit_5p28_key]
|
||||
var timer_check_state: = Timer.new()
|
||||
add_child(timer_check_state)
|
||||
var resend_timeout = ProjectSettings.get_setting('application/interfer/resend_timeout', 1000.0)
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
class_name mod_bus extends Node
|
||||
|
||||
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды.
|
||||
|
||||
class ModbusClient:
|
||||
|
||||
## Состояние автомата выполнения команды.
|
||||
enum CmdState {
|
||||
DONE, ## Команда выполнена.
|
||||
FAIL, ## Команда не выполнена.
|
||||
SEND, ## Буфер готов для отправки.
|
||||
WAIT ## Ожидание выполнения.
|
||||
}
|
||||
|
||||
var name: String
|
||||
var unit: = 1 ## Адрес устройства Modbus.
|
||||
var cmd_state: = CmdState.DONE ## Код текущей команды.
|
||||
var tx_data: PackedByteArray ## Данные для отправки.
|
||||
var online: = false ## Флаг. Если установлен, устройство на связи. Активный уровень - [b]true[/b].
|
||||
var tick_rx: = 0 ## Время приёма крайнего сообщения.
|
||||
var tick_tx: = 0 ## Время отправки крайнего сообщения.
|
||||
|
||||
static var json_conv: = JSON.new()
|
||||
|
||||
signal command_done() ## Вызывается при успешном выполнении команды.
|
||||
signal command_fail(unit: ModbusClient) ## Вызывается при возникновении ошибки во время выполнения команды.
|
||||
signal line_changed(unit: ModbusClient) ## Вызывается при смене состояния связи с ячейкой.
|
||||
signal data_received() ## Вызывается при приёме сообщения, до его разбора.
|
||||
signal parse_failed(msg: String) ## Вызывается при возникновении ошибки во время разбора пакета. Передаёт сообщение об ошибке.
|
||||
|
||||
signal responce_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения.
|
||||
signal info_received(msg: String) ## Вызывается при получении информационного сообщения.
|
||||
signal except_received(msg: String) ## Вызывается при получении сообщения об исключительной ситуации.
|
||||
|
||||
func _init(nm: String, u: int = 1):
|
||||
unit = u
|
||||
name = nm
|
||||
|
||||
## Изменяет состояние. Вызывать периодически.[br]
|
||||
## [param tick] - Текущщее время в мс.[br]
|
||||
func process(tick: int):
|
||||
if online and ((tick - tick_rx) > ONLINE_TIMEOUT):
|
||||
online = false
|
||||
emit_signal('line_changed', self)
|
||||
if (cmd_state == CmdState.WAIT) or (cmd_state == CmdState.SEND):
|
||||
cmd_state = CmdState.FAIL
|
||||
emit_signal('command_fail', self)
|
||||
var rc = Error.ERR_BUSY
|
||||
if cmd_state == CmdState.SEND:
|
||||
rc = Error.OK
|
||||
tick_tx = tick
|
||||
cmd_state = CmdState.WAIT
|
||||
return rc
|
||||
|
||||
## Производит разбор принятых данных. Вызывать при приёме данных на сокете.[br]
|
||||
## [param data] - Данные принятые на сокете.[br]
|
||||
## [param tick] - Текущщее время в мс.[br]
|
||||
func parse(data: PackedByteArray, tick: int) -> bool:
|
||||
tick_rx = tick
|
||||
if not online:
|
||||
online = true
|
||||
emit_signal('line_changed', self)
|
||||
var utf8_data = data.get_string_from_utf8()
|
||||
if Error.OK == json_conv.parse(utf8_data):
|
||||
emit_signal('data_received')
|
||||
var message: Dictionary = json_conv.get_data()
|
||||
if message.has('code') and message.has('data'):
|
||||
var rc: = true
|
||||
var message_code = message['code']
|
||||
var message_data = message['data']
|
||||
match message_code:
|
||||
'response':
|
||||
var addr = message_data[0]
|
||||
var regs = message_data.slice(1)
|
||||
emit_signal('responce_received', addr, regs)
|
||||
'info':
|
||||
var msg = message['data']
|
||||
emit_signal('info_received', msg)
|
||||
'exception':
|
||||
var msg = message['data']
|
||||
emit_signal('except_received', msg)
|
||||
rc = false
|
||||
_:
|
||||
var msg: String = 'код команды \"%s\" - не распознан' % message_code
|
||||
emit_signal('parse_failed', msg)
|
||||
rc = false
|
||||
if (cmd_state == CmdState.WAIT) and rc:
|
||||
cmd_state = CmdState.DONE
|
||||
emit_signal('command_done')
|
||||
elif (cmd_state == CmdState.WAIT) and (not rc):
|
||||
cmd_state = CmdState.FAIL
|
||||
emit_signal('command_fail', self)
|
||||
else:
|
||||
var message = json_conv.get_error_message()
|
||||
emit_signal('parse_failed', message)
|
||||
return true
|
||||
|
||||
## Отправляет команду "записать в регистры".[br]
|
||||
## [param addr] - Начальный адрес регистров.[br]
|
||||
## [param count] - Данные для записи в регистры от начального адреса.[br]
|
||||
func write(addr: int, data: Array) -> bool:
|
||||
if cmd_state != CmdState.DONE: return false
|
||||
var json_dict = {'code': 'write', 'data': [addr] + data}
|
||||
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
|
||||
## Отправляет команду "читать регистры хранения".[br]
|
||||
## [param addr] - Начальный адрес регистров.[br]
|
||||
## [param count] - Количество регистров от начального адреса.[br]
|
||||
func read_holdind(addr: int, count: int = 1) -> bool:
|
||||
if cmd_state != CmdState.DONE: return false
|
||||
var json_dict = {'code': 'read_holding', 'data': [addr, count]}
|
||||
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
|
||||
## Отправляет команду "читать регистры входов".[br]
|
||||
## [param addr] - Начальный адрес регистров.[br]
|
||||
## [param count] - Количество регистров от начального адреса.[br]
|
||||
func read_input(addr: int, count: int = 1) -> bool:
|
||||
if cmd_state != CmdState.DONE: return false
|
||||
var json_dict = {'code': 'read_input', 'data': [addr, count]}
|
||||
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
@@ -1,21 +1,24 @@
|
||||
@tool
|
||||
class_name rep_network extends Node
|
||||
|
||||
|
||||
const PROTOCOL_TYPES: = {'yau07tx': yau07.YaU07, 'json-capsrpb': capsrpb.CapsRpb, 'udp-json-mbcs': modbus.ModbusClient}
|
||||
const PROTOCOL_TYPES: = {'yau07tx': yau07.YaU07, 'json-capsrpb': capsrpb.CapsRpb, 'udp-json-mbcs': sch3.Sch3}
|
||||
const TCP_PROTO: = {'5p28': tcp5p28.TCP5P28}
|
||||
const SERIAL_PROTO: = {'uart': spt25.SPT25 }
|
||||
|
||||
var tick: int = 0
|
||||
|
||||
class Serial extends SerialPort:
|
||||
func send_to(data: PackedByteArray):
|
||||
write_raw(data)
|
||||
func send_to(data: PackedByteArray): return write_raw(data)
|
||||
func _to_string() -> String: return 'последовательный порт \"%s\" @ %d (%s)' % [self.port, self.baudrate, 'открыт' if is_open() else 'закрыт']
|
||||
|
||||
func try_open(parsing_proc: Callable):
|
||||
if not is_open():
|
||||
open(port)
|
||||
if is_open():
|
||||
data_received.connect(parsing_proc)
|
||||
start_monitoring(timeout)
|
||||
if is_open():
|
||||
return Error.OK
|
||||
var rc = open(port)
|
||||
if rc == Error.OK:
|
||||
data_received.connect(parsing_proc)
|
||||
start_monitoring(timeout)
|
||||
return rc
|
||||
|
||||
|
||||
class Socket extends PacketPeerUDP:
|
||||
@@ -56,11 +59,14 @@ var sock_capsrpb: Socket
|
||||
var logger_page: Node
|
||||
|
||||
|
||||
func on_serial_data(data, unit): unit.parse(data, tick)
|
||||
|
||||
|
||||
func create_socket(nm) -> Socket:
|
||||
var addr = repsettings.UnitProfiles[nm][1]
|
||||
var port = repsettings.UnitProfiles[nm][2][0]
|
||||
var broad = repsettings.UnitProfiles[nm][3]
|
||||
var bind = repsettings.UnitProfiles[nm][4]
|
||||
var addr = settings.UnitProfiles[nm][1]
|
||||
var port = settings.UnitProfiles[nm][2][0]
|
||||
var broad = settings.UnitProfiles[nm][3]
|
||||
var bind = settings.UnitProfiles[nm][4]
|
||||
var sock: = Socket.new()
|
||||
sock.set_broadcast_enabled(broad)
|
||||
var rc = Error.OK if not bind else sock.bind(port, addr)
|
||||
@@ -70,26 +76,22 @@ func create_socket(nm) -> Socket:
|
||||
|
||||
|
||||
func create_tcpsocket(nm) -> SocketTCP:
|
||||
var addr = repsettings.UnitProfiles[nm][1]
|
||||
var port = repsettings.UnitProfiles[nm][2][0]
|
||||
var addr = settings.UnitProfiles[nm][1]
|
||||
var port = settings.UnitProfiles[nm][2][0]
|
||||
var sock = SocketTCP.new()
|
||||
sock.unit_key = repsettings.get_unit_key(nm)
|
||||
sock.unit_key = settings.get_unit_key(nm)
|
||||
sock.listen(port, addr)
|
||||
log.message(log.INFO, '%s: сокет:%s:%d привязанный:' % [nm, addr, port])
|
||||
return sock
|
||||
|
||||
|
||||
func create_serial(nm) -> Serial:
|
||||
var port = repsettings.UnitProfiles[nm][1]
|
||||
var baud = repsettings.UnitProfiles[nm][2][0]
|
||||
var port = settings.UnitProfiles[nm][1]
|
||||
var baud = settings.UnitProfiles[nm][2][0]
|
||||
var sp: = Serial.new()
|
||||
sp.port = port
|
||||
sp.baudrate = baud
|
||||
sp.timeout = 20000
|
||||
var rc = sp.open(port)
|
||||
if rc != Error.OK:
|
||||
log.message(log.ERROR, 'Невозможно открыть порт \"%s\" для \"%s\"' % [port, nm])
|
||||
else:
|
||||
log.message(log.INFO, 'Последовательный порт \"%s\"@%d открыт для \"%s\"' % [port, baud, nm])
|
||||
return sp
|
||||
|
||||
|
||||
@@ -102,25 +104,25 @@ func _ready() -> void:
|
||||
sock_unicast = poll_sockets[0]
|
||||
sock_capsrpb = poll_sockets[2]
|
||||
|
||||
for unit_name in repsettings.UnitProfiles:
|
||||
var settings = repsettings.UnitProfiles[unit_name]
|
||||
var proto = settings[0]
|
||||
for unit_name in settings.UnitProfiles:
|
||||
var st = settings.UnitProfiles[unit_name]
|
||||
var proto = st[0]
|
||||
if proto in PROTOCOL_TYPES:
|
||||
var unit = PROTOCOL_TYPES[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
units[unit_key] = unit
|
||||
units_udp[unit_key] = unit
|
||||
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))
|
||||
if len(settings[2]) > 1:
|
||||
dst_ports[unit_key] = settings[2][1]
|
||||
if len(st[2]) > 1:
|
||||
dst_ports[unit_key] = st[2][1]
|
||||
else:
|
||||
dst_ports[unit_key] = settings[2][0]
|
||||
dst_ports[unit_key] = st[2][0]
|
||||
|
||||
if proto in TCP_PROTO:
|
||||
var unit = TCP_PROTO[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
units_tcp[unit_key] = unit
|
||||
if logger_page:
|
||||
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
@@ -128,7 +130,7 @@ func _ready() -> void:
|
||||
|
||||
if proto in SERIAL_PROTO:
|
||||
var unit = SERIAL_PROTO[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
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))
|
||||
@@ -136,16 +138,20 @@ func _ready() -> void:
|
||||
units_serial[unit_key] = unit
|
||||
units[unit_key] = unit
|
||||
serials[unit_key] = serial
|
||||
serial.try_open(unit.parse)
|
||||
var rc = serial.try_open(on_serial_data.bind(unit))
|
||||
if rc != Error.OK:
|
||||
log.message(log.ERROR, 'Невозможно открыть %s для \"%s\"' % [serial, unit_name])
|
||||
else:
|
||||
log.message(log.INFO, '%s для \"%s\"' % [serial, unit_name])
|
||||
|
||||
tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp[repsettings.get_unit_key('уарэп-5п28')]])
|
||||
tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp[settings.get_unit_key('уарэп-5п28')]])
|
||||
|
||||
for key in units: log.info('%s %s:%d' % [units[key].name, key[0], key[1]])
|
||||
for key in units_tcp: log.info('%s %s:%d' % [units_tcp[key].name, key[0], key[1]])
|
||||
for key in dst_ports: unit_keys[dst_ports[key]] = key
|
||||
|
||||
|
||||
func poll_receive(sock: Socket, tick: int) -> bool:
|
||||
func poll_receive(sock: Socket) -> bool:
|
||||
while sock.get_available_packet_count() > 0:
|
||||
var data: = sock.get_packet()
|
||||
var addr: = sock.get_packet_ip()
|
||||
@@ -159,7 +165,7 @@ func poll_receive(sock: Socket, tick: int) -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func poll_receive_tcp(sock: SocketTCP, tick: int) -> bool:
|
||||
func poll_receive_tcp(sock: SocketTCP) -> bool:
|
||||
if sock.is_connection_available(): # check if someone's trying to connect
|
||||
var client = sock.take_connection() # accept connection
|
||||
sock.peerstream.set_stream_peer(client) # bind peerstream to new client
|
||||
@@ -167,12 +173,12 @@ func poll_receive_tcp(sock: SocketTCP, tick: int) -> bool:
|
||||
if peer:
|
||||
var peer_len_data = peer.get_available_bytes()
|
||||
if peer_len_data > 0:
|
||||
get_client_data(sock, peer_len_data, peer, tick)
|
||||
get_client_data(sock, peer_len_data, peer)
|
||||
if sock.unit_key in units_tcp and sock.rx_all: units_tcp[sock.unit_key].parse(sock.rx_data, tick)
|
||||
return false
|
||||
|
||||
|
||||
func get_client_data(sock: SocketTCP, peer_len_data, peer, tick):
|
||||
func get_client_data(sock: SocketTCP, peer_len_data, peer):
|
||||
if tick - sock.rx_tick > sock.RX_TIMEOUT:
|
||||
sock.rx_all = true
|
||||
sock.rx_tick = tick
|
||||
@@ -205,11 +211,11 @@ func get_tcp_data(sock: SocketTCP, peer, len_rx):
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var tick = Time.get_ticks_msec()
|
||||
tick = Time.get_ticks_msec()
|
||||
for addr in units_udp:
|
||||
var unit = units[addr]
|
||||
match unit.process(tick):
|
||||
Error.OK: sock_unicast.send_to([addr[0], dst_ports[addr]], unit.tx_data)
|
||||
Error.OK: sock_unicast.send_to([addr[0], dst_ports[addr]], unit.tx_data.slice(0, unit.tx_len))
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s %s:%d' % [unit, addr[0], addr[1]])
|
||||
for key in units_serial:
|
||||
var unit = units_serial[key]
|
||||
@@ -223,5 +229,5 @@ func _process(_delta: float) -> void:
|
||||
match unit.process(tick):
|
||||
Error.OK: sock.send_to(unit.tx_data)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s' % unit)
|
||||
poll_receive_tcp(sock, tick)
|
||||
poll_sockets.any(func(sock): poll_receive(sock, tick))
|
||||
poll_receive_tcp(sock)
|
||||
poll_sockets.any(func(sock): poll_receive(sock))
|
||||
|
||||
139
scripts/sch3.gd
139
scripts/sch3.gd
@@ -1,26 +1,125 @@
|
||||
extends Node
|
||||
class_name sch_3 extends Node
|
||||
|
||||
var cnt: int = 0
|
||||
var rw: bool = true
|
||||
const ONLINE_TIMEOUT: int = 5000 ## Время ожидания данных
|
||||
const REQUEST_PERIOD: int = 3000 ## Переиод запроса, мс
|
||||
|
||||
func _ready():
|
||||
var unit_key = repsettings.get_unit_key('уарэп-щ3')
|
||||
var unit = repnetwork.units[unit_key]
|
||||
var timer = Timer.new()
|
||||
add_child(timer)
|
||||
unit.connect('command_fail', Callable(self, 'on_command_fail'))
|
||||
timer.connect('timeout', Callable(self, 'on_timer').bind(unit))
|
||||
timer.start(1.0)
|
||||
class Sch3 extends unit.Unit:
|
||||
|
||||
## Состояние автомата выполнения команды.
|
||||
enum CmdState {
|
||||
DONE, ## Команда выполнена.
|
||||
FAIL, ## Команда не выполнена.
|
||||
SEND, ## Буфер готов для отправки.
|
||||
WAIT ## Ожидание выполнения.
|
||||
}
|
||||
|
||||
var unit: = 1 ## Адрес устройства Modbus.
|
||||
var cmd_state: = CmdState.DONE ## Код текущей команды.
|
||||
var tick_rx: = 0 ## Время приёма крайнего сообщения.
|
||||
var tick_tx: = 0 ## Время отправки крайнего сообщения.
|
||||
|
||||
static var json_conv: = JSON.new()
|
||||
signal responce_received(addr: int, data: Array) ## Вызывается при получении сообщения c данными из регистров хранения.
|
||||
signal info_received(msg: String) ## Вызывается при получении информационного сообщения.
|
||||
signal except_received(msg: String) ## Вызывается при получении сообщения об исключительной ситуации.
|
||||
|
||||
func _init(nm: String, u: int = 1):
|
||||
unit = u
|
||||
name = nm
|
||||
|
||||
## Изменяет состояние. Вызывать периодически.[br]
|
||||
## [param tick] - Текущщее время в мс.[br]
|
||||
func process(tick: int):
|
||||
if online and ((tick - rx_tick) > ONLINE_TIMEOUT):
|
||||
online = false
|
||||
emit_signal('line_changed', self)
|
||||
if cmd_state == CmdState.WAIT:
|
||||
cmd_state = CmdState.FAIL
|
||||
emit_signal('command_fail', self)
|
||||
var rc = Error.ERR_BUSY
|
||||
if (tick - tx_tick) > REQUEST_PERIOD:
|
||||
if read_input(0, 4):
|
||||
tx_tick = tick
|
||||
cmd_state = CmdState.WAIT
|
||||
rc = Error.OK
|
||||
return rc
|
||||
|
||||
|
||||
func on_timer(unit):
|
||||
cnt +=1
|
||||
if rw:
|
||||
unit.write(0x0000, [cnt])
|
||||
else:
|
||||
unit.read_holdind(0x0000)
|
||||
rw = not rw
|
||||
## Производит разбор принятых данных. Вызывать при приёме данных на сокете.[br]
|
||||
## [param data] - Данные принятые на сокете.[br]
|
||||
## [param tick] - Текущщее время в мс.[br]
|
||||
func parse(data: PackedByteArray, tick: int) -> bool:
|
||||
rx_tick = tick
|
||||
if not online:
|
||||
online = true
|
||||
emit_signal('line_changed', self)
|
||||
var utf8_data = data.get_string_from_utf8()
|
||||
if Error.OK == json_conv.parse(utf8_data):
|
||||
emit_signal('data_received')
|
||||
var message: Dictionary = json_conv.get_data()
|
||||
if message.has('code') and message.has('data'):
|
||||
var rc: = true
|
||||
var message_code = message['code']
|
||||
var message_data = message['data']
|
||||
match message_code:
|
||||
'response':
|
||||
var addr = message_data[0]
|
||||
var regs = message_data.slice(1)
|
||||
emit_signal('responce_received', addr, regs)
|
||||
rc = true
|
||||
'info':
|
||||
var msg = message['data']
|
||||
emit_signal('info_received', msg)
|
||||
'exception':
|
||||
var msg = message['data']
|
||||
cmd_state = CmdState.FAIL
|
||||
emit_signal('except_received', msg)
|
||||
rc = false
|
||||
_:
|
||||
var msg: String = 'код команды \"%s\" - не распознан' % message_code
|
||||
cmd_state = CmdState.FAIL
|
||||
emit_signal('parse_failed', msg)
|
||||
rc = false
|
||||
if (cmd_state == CmdState.WAIT) and rc:
|
||||
cmd_state = CmdState.DONE
|
||||
emit_signal('command_done')
|
||||
elif (cmd_state == CmdState.WAIT) and (not rc):
|
||||
cmd_state = CmdState.FAIL
|
||||
emit_signal('command_fail', self)
|
||||
else:
|
||||
var message = json_conv.get_error_message()
|
||||
emit_signal('parse_failed', message)
|
||||
return true
|
||||
|
||||
## Отправляет команду "записать в регистры".[br]
|
||||
## [param addr] - Начальный адрес регистров.[br]
|
||||
## [param count] - Данные для записи в регистры от начального адреса.[br]
|
||||
func write(addr: int, data: Array) -> bool:
|
||||
if cmd_state != CmdState.DONE: return false
|
||||
var json_dict = {'code': 'write', 'data': [addr] + data}
|
||||
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
|
||||
tx_len = len(tx_data)
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
|
||||
func on_command_fail(unit):
|
||||
unit.cmd_state = unit.CmdState.DONE
|
||||
## Отправляет команду "читать регистры хранения".[br]
|
||||
## [param addr] - Начальный адрес регистров.[br]
|
||||
## [param count] - Количество регистров от начального адреса.[br]
|
||||
func read_holding(addr: int, count: int = 1) -> bool:
|
||||
if cmd_state != CmdState.DONE: return false
|
||||
var json_dict = {'code': 'read_holding', 'data': [addr, count]}
|
||||
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
|
||||
tx_len = len(tx_data)
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
|
||||
## Отправляет команду "читать регистры входов".[br]
|
||||
## [param addr] - Начальный адрес регистров.[br]
|
||||
## [param count] - Количество регистров от начального адреса.[br]
|
||||
func read_input(addr: int, count: int = 1) -> bool:
|
||||
if cmd_state != CmdState.DONE: return false
|
||||
var json_dict = {'code': 'read_input', 'data': [addr, count]}
|
||||
tx_data = JSON.stringify(json_dict).to_utf8_buffer()
|
||||
tx_len = len(tx_data)
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
|
||||
@@ -6,9 +6,9 @@ class_name rep_settings extends Node
|
||||
@export var UnitProfiles: = { \
|
||||
# Название | Протокол | Адрес | Порт | Широковещательное | Привязывать к адресу | Комментарий
|
||||
'уарэп-яу07-частный': ['yau07rx', '10.1.1.2', [50002], false, true, 'IP-адрес на котором принимают частные сообщения от ЯУ-07'],
|
||||
'уарэп-яу07-общий': ['yau07rx', '10.1.1.255', [50000], true, true, 'IP-адрес на котором принимают широковещательные сообщения от ЯУ-07'],
|
||||
'уарэп-яу07-общий': ['yau07rx', '*', [50000], true, true, 'IP-адрес на котором принимают широковещательные сообщения от ЯУ-07'],
|
||||
'уарэп-капсрпб': ['json-capsrpb', '127.0.0.1', [42023, 42022], false, true, 'IP-адрес на котором принимают сообщения от КАПС РПБ'],
|
||||
'уарэп-эмс': ['yau07tx', '10.1.1.52', [50027], false, false, 'IP-адрес ЯУ-07 прибора УФ'],
|
||||
'уарэп-эмс': ['yau07tx', '10.1.1.52', [50052], false, false, 'IP-адрес ЯУ-07 прибора УФ'],
|
||||
'уарэп-яу07-2в': ['yau07tx', '10.1.1.34', [50034], false, false, 'IP-адрес ЯУ-07 прибора ПРД-В'],
|
||||
'уарэп-яу07-2н': ['yau07tx', '10.1.1.33', [50033], false, false, 'IP-адрес ЯУ-07 прибора ПРД-Н'],
|
||||
'уарэп-яу07-2к': ['yau07tx', '10.1.1.35', [50035], false, false, 'IP-адрес ЯУ-07 прибора ПРД-К'],
|
||||
@@ -44,6 +44,5 @@ func _ready() -> void: log.info('Модуль настроек готов')
|
||||
|
||||
## Возвращает ключ устройства.
|
||||
func get_unit_key(unit_name: String) -> Array:
|
||||
assert(UnitProfiles.has(unit_name), 'ошибка: нет такого устройства \"%s\"' % unit_name)
|
||||
var item = UnitProfiles[unit_name]
|
||||
return [item[1], item[2][0]]
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
class_name spt25_unit extends Node
|
||||
|
||||
const ONLINE_TIMEOUT: int = 5000 ## Время ожидания данных
|
||||
const REQUEST_PERIOD: int = 3000 ## Переиод запроса, мс
|
||||
|
||||
class SPT25 extends unit.Unit:
|
||||
|
||||
var tx_tick: int = 0
|
||||
var req_period = 3000
|
||||
func _to_string() -> String: return String('СПТ-25: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
func _to_string() -> String: return String('СПТ-25 %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
|
||||
func _init(nm) -> void:
|
||||
self.name = nm
|
||||
@@ -19,14 +19,25 @@ class SPT25 extends unit.Unit:
|
||||
tx_data[6] = 0 # Контрольная сумма
|
||||
tx_data[7] = 0x7e # Флаги синхронизации пакета
|
||||
|
||||
func parse(rx_data: PackedByteArray):
|
||||
if not self.online:
|
||||
self.online = true
|
||||
|
||||
func parse(rx_data: PackedByteArray, tick: int):
|
||||
rx_tick = tick
|
||||
if not online:
|
||||
online = true
|
||||
emit_signal('line_changed', self)
|
||||
if rx_data.size() <= 6:
|
||||
emit_signal('parse_failed', self)
|
||||
return
|
||||
emit_signal('data_received', rx_data)
|
||||
|
||||
func process(delta: float):
|
||||
tick += delta
|
||||
if (tick - tx_tick) > req_period:
|
||||
return Error.OK
|
||||
return Error.ERR_BUSY
|
||||
|
||||
func process(tick: int):
|
||||
var rc: = Error.ERR_BUSY
|
||||
if (tick - tx_tick) > REQUEST_PERIOD:
|
||||
tx_tick = tick
|
||||
rc = Error.OK
|
||||
if online:
|
||||
if (tick - rx_tick) > ONLINE_TIMEOUT:
|
||||
online = false
|
||||
emit_signal('line_changed', self)
|
||||
return rc
|
||||
|
||||
@@ -27,30 +27,29 @@ const MOD_TYPES: Array = ['',
|
||||
'ofdm',]
|
||||
|
||||
const CU_STATE: Dictionary = {
|
||||
0:2, # Подготовка к выполнению
|
||||
1:1, # Выполняется
|
||||
2:9, # Ошибка в команде
|
||||
3:7, # Занят выполнением другого ЦУ
|
||||
4:9, # Неисправность
|
||||
0: 2, # Подготовка к выполнению
|
||||
1: 1, # Выполняется
|
||||
2: 9, # Ошибка в команде
|
||||
3: 7, # Занят выполнением другого ЦУ
|
||||
4: 9, # Неисправность
|
||||
}
|
||||
|
||||
class TCP5P28 extends unit.Unit:
|
||||
const PACK_TYPE_CMD: int = 1
|
||||
const PACK_TYPE_RES: int = 2
|
||||
const PACK_TYPE_CMD: int = 1
|
||||
const PACK_TYPE_RES: int = 2
|
||||
const CMD_TYPE_STATE: int = 1
|
||||
const CMD_TYPE_TH: int = 2
|
||||
const CMD_TYPE_IN: int = 3
|
||||
const CMD_TYPE_TH: int = 2
|
||||
const CMD_TYPE_IN: int = 3
|
||||
|
||||
signal get_threats(unit: TCP5P28) ## Сигнал запрос целей.
|
||||
signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания.
|
||||
|
||||
var rx_tick: = 0 ## Тик время последнего приёма, мс.
|
||||
var tx_stack: Array ## Массив пакетов для отправки.
|
||||
|
||||
func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
|
||||
func parse(data: PackedByteArray, now_tick: int):
|
||||
rx_tick = now_tick
|
||||
func parse(data: PackedByteArray, tick: int):
|
||||
rx_tick = tick
|
||||
if not online:
|
||||
online = true
|
||||
emit_signal('line_changed', self)
|
||||
@@ -65,8 +64,8 @@ class TCP5P28 extends unit.Unit:
|
||||
if cmd_type == CMD_TYPE_IN and external_cu:
|
||||
set_interfer(data)
|
||||
|
||||
func process(now_tick: int):
|
||||
if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT):
|
||||
func process(tick: int):
|
||||
if online and ((tick - rx_tick) > ONLINE_TIMEOUT):
|
||||
online = false
|
||||
emit_signal('line_changed', self)
|
||||
if len(tx_stack):
|
||||
|
||||
@@ -46,18 +46,18 @@ signal threats_resized(th: Dictionary)
|
||||
func _ready() -> void:
|
||||
log.info('Модуль обработки целей готов')
|
||||
var threats = {} ## Список целей. Индекс - <номер цели>
|
||||
var unit_key = repsettings.get_unit_key('уарэп-капсрпб')
|
||||
var unit = repnetwork.units[unit_key]
|
||||
var unit_5p28_key = repsettings.get_unit_key('уарэп-5п28')
|
||||
var unit_5p28 = repnetwork.units_tcp[unit_5p28_key]
|
||||
var unit_key = settings.get_unit_key('уарэп-капсрпб')
|
||||
var unit = network.units[unit_key]
|
||||
var unit_5p28_key = settings.get_unit_key('уарэп-5п28')
|
||||
var unit_5p28 = network.units_tcp[unit_5p28_key]
|
||||
var timer_check_lost: = Timer.new()
|
||||
var timer_aoa_update: = Timer.new()
|
||||
add_child(timer_check_lost)
|
||||
add_child(timer_aoa_update)
|
||||
unit.connect('data_received', Callable(self, 'on_data_capsrpb_received').bind(threats))
|
||||
unit_5p28.connect('get_threats', Callable(self, 'on_get_threats').bind(unit_5p28, threats))
|
||||
timer_check_lost.connect('timeout', Callable(self, 'on_timer_check_lost').bind(repsettings.ThreatParams.time_lost, threats))
|
||||
timer_check_lost.start(repsettings.ThreatParams.time_lost / 1000.0)
|
||||
timer_check_lost.connect('timeout', Callable(self, 'on_timer_check_lost').bind(settings.ThreatParams.time_lost, threats))
|
||||
timer_check_lost.start(settings.ThreatParams.time_lost / 1000.0)
|
||||
timer_aoa_update.connect('timeout', Callable(self, 'on_timer_aoa_update').bind(threats))
|
||||
timer_aoa_update.start(0.25)
|
||||
signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(threats))
|
||||
|
||||
@@ -74,7 +74,6 @@ func get_string_slice(s_in: String, s_out: Array, i0: int, i1: int):
|
||||
func pos_calc(freq: float, aoa: float, pos0: Vector2, r0: float, r1: float, f0: float, f1: float):
|
||||
var r = remap(freq, f0, f1, r0, r1)
|
||||
var aoa_rad = radians(aoa) - PI / 2.0
|
||||
|
||||
return Vector2(cos(aoa_rad), sin(aoa_rad)) * r + pos0
|
||||
|
||||
|
||||
@@ -112,11 +111,6 @@ func map_dec_to_rad(pos0: Vector2, pos: Vector2) -> Vector2:
|
||||
return Vector2(ang + 360.0 * float(ang < 0.0), hypot(x1, y1))
|
||||
|
||||
|
||||
## Переводит значение val из диапазона a0...a1 в диапазон b0...b1.
|
||||
func map_range(val: float, a0: float, a1: float, b0: float, b1: float) -> float:
|
||||
return (((val - a0) * (b1 - b0)) / (a1 - a0)) + b0
|
||||
|
||||
|
||||
## Возвращает [b]true[/b], если точка внутри заданного полигона.[br]
|
||||
## [param pos] - Проверяемая точка.[br]
|
||||
## [param p] - Координаты вершин полигона.[br]
|
||||
@@ -138,3 +132,31 @@ func is_point_in_polygon(pos: Vector2, p: PackedVector2Array) -> bool:
|
||||
func set_wordi(buf: PackedByteArray, index: int, val: int) -> void:
|
||||
buf[index] = val & 0xff
|
||||
buf[index + 1] = (val >> 8) & 0xff
|
||||
|
||||
|
||||
func set_bit(bits, index, val, mask = 0xfffffffffffffff):
|
||||
"""
|
||||
:param bits: прежние значения
|
||||
:param index: индекс бита
|
||||
:param val: новое значение бита
|
||||
:param mask:
|
||||
:return:
|
||||
мастер
|
||||
"""
|
||||
bits &= mask
|
||||
if val:
|
||||
bits |= 1 << index
|
||||
else:
|
||||
bits &= ~(1 << index)
|
||||
return (bits & mask)
|
||||
|
||||
|
||||
func set_bits(v, a, m):
|
||||
"""
|
||||
Устанавливает биты в соответствии с маской
|
||||
:param v: Прежние значения бит
|
||||
:param a: Новые значения бит
|
||||
:param m: Маска изменяемых бит
|
||||
:return: Изменённые значения бит
|
||||
"""
|
||||
return v & a & (~m) | (~v) & a & m | v & a & m | v & (~a) & (~m)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
class_name base_unit extends Node
|
||||
|
||||
## Базовый класс для управления подключаемыми устройствами
|
||||
|
||||
class Unit:
|
||||
signal line_changed(unit) ## Вызывается при изменение состояния связи
|
||||
signal line_changed(unit) ## Вызывается при изменении состояния связи
|
||||
signal command_done(unit) ## Вызывается после выполнения команды.
|
||||
signal command_fail(unit) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена.
|
||||
signal parse_failed(unit) ## Вызывается при обнаружении ошибки во входных данных
|
||||
signal data_received(unit) ## Вызывается по приёму данных
|
||||
signal data_received(data: PackedByteArray) ## Вызывается по приёму данных
|
||||
|
||||
var tick = 0.0 ## Текущее тик-время в мс.
|
||||
var tx_data: = PackedByteArray() ## Буфер отправленный.
|
||||
var tx_len = 0 ## Длина последнего отправленного пакета.
|
||||
var tx_data: = PackedByteArray() ## Буфер отправленный.
|
||||
var tx_len = 0 ## Длина последнего отправленного пакета.
|
||||
var tx_tick: int = 0
|
||||
var rx_tick: int = 0
|
||||
var online: bool
|
||||
var name: String
|
||||
func _init(nm) -> void: self.name = nm
|
||||
|
||||
@@ -2,8 +2,8 @@ class_name yau_07 extends Node
|
||||
|
||||
## Протокол ячейки ЯУ-07.
|
||||
|
||||
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды
|
||||
const RESEND_TIMEOUT = 0.3 ## Задержка для повторной отправки команды, секунды
|
||||
const ONLINE_TIMEOUT = 5000 ## Время ожидания пакета от ячейки, милисекунды
|
||||
const RESEND_TIMEOUT = 300 ## Задержка для повторной отправки команды, секунды
|
||||
const RETRY_COUNT = 5 ## Количество повторных отправок
|
||||
const BUFFER_SIZE = 2048 ## Размер буфера для приёма датаграмм
|
||||
|
||||
@@ -13,10 +13,14 @@ class YaU07 extends unit.Unit:
|
||||
|
||||
## Коды выполняемых команд.
|
||||
enum CmdCode {
|
||||
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07.
|
||||
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07.
|
||||
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07.
|
||||
READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07.
|
||||
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07
|
||||
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07
|
||||
ERASE_FLASH = 49, ## Код команды "стереть данные из FLASH" ячейки ЯУ-07
|
||||
WRITE_FLASH = 50, ## Код команды "записать данные в FLASH" ячейки ЯУ-07
|
||||
READ_FLASH = 51, ## Код команды "прочитать данные из FLASH" ячейки ЯУ-07
|
||||
LOAD_FLASH = 52, ## Код команды "записать данные из FLASH в КЭМС" ячейки ЯУ-07
|
||||
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07
|
||||
READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07
|
||||
}
|
||||
|
||||
## Состояние автомата выполнения команды.
|
||||
@@ -28,17 +32,20 @@ class YaU07 extends unit.Unit:
|
||||
FAIL ## Команда не выполнена.
|
||||
}
|
||||
|
||||
var cmd_num_rx: = 0 ## Номер команды принятый.
|
||||
var cmd_num_tx: = 0 ## Номер команды переданный.
|
||||
var cmd_state = CmdState.UNCK ## Состояние выполнения команды.
|
||||
var cmd_result: = 1 ## Результат выполнения команды. Устанавливается в ЯУ-07.
|
||||
var cmd_data: = PackedByteArray() ## Данные команды. Устанавливается в ЯУ-07.
|
||||
var cmd_retry = 0 ## Счётчик оставшихся попыток выполнить команду.
|
||||
var cmd_tick_tx = 0.0 ## Время последней отправки команды.
|
||||
var cmd_tick_rx = 0.0 ## Время последнего приёма команды.
|
||||
var status: = PackedByteArray() ## Поле "состояние прибора".
|
||||
var isa_ports = {} ## Результат выполнения команды "читать порт".
|
||||
var isa_block = {} ## Результат выполнения команды "читать массив из порта".
|
||||
var cmd_num_rx: = 0 ## Номер команды принятый
|
||||
var cmd_num_tx: = 0 ## Номер команды переданный
|
||||
var cmd_state = CmdState.UNCK ## Состояние выполнения команды
|
||||
var cmd_result: = 1 ## Результат выполнения команды. Устанавливается в ЯУ-07
|
||||
var cmd_data: = PackedByteArray() ## Данные команды. Устанавливается в ЯУ-07
|
||||
var cmd_retry = 0 ## Счётчик оставшихся попыток выполнить команду
|
||||
var cmd_code_rx = 0 ## Код последней выполненой команды
|
||||
var cmd_tick_tx = 0.0 ## Время последней отправки команды
|
||||
var cmd_tick_rx = 0.0 ## Время последнего приёма команды
|
||||
var status: = PackedByteArray() ## Поле "состояние прибора"
|
||||
var isa_ports = {} ## Результат выполнения команды "читать порт"
|
||||
var isa_block = {} ## Результат выполнения команды "читать массив из порта"
|
||||
var flash_data: = PackedByteArray() ## Данные прочитанные из Flash
|
||||
var flash_len: = 0 ## Длинна данных прочитанных из Flash
|
||||
|
||||
|
||||
func _to_string() -> String: return String('яу07: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
@@ -48,11 +55,9 @@ class YaU07 extends unit.Unit:
|
||||
self.name = nm
|
||||
tx_data.resize(BUFFER_SIZE)
|
||||
tx_data.fill(0)
|
||||
tick = 0.0
|
||||
|
||||
|
||||
func process(delta: float):
|
||||
tick += delta
|
||||
func process(tick: int):
|
||||
if online and ((tick - cmd_tick_rx) > ONLINE_TIMEOUT):
|
||||
online = false
|
||||
emit_signal('line_changed', self)
|
||||
@@ -75,6 +80,33 @@ class YaU07 extends unit.Unit:
|
||||
rc = Error.FAILED
|
||||
return rc
|
||||
|
||||
func send_flash(cmd_code: int, fl_data: Array, num_byte_rd: int) -> bool:
|
||||
if (cmd_state == CmdState.WAIT) \
|
||||
or (cmd_state == CmdState.SEND) \
|
||||
or (cmd_state == CmdState.UNCK):
|
||||
return false
|
||||
if not ((cmd_code == CmdCode.ERASE_FLASH) or (cmd_code == CmdCode.WRITE_FLASH) \
|
||||
or (cmd_code == CmdCode.READ_FLASH) or (cmd_code == CmdCode.LOAD_FLASH)):
|
||||
return false
|
||||
cmd_num_tx = (cmd_num_rx + 1) % 0xffff
|
||||
tx_data.encode_u16(0, cmd_retry)
|
||||
tx_data.encode_u16(2, cmd_num_tx)
|
||||
tx_data.encode_u8(6, cmd_code)
|
||||
if cmd_code == CmdCode.ERASE_FLASH:
|
||||
tx_len = 7
|
||||
elif cmd_code == CmdCode.WRITE_FLASH:
|
||||
tx_data.encode_u8(7, 1)
|
||||
tx_data.encode_u16(8, 0)
|
||||
tx_data.encode_u16(10, len(fl_data))
|
||||
tx_len = 11 + len(fl_data) * 2
|
||||
for i in range(len(fl_data)):
|
||||
tx_data.encode_u16(12 + i * 2, fl_data[i])
|
||||
elif cmd_code == CmdCode.READ_FLASH:
|
||||
tx_len = 11
|
||||
tx_data.encode_u16(7, 0)
|
||||
tx_data.encode_u16(9, num_byte_rd)
|
||||
cmd_state = CmdState.SEND
|
||||
return true
|
||||
|
||||
func send_isa(cmd_code: int, ports_data: Array) -> bool:
|
||||
if (cmd_state == CmdState.WAIT) \
|
||||
@@ -175,13 +207,18 @@ class YaU07 extends unit.Unit:
|
||||
isa_block[block_adr] = block_data
|
||||
return true
|
||||
|
||||
func parse_flash(rx_data: PackedByteArray, status_len, cmd_code) -> bool:
|
||||
if cmd_code == CmdCode.READ_FLASH:
|
||||
flash_len = rx_data.decode_u16(status_len + 12)
|
||||
flash_data = rx_data.slice(status_len + 14)
|
||||
return true
|
||||
|
||||
## Заполняет состояние прибора данными прочитанными из портов ЯУ-07.
|
||||
## для команд "читать порты" или "записать порты".[br]
|
||||
## [param rx_data] - Принятые данные.[br]
|
||||
## Возвращает [b]true[/b] - Данные обработаны успешно.[br]
|
||||
## Возвращает [b]false[/b] - Данные не обработаны из за ошибки.[br]
|
||||
func parse(rx_data: PackedByteArray) -> bool:
|
||||
func parse(rx_data: PackedByteArray, tick: int) -> bool:
|
||||
|
||||
cmd_tick_rx = tick
|
||||
|
||||
@@ -208,6 +245,7 @@ class YaU07 extends unit.Unit:
|
||||
if byte_i < len_rx_data:
|
||||
status[i] = rx_data[byte_i] # Массив байтовый "состояние прибора"
|
||||
i += 1
|
||||
emit_signal('data_received', self)
|
||||
|
||||
if rx_data_len == (status_len + 6):
|
||||
return true # Нет поля "ответ на команду", разбор пакета завершить
|
||||
@@ -231,9 +269,14 @@ class YaU07 extends unit.Unit:
|
||||
elif (cmd_code == CmdCode.READ_BLOCK) or (cmd_code == CmdCode.WRITE_BLOCK):
|
||||
rc = parse_block(rx_data, status_len)
|
||||
|
||||
elif (cmd_code == CmdCode.ERASE_FLASH) or (cmd_code == CmdCode.WRITE_FLASH) \
|
||||
or (cmd_code == CmdCode.READ_FLASH) or (cmd_code == CmdCode.LOAD_FLASH):
|
||||
rc = parse_flash(rx_data, status_len, cmd_code)
|
||||
|
||||
if rc:
|
||||
if (cmd_state == CmdState.WAIT) and (cmd_num_rx == cmd_num_tx):
|
||||
cmd_state = CmdState.DONE
|
||||
cmd_code_rx = cmd_code
|
||||
emit_signal('command_done', self)
|
||||
else:
|
||||
emit_signal('parse_failed', self)
|
||||
|
||||
@@ -1,15 +1,185 @@
|
||||
class_name yems_boards extends Node
|
||||
|
||||
class EmsBoard:
|
||||
enum {WAIT, WR_DEV_NUM_W, WRITE, WR_DEV_NUM_R, READ, READ_FLASH, WRITE_FLASH_BEGIN, \
|
||||
LOAD_KEMS, WRITE_FLASH_END}
|
||||
|
||||
var id_board: int ## id платы
|
||||
var in_devs: Dictionary ## Словарь с входными устройствами.
|
||||
var out_devs: Dictionary ## Словарь с выходными устройствами.
|
||||
var base_addr_isa: int ## Базовый адрес ячейки isa.
|
||||
var ports_to_wr: Array ## Порты для записи
|
||||
var in_tbl: Array
|
||||
var out_tbl: Array
|
||||
var online: bool ## статус платы
|
||||
var ems_load: bool ## флаг загрузки платы
|
||||
var state = WAIT ## текущее состояние платы ЭМС
|
||||
var state_read = WAIT ## текущее состояние платы ЭМС
|
||||
var cur_dev ## Текущее устройство
|
||||
var cur_dev_num: = 0 ## Номер текущего устройства
|
||||
var cur_dev_index: = 0 ## Индекс текущего устройства в списке
|
||||
var dev_num_list: = Array() ## Список всех устройств
|
||||
var need_next_dev: bool = false ## Нужно ли переходить к следующему устройству
|
||||
var unit_ems ## Юнит эмс
|
||||
var read_done: bool = false ## Флаг, что данные из ячейки прочитанны
|
||||
|
||||
func _init(id, base_addr, in_table, out_table):
|
||||
signal upd_delay_offset(board, cur_dev)
|
||||
signal upd_o_state(board, cur_dev)
|
||||
|
||||
func _init(id, base_addr, in_table, out_table, u):
|
||||
id_board = id
|
||||
in_tbl = in_table
|
||||
out_tbl = out_table
|
||||
base_addr_isa = base_addr
|
||||
unit_ems = u
|
||||
for i in range(4):
|
||||
ports_to_wr.append(base_addr_isa + 4 + i * 2) # Заполнение списка портами для записи
|
||||
dev_num_list = in_tbl + out_tbl
|
||||
|
||||
|
||||
func set_status(status):
|
||||
var offset = yemsconsts.STATUS_OFFSET[id_board]
|
||||
var bit_online = 0 + id_board
|
||||
var bit_load = 3 + id_board
|
||||
online = (status[0] >> bit_online) & 1
|
||||
ems_load = (status[0] >> bit_load) & 1
|
||||
var in_blank = int(status[1 + offset] | (status[2 + offset] << 8) | (status[3 + offset] << 16) | \
|
||||
(status[4 + offset] << 24) | (status[5 + offset] << 32))
|
||||
var in_imp = int(status[7 + offset] | (status[8 + offset] << 8) | (status[9 + offset] << 16) | \
|
||||
(status[10 + offset] << 24) | (status[11 + offset] << 32))
|
||||
var out_blank = int(status[13 + offset] | (status[14 + offset] << 8) | (status[15 + offset] << 16) | \
|
||||
(status[16 + offset] << 24) | (status[17 + offset] << 32))
|
||||
var out_imp = int(status[19 + offset] | (status[20 + offset] << 8) | (status[21 + offset] << 16)| \
|
||||
(status[22 + offset] << 24) | (status[23 + offset] << 32))
|
||||
var out_kz = int(status[25 + offset] | (status[26 + offset] << 8))
|
||||
if id_board > 0:
|
||||
out_kz = 0
|
||||
|
||||
for in_dev in in_devs.values():
|
||||
if (in_blank >> (in_dev.id - 1)) & 1:
|
||||
in_dev.state = 1
|
||||
elif (in_imp >> (in_dev.id - 1)) & 1:
|
||||
in_dev.state = 2
|
||||
else:
|
||||
in_dev.state = 0
|
||||
|
||||
for out_dev in out_devs.values():
|
||||
if (out_kz >> (out_dev.id - 1)) & 1:
|
||||
out_dev.state = 3
|
||||
elif (out_blank >> (out_dev.id - 1)) & 1:
|
||||
out_dev.state = 1
|
||||
elif (out_imp >> (out_dev.id - 1)) & 1:
|
||||
out_dev.state = 2
|
||||
else:
|
||||
out_dev.state = 0
|
||||
|
||||
# Отправка команды на запись или чтение порта
|
||||
func on_wr_device(dev_number):
|
||||
print_debug([id_board, dev_number])
|
||||
if (state == WR_DEV_NUM_W) or (state == WR_DEV_NUM_R):
|
||||
unit_ems.send_isa(unit_ems.CmdCode.WRITE_ISA, [base_addr_isa + 2, dev_number])
|
||||
elif state == WRITE:
|
||||
var ports: Array = []
|
||||
if not check_dev_number():
|
||||
return
|
||||
for port in cur_dev.ports_data:
|
||||
if port in ports_to_wr:
|
||||
var data = cur_dev.ports_data[port]
|
||||
ports.append(port)
|
||||
ports.append(data)
|
||||
unit_ems.send_isa(unit_ems.CmdCode.WRITE_ISA, ports)
|
||||
elif state == READ:
|
||||
var ports: Array = []
|
||||
for port in cur_dev.ports_data:
|
||||
if port in ports_to_wr:
|
||||
ports.append(port)
|
||||
unit_ems.send_isa(unit_ems.CmdCode.READ_ISA, ports)
|
||||
|
||||
# Обработчик сообщения, о том, что команда выполнена (машина состояний)
|
||||
func on_command_done(_yau_07):
|
||||
if not check_dev_number():
|
||||
return
|
||||
if (unit_ems.cmd_code_rx == 1) and state == WR_DEV_NUM_W:
|
||||
state = WRITE
|
||||
cur_dev_num = unit_ems.isa_ports[base_addr_isa + 2]
|
||||
if not check_dev_number():
|
||||
return
|
||||
on_wr_device(cur_dev_num)
|
||||
elif (unit_ems.cmd_code_rx == 1) and state == WR_DEV_NUM_R:
|
||||
state = READ
|
||||
cur_dev_num = unit_ems.isa_ports[base_addr_isa + 2]
|
||||
if not check_dev_number():
|
||||
return
|
||||
on_wr_device(cur_dev_num)
|
||||
elif (state == READ) or (state == WRITE) \
|
||||
and ((unit_ems.cmd_code_rx == 1) or (unit_ems.cmd_code_rx == 0)):
|
||||
for key in unit_ems.isa_ports.keys():
|
||||
if cur_dev.ports_data.has(key):
|
||||
cur_dev.ports_data[key] = unit_ems.isa_ports[key]
|
||||
cur_dev.set_delay_offset()
|
||||
emit_signal('upd_delay_offset', self, cur_dev)
|
||||
if cur_dev is yemsdevs.OutDev: # Если это выход, заполняем комбобоксы и чекбатоны
|
||||
cur_dev.set_mode()
|
||||
cur_dev.set_btns_state()
|
||||
emit_signal('upd_o_state', self, cur_dev)
|
||||
if need_next_dev: # Если нужно вычитать все устройства, выбираем следующее
|
||||
cur_dev_index += 1
|
||||
if cur_dev_index < len(dev_num_list):
|
||||
cur_dev_num = dev_num_list[cur_dev_index][0]
|
||||
if state == READ:
|
||||
state = WR_DEV_NUM_R
|
||||
on_wr_device(cur_dev_num)
|
||||
else:
|
||||
state = WR_DEV_NUM_W
|
||||
on_wr_device(cur_dev_num)
|
||||
else: # Пробег закончен, выбираем последнее устройство
|
||||
state = WAIT
|
||||
state_read = WAIT
|
||||
read_done = true
|
||||
cur_dev_index -= 1
|
||||
need_next_dev = false
|
||||
else:
|
||||
state = WAIT
|
||||
|
||||
elif (state == READ_FLASH) and (unit_ems.cmd_code_rx == 51):
|
||||
pass
|
||||
#read_flash()
|
||||
elif (state == WRITE_FLASH_BEGIN) and (unit_ems.cmd_code_rx == 49):
|
||||
pass
|
||||
#write_flash()
|
||||
#emit_signal('write_msg', 'Произведено чтение из ПЗУ ячейки ЯУ-07')
|
||||
elif (state == LOAD_KEMS) and (unit_ems.cmd_code_rx == 52):
|
||||
pass
|
||||
#start_rw_kems(true)
|
||||
elif (state == WRITE_FLASH_END) and (unit_ems.cmd_code_rx == 50):
|
||||
pass
|
||||
#load_flash()
|
||||
#emit_signal('write_msg', 'Произведена запись в ПЗУ ячейки ЯУ-07')
|
||||
|
||||
# Выбор текущего устройства и проверка правильности его номера
|
||||
func check_dev_number():
|
||||
cur_dev = get_dev()
|
||||
if not cur_dev:
|
||||
state = WAIT
|
||||
return false
|
||||
return true
|
||||
|
||||
# Возвращает устройство по текущему номеру, если он есть в словарях
|
||||
func get_dev():
|
||||
if in_devs.has(cur_dev_num):
|
||||
return in_devs[cur_dev_num]
|
||||
elif out_devs.has(cur_dev_num):
|
||||
return out_devs[cur_dev_num]
|
||||
else:
|
||||
return null
|
||||
|
||||
# Запуск чтения/записи данных из/в ячейки КЭМС
|
||||
func start_rw_kems(read: bool):
|
||||
cur_dev_index = 0
|
||||
cur_dev_num = dev_num_list[cur_dev_index][0]
|
||||
need_next_dev = true
|
||||
if read:
|
||||
state = WR_DEV_NUM_R
|
||||
else:
|
||||
state = WR_DEV_NUM_W
|
||||
on_wr_device(cur_dev_num)
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
class_name yerms_consts extends Node
|
||||
|
||||
const NUM_INPUT = 38
|
||||
const NUM_OUTPUT = 38
|
||||
const STATUS_OFFSET = { # Смещение статуса, ключ id платы
|
||||
0: 0,
|
||||
1: 26,
|
||||
2: 52 }
|
||||
|
||||
## Таблица с данными для входов, первое значение - индекс устройства в ячейке КЭМС.
|
||||
const INPUT_KEMS = [
|
||||
@@ -65,40 +71,40 @@ const INPUT_EMS1 = [
|
||||
|
||||
## Таблица с данными для выходов, первое значение - индекс устройства в ячейке КЭМС.
|
||||
const OUTPUT_EMS1 = [
|
||||
[1 ,['СЗИ1 Л1','X31 : 11', '0.00', '0.00']],
|
||||
[18,['СЗИ1 Л6','X31 : 14', '0.00', '0.00']],
|
||||
[2 ,['СЗИ1 Л7','X31 : 17', '0.00', '0.00']],
|
||||
[19,['СЗИ2 Л1','X32 : 11', '0.00', '0.00']],
|
||||
[3 ,['СЗИ2 Л6','X32 : 14', '0.00', '0.00']],
|
||||
[20,['СЗИ2 Л7','X32 : 17', '0.00', '0.00']],
|
||||
[4 ,['СЗИ3 Л1','X33 : 11', '0.00', '0.00']],
|
||||
[21,['СЗИ3 Л6','X33 : 14', '0.00', '0.00']],
|
||||
[5 ,['СЗИ3 Л7','X33 : 17', '0.00', '0.00']],
|
||||
[22,['СЗИ4 Л1','X34 : 11', '0.00', '0.00']],
|
||||
[6 ,['СЗИ4 Л6','X34 : 14', '0.00', '0.00']],
|
||||
[23,['СЗИ4 Л7','X34 : 17', '0.00', '0.00']],
|
||||
[7 ,['СЗИ1 Л2','X38 : 11', '0.00', '0.00']],
|
||||
[24,['СЗИ1 Л3','X38 : 14', '0.00', '0.00']],
|
||||
[8 ,['СЗИ2 Л2','X39 : 11', '0.00', '0.00']],
|
||||
[25,['СЗИ2 Л3','X39 : 14', '0.00', '0.00']],
|
||||
[9 ,['СЗИ3 Л2','X40 : 11', '0.00', '0.00']],
|
||||
[26,['СЗИ3 Л3','X40 : 14', '0.00', '0.00']],
|
||||
[10,['СЗИ4 Л2','X41 : 11', '0.00', '0.00']],
|
||||
[27,['СЗИ4 Л3','X41 : 14', '0.00', '0.00']],
|
||||
[11,['СЗИ1 Л4','X42 : 11', '0.00', '0.00']],
|
||||
[28,['СЗИ1 Л5','X42 : 14', '0.00', '0.00']],
|
||||
[12,['СЗИ2 Л4','X43 : 11', '0.00', '0.00']],
|
||||
[29,['СЗИ2 Л5','X43 : 14', '0.00', '0.00']],
|
||||
[13,['СЗИ3 Л4','X44 : 11', '0.00', '0.00']],
|
||||
[30,['СЗИ3 Л5','X44 : 14', '0.00', '0.00']],
|
||||
[14,['СЗИ4 Л4','X45 : 11', '0.00', '0.00']],
|
||||
[31,['СЗИ4 Л5','X45 : 14', '0.00', '0.00']],
|
||||
[33,['УИЗП_МП №1', 'X29 : 8', '0.00', '0.00']],
|
||||
[34,['УИЗП_МП №2', 'X29 : 9', '0.00', '0.00']],
|
||||
[35,['Выход 35', 'X29 : 10', '0.00', '0.00']],
|
||||
[36,['Выход 36', 'X29 : 11', '0.00', '0.00']],
|
||||
[37,['Выход 37', 'X29 : 12', '0.00', '0.00']],
|
||||
[38,['Выход 38', 'X29 : 13', '0.00', '0.00']],]
|
||||
[47 ,['СЗИ1 Л1','X31 : 11', '0.00', '0.00']],
|
||||
[64,['СЗИ1 Л6','X31 : 14', '0.00', '0.00']],
|
||||
[48 ,['СЗИ1 Л7','X31 : 17', '0.00', '0.00']],
|
||||
[65,['СЗИ2 Л1','X32 : 11', '0.00', '0.00']],
|
||||
[49 ,['СЗИ2 Л6','X32 : 14', '0.00', '0.00']],
|
||||
[66,['СЗИ2 Л7','X32 : 17', '0.00', '0.00']],
|
||||
[50 ,['СЗИ3 Л1','X33 : 11', '0.00', '0.00']],
|
||||
[67,['СЗИ3 Л6','X33 : 14', '0.00', '0.00']],
|
||||
[51 ,['СЗИ3 Л7','X33 : 17', '0.00', '0.00']],
|
||||
[68,['СЗИ4 Л1','X34 : 11', '0.00', '0.00']],
|
||||
[52 ,['СЗИ4 Л6','X34 : 14', '0.00', '0.00']],
|
||||
[69,['СЗИ4 Л7','X34 : 17', '0.00', '0.00']],
|
||||
[53 ,['СЗИ1 Л2','X38 : 11', '0.00', '0.00']],
|
||||
[70,['СЗИ1 Л3','X38 : 14', '0.00', '0.00']],
|
||||
[54 ,['СЗИ2 Л2','X39 : 11', '0.00', '0.00']],
|
||||
[71,['СЗИ2 Л3','X39 : 14', '0.00', '0.00']],
|
||||
[55 ,['СЗИ3 Л2','X40 : 11', '0.00', '0.00']],
|
||||
[72,['СЗИ3 Л3','X40 : 14', '0.00', '0.00']],
|
||||
[56,['СЗИ4 Л2','X41 : 11', '0.00', '0.00']],
|
||||
[73,['СЗИ4 Л3','X41 : 14', '0.00', '0.00']],
|
||||
[57,['СЗИ1 Л4','X42 : 11', '0.00', '0.00']],
|
||||
[74,['СЗИ1 Л5','X42 : 14', '0.00', '0.00']],
|
||||
[58,['СЗИ2 Л4','X43 : 11', '0.00', '0.00']],
|
||||
[76,['СЗИ2 Л5','X43 : 14', '0.00', '0.00']],
|
||||
[59,['СЗИ3 Л4','X44 : 11', '0.00', '0.00']],
|
||||
[76,['СЗИ3 Л5','X44 : 14', '0.00', '0.00']],
|
||||
[60,['СЗИ4 Л4','X45 : 11', '0.00', '0.00']],
|
||||
[77,['СЗИ4 Л5','X45 : 14', '0.00', '0.00']],
|
||||
[79,['УИЗП_МП №1', 'X29 : 8', '0.00', '0.00']],
|
||||
[80,['УИЗП_МП №2', 'X29 : 9', '0.00', '0.00']],
|
||||
[81,['Выход 35', 'X29 : 10', '0.00', '0.00']],
|
||||
[82,['Выход 36', 'X29 : 11', '0.00', '0.00']],
|
||||
[83,['Выход 37', 'X29 : 12', '0.00', '0.00']],
|
||||
[84,['Выход 38', 'X29 : 13', '0.00', '0.00']],]
|
||||
|
||||
|
||||
## Таблица с данными для входов, первое значение - индекс устройства в ячейке КЭМС.
|
||||
@@ -141,18 +147,18 @@ const INPUT_EMS2 = [
|
||||
|
||||
## Таблица с данными для выходов, первое значение - индекс устройства в ячейке КЭМС.
|
||||
const OUTPUT_EMS2 = [
|
||||
[1,['БИ РТР №1','X47 : 2', '0.00', '0.00']],
|
||||
[19,['БИ РТР №2','X47 : 5', '0.00', '0.00']],
|
||||
[2,['БИ РТР №3','X47 : 8', '0.00', '0.00']],
|
||||
[19,['БИ РТР №4','X47 : 11', '0.00', '0.00']],
|
||||
[3,['СИ В Лб', 'Х49 : 21', '0.00', '0.00']],
|
||||
[20,['СИ В ПрБ', 'Х49 : 19', '0.00', '0.00']],
|
||||
[4,['СИ Г Лб', 'Х49 : 28', '0.00', '0.00']],
|
||||
[21,['СИ Г ПрБ', 'Х49 : 30', '0.00', '0.00']],
|
||||
[5,['СИ Д Лб', 'Х49 : 13', '0.00', '0.00']],
|
||||
[22,['СИ Д ПрБ', 'Х49 : 11', '0.00', '0.00']],
|
||||
[6,['СИ Е Лб', 'Х49 : 26', '0.00', '0.00']],
|
||||
[23,['СИ Е ПрБ', 'Х49 : 35', '0.00', '0.00']],
|
||||
[33,['УИЗП_МП №3', 'X30 : 8', '0.00', '0.00']],
|
||||
[34,['УИЗП_МП №4', 'X30 : 9', '0.00', '0.00']],
|
||||
[35,['УИЗП_МП №5', 'X30 : 10', '0.00', '0.00']],]
|
||||
[47,['БИ РТР №1','X47 : 2', '0.00', '0.00']],
|
||||
[64,['БИ РТР №2','X47 : 5', '0.00', '0.00']],
|
||||
[48,['БИ РТР №3','X47 : 8', '0.00', '0.00']],
|
||||
[65,['БИ РТР №4','X47 : 11', '0.00', '0.00']],
|
||||
[49,['СИ В Лб', 'Х49 : 21', '0.00', '0.00']],
|
||||
[66,['СИ В ПрБ', 'Х49 : 19', '0.00', '0.00']],
|
||||
[50,['СИ Г Лб', 'Х49 : 28', '0.00', '0.00']],
|
||||
[67,['СИ Г ПрБ', 'Х49 : 30', '0.00', '0.00']],
|
||||
[51,['СИ Д Лб', 'Х49 : 13', '0.00', '0.00']],
|
||||
[68,['СИ Д ПрБ', 'Х49 : 11', '0.00', '0.00']],
|
||||
[52,['СИ Е Лб', 'Х49 : 26', '0.00', '0.00']],
|
||||
[69,['СИ Е ПрБ', 'Х49 : 35', '0.00', '0.00']],
|
||||
[79,['УИЗП_МП №3', 'X30 : 8', '0.00', '0.00']],
|
||||
[80,['УИЗП_МП №4', 'X30 : 9', '0.00', '0.00']],
|
||||
[81,['УИЗП_МП №5', 'X30 : 10', '0.00', '0.00']],]
|
||||
|
||||
@@ -16,23 +16,71 @@ class InDev:
|
||||
var board: String ## Плата в которой находится устройство.
|
||||
var isa_addr: int ## Адрес устройства на шине isa
|
||||
|
||||
func _init(dev_id : int, params : Array, row_id : int):
|
||||
func _init(dev_id : int, params : Array, row_id : int, base_addr: int):
|
||||
id = dev_id
|
||||
dev_name = String(params[0])
|
||||
connector = String(params[1])
|
||||
delay = float(params[2])
|
||||
offset = float(params[3])
|
||||
tbl_row_id = row_id
|
||||
isa_addr = base_addr
|
||||
ports_data[isa_addr + 4] = 0xFFFF
|
||||
ports_data[isa_addr + 6] = 0xFFFF
|
||||
ports_data[isa_addr + 8] = 0xFFFF
|
||||
ports_data[isa_addr + 10] = 0xFFFF
|
||||
|
||||
func set_delay_offset():
|
||||
delay = float(ports_data[isa_addr + 10] & 0x003F)/10
|
||||
offset = float((ports_data[isa_addr + 10] >> 6) & 0x01FF)/10
|
||||
|
||||
func set_delay(val):
|
||||
delay = val
|
||||
var bin_val = int(val * 10)
|
||||
ports_data[isa_addr + 10] = tools.set_bits(ports_data[isa_addr + 10], bin_val, 0x003F)
|
||||
|
||||
func set_offset(val):
|
||||
offset = val
|
||||
var bin_val = int(val * 10)
|
||||
ports_data[isa_addr + 10] = tools.set_bits(ports_data[isa_addr + 10], (bin_val << 6), 0x7FC0)
|
||||
|
||||
class OutDev extends InDev:
|
||||
var mode: String ## Режим работы выхода.
|
||||
var mode: int ## Режим работы выхода.
|
||||
var btns_state: = Dictionary()
|
||||
|
||||
func _init(dev_id : int, params : Array, row_id : int):
|
||||
id = dev_id
|
||||
dev_name = String(params[0])
|
||||
connector = String(params[1])
|
||||
delay = float(params[2])
|
||||
offset = float(params[3])
|
||||
tbl_row_id = row_id
|
||||
mode = 'Работа'
|
||||
func set_default_mode(): mode = 0
|
||||
|
||||
func set_mode():
|
||||
if (ports_data[isa_addr + 8] >> 13) & 1:
|
||||
mode = 1
|
||||
elif (ports_data[isa_addr + 8] >> 14) & 1:
|
||||
mode = 2
|
||||
elif (ports_data[isa_addr + 8] >> 15) & 1:
|
||||
mode = 3
|
||||
else:
|
||||
mode = 0
|
||||
|
||||
func set_btns_state():
|
||||
var data = ports_data[isa_addr + 4] | (ports_data[isa_addr + 6] << 16) | ((ports_data[isa_addr + 8] & 0x3f) << 32)
|
||||
for i in range(yemsconsts.NUM_INPUT):
|
||||
btns_state[i+1] = bool((data >> i) & 1)
|
||||
|
||||
func set_dot(i_dev):
|
||||
if btns_state.has(i_dev):
|
||||
btns_state[i_dev] = not btns_state[i_dev]
|
||||
var data = 0
|
||||
for i in range(yemsconsts.NUM_INPUT):
|
||||
data = data | (int(btns_state[i+1]) << i)
|
||||
ports_data[isa_addr + 4] = data & 0xffff
|
||||
ports_data[isa_addr + 6] = (data >> 16) & 0xffff
|
||||
ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], ((data >> 32) & 0x3f), 0x003F)
|
||||
|
||||
func set_sw_mode(o_state):
|
||||
mode = o_state
|
||||
if mode == 0:
|
||||
ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], 0x0000, 0xE000)
|
||||
elif mode == 1:
|
||||
ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], 0x2000, 0xE000)
|
||||
elif mode == 2:
|
||||
ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], 0x4000, 0xE000)
|
||||
elif mode == 3:
|
||||
ports_data[isa_addr + 8] = tools.set_bits(ports_data[isa_addr + 8], 0x8000, 0xE000)
|
||||
|
||||
@@ -3,7 +3,7 @@ shader_type canvas_item;
|
||||
uniform vec4 color: source_color = vec4(1, 1, 1, 1);
|
||||
uniform vec4 color_up: source_color = vec4(1, 1, 1, 1); /* Цвет вспышки при обновлении */
|
||||
const float ds = 0.01425; /* Относительное расстояние на котором выполняется сглаживание краёв */
|
||||
const float dsr = 12.125;
|
||||
const float dsr = 12.125;
|
||||
const vec2 center = vec2(0.5, 0.5); /* Центр должен быть в (0.5, 0.5), но это не так */
|
||||
const float radius = 0.075 - ds * 2.0; /* Радиус должен быть 0.5, но это не так */
|
||||
|
||||
@@ -60,7 +60,7 @@ vec2 rotateUVmatrinx(vec2 uv, vec2 pivot, float rotation)
|
||||
|
||||
|
||||
void vertex()
|
||||
{
|
||||
{
|
||||
float dir = 0.0;
|
||||
dir += speed * TIME;
|
||||
VERTEX = rotateUVmatrinx(VERTEX, center, radians(dir));
|
||||
@@ -70,7 +70,7 @@ void vertex()
|
||||
|
||||
void fragment()
|
||||
{
|
||||
|
||||
|
||||
ivec2 isz = textureSize(TEXTURE, 0);
|
||||
vec2 uv = UV * vec2(float(isz.x), float(isz.y)); // координаты текущей точки в пикселях
|
||||
COLOR = vec4(0, 0, 0, 0.0); //texture(TEXTURE, UV); // Цвет текущей точки
|
||||
|
||||
Reference in New Issue
Block a user