Add control panel

This commit is contained in:
2024-12-18 20:47:40 +03:00
parent 38e958adac
commit 3865ac1128
22 changed files with 1221 additions and 289 deletions

File diff suppressed because one or more lines are too long

View File

@@ -2,10 +2,11 @@ extends Panel
var node_select1: Node
var shift: int = 2
var button_link_meta: Dictionary = {}
var flag_sync_ems_g: bool = false
func _on_read_ems_g():
$load_boadr.visible = true
Constants.EMS_G_PORT_DATA_HOLDER.clear()
for i in 16:
Network.send_array.append(['wr', {Constants.EMS_G_BASE_ADDR+2: 1+i}])
Network.send_array.append(['rd', [Constants.EMS_G_BASE_ADDR+0xA]])
@@ -67,8 +68,7 @@ func _ready() -> void:
list.set_meta('device', Constants.OUT_EMS_G[i][0])
list.connect('item_selected', Callable(self, 'on_mode_link').bind(list))
for k in Constants.OUT_x128.size():
list.add_item(Constants.OUT_x128[k])
list.add_item(Constants.OUT_x128[k])
var columns_min_size: Array
for i in EMS_G_TABLE[0].size():
@@ -168,12 +168,9 @@ func on_btn_connect(toggled_on: bool, chk_node: Node, chk_btn: Node):
var ports_wr: Dictionary = {address_port_wr : meta[1]}
Network.send_array.append(['wr', ports_wr]) # Отправка команды
## Формирование команды для отправкы команды на устройство
var color_chk_btn = chk_node.get_child(0, false)
if toggled_on:
color_chk_btn.color = Color.WEB_GREEN
button_link_meta[meta[1]] += 1 << meta[0]-1
else:
color_chk_btn.color = Color.BLACK
button_link_meta[meta[1]] -= 1 << meta[0]-1
ports_wr = {}

82
kasseta-fs-kd.tscn Normal file
View File

@@ -0,0 +1,82 @@
[gd_scene load_steps=4 format=3 uid="uid://bdb0bhfu7366l"]
[ext_resource type="Texture2D" uid="uid://cgtg4gbqnuxrc" path="res://nine-patch-round.png" id="1_1jljp"]
[ext_resource type="Script" path="res://scripts/кассета.gd" id="2_20xal"]
[ext_resource type="PackedScene" uid="uid://p2suppildvq0" path="res://table/элемент-в.tscn" id="3_kqnvt"]
[node name="kasseta_fs_kd" type="NinePatchRect"]
offset_top = -32.0
offset_right = 310.0
offset_bottom = 190.0
texture = ExtResource("1_1jljp")
patch_margin_left = 16
patch_margin_top = 16
patch_margin_right = 16
patch_margin_bottom = 16
script = ExtResource("2_20xal")
metadata/Fname = ""
[node name="lbl_fname" type="Label" parent="."]
self_modulate = Color(1, 1, 1, 0.62)
layout_mode = 0
offset_left = 5.0
offset_top = 7.0
offset_right = 303.0
offset_bottom = 33.0
text = "Кассета"
horizontal_alignment = 1
vertical_alignment = 1
[node name="ref_A2" parent="." instance=ExtResource("3_kqnvt")]
offset_left = 5.0
offset_top = 39.0
offset_right = 55.0
offset_bottom = 215.0
self_size = Vector2i(50, 176)
fname = "Модуль ФС"
rname = "A1"
[node name="ref_A3" parent="." instance=ExtResource("3_kqnvt")]
offset_left = 55.0
offset_top = 39.0
offset_right = 105.0
offset_bottom = 215.0
self_size = Vector2i(50, 176)
fname = "Блок ФС-1"
rname = "A4"
[node name="ref_A4" parent="." instance=ExtResource("3_kqnvt")]
offset_left = 105.0
offset_top = 39.0
offset_right = 155.0
offset_bottom = 215.0
self_size = Vector2i(50, 176)
fname = "Модуль ФС"
rname = "A2"
[node name="ref_A6" parent="." instance=ExtResource("3_kqnvt")]
offset_left = 155.0
offset_top = 39.0
offset_right = 205.0
offset_bottom = 215.0
self_size = Vector2i(50, 176)
fname = "Блок ФС-6"
rname = "A5"
[node name="ref_A5" parent="." instance=ExtResource("3_kqnvt")]
offset_left = 205.0
offset_top = 39.0
offset_right = 255.0
offset_bottom = 215.0
self_size = Vector2i(50, 176)
fname = "Модуль ФС"
rname = "A3"
[node name="ref_A7" parent="." instance=ExtResource("3_kqnvt")]
offset_left = 255.0
offset_top = 39.0
offset_right = 305.0
offset_bottom = 215.0
self_size = Vector2i(50, 176)
fname = "Блок ФС-2"
rname = "A6"

69
light_ind.tscn Normal file
View File

@@ -0,0 +1,69 @@
[gd_scene load_steps=11 format=3 uid="uid://c7ft3pxeufffh"]
[ext_resource type="Shader" path="res://opt_btn.gdshader" id="1_sq6hl"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0dcn8"]
bg_color = Color(0, 0, 0, 1)
[sub_resource type="ShaderMaterial" id="ShaderMaterial_uw1r3"]
shader = ExtResource("1_sq6hl")
shader_parameter/range = 0.4
shader_parameter/color = Color(0.764706, 0.764706, 0.764706, 1)
[sub_resource type="ShaderMaterial" id="ShaderMaterial_s3tbi"]
shader = ExtResource("1_sq6hl")
shader_parameter/range = 0.4
shader_parameter/color = Color(0.764706, 0.764706, 0.764706, 1)
[sub_resource type="Gradient" id="Gradient_baoy0"]
colors = PackedColorArray(1, 1, 1, 1, 0.393086, 0.393086, 0.393085, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_hwb0g"]
gradient = SubResource("Gradient_baoy0")
width = 25
height = 25
fill = 1
fill_from = Vector2(0.5, 0.5)
fill_to = Vector2(1.125, 0)
[sub_resource type="Gradient" id="Gradient_f88ot"]
colors = PackedColorArray(0.1, 1, 0.1, 1, 0.124744, 0.328804, 0.202483, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_qe3hl"]
gradient = SubResource("Gradient_f88ot")
width = 25
height = 25
fill = 1
fill_from = Vector2(0.5, 0.5)
[sub_resource type="Gradient" id="Gradient_2hsy1"]
colors = PackedColorArray(1, 0.1, 0.1, 1, 0.329, 0.125, 0.202, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_cgmcr"]
gradient = SubResource("Gradient_2hsy1")
width = 25
height = 25
fill = 1
fill_from = Vector2(0.5, 0.5)
[node name="GrLight" type="PanelContainer"]
offset_right = 200.0
offset_bottom = 25.0
theme_override_styles/panel = SubResource("StyleBoxFlat_0dcn8")
[node name="basic_layer" type="GridContainer" parent="."]
material = SubResource("ShaderMaterial_uw1r3")
custom_minimum_size = Vector2(125, 0)
layout_mode = 2
size_flags_horizontal = 4
mouse_filter = 2
[node name="light_ind" type="TextureButton" parent="basic_layer"]
material = SubResource("ShaderMaterial_s3tbi")
layout_mode = 2
size_flags_vertical = 6
toggle_mode = true
button_mask = 0
texture_normal = SubResource("GradientTexture2D_hwb0g")
texture_pressed = SubResource("GradientTexture2D_qe3hl")
texture_disabled = SubResource("GradientTexture2D_cgmcr")

View File

@@ -1,25 +1,49 @@
shader_type canvas_item;
// Parameters for the sine wave
uniform float frequency = 1.5;
uniform float amplitude = 1000.0;
uniform float speed = 10.0;
uniform float direction: hint_range(-1.0, 1.0) = 1.0;
uniform float frequency = 5.0;
uniform float amplitude = 0.1; // Уменьшаем амплитуду для корректного отображения
uniform float speed = 5.0;
uniform float direction: hint_range(-1.0, 1.0) = -1.0;
// Uniforms for colors
uniform vec4 color1: source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform vec4 color2: source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform vec4 color3: source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform vec4 color4: source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform vec4 color1: source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform vec4 color2: source_color = vec4(0.235, 0.18, 0.235, 1.0);
uniform vec4 color3: source_color = vec4(0.235, 0.18, 0.235, 0.5);
uniform vec4 color4: source_color = vec4(0.0, 0.0, 0.0, 0.0);
uniform float opacity: hint_range(0.0, 1.0) = 0.5;
uniform float turn = 0.785; // 45 градусов в радианах (TAU / 8)
uniform float opacity: hint_range(0.0, 1.0) = 1.0;
vec2 rotate_uv(vec2 uv, vec2 pivot, float rotation) {
float cosa = cos(rotation);
float sina = sin(rotation);
uv -= pivot;
return vec2(
cosa * uv.x - sina * uv.y,
sina * uv.x + cosa * uv.y
) + pivot;
}
void fragment() {
vec2 uv = FRAGCOORD.xy;
float sine_wave = sin(UV.x * frequency + TIME * speed * direction) * amplitude;
// Нормализуем UV-координаты в диапазоне [0, 1]
uv = uv * 0.15 - 1.0; // Преобразуем в диапазон [-1, 1]
// Поворот UV-координат на 45 градусов
float angle = radians(-60.0); // Преобразуем градусы в радианы
vec2 origin = vec2(0.0, 0.0);
uv = rotate_uv(uv, origin, angle);
// Преобразуем обратно в диапазон [0, 1]
uv = uv * 0.05 + 0.05;
// Вычисляем синусоидальную волну
float sine_wave = sin(uv.x * frequency + TIME * speed * direction) * amplitude;
uv.y += sine_wave;
float t = sin(UV.x * frequency + TIME * speed * direction);
vec4 final_color;
float t = sin(uv.x * frequency + TIME * speed * direction);
vec4 final_color;
if (t < -0.5) {
final_color = color1;
} else if (t < 0.0) {

BIN
nine-patch-round.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cgtg4gbqnuxrc"
path="res://.godot/imported/nine-patch-round.png-61bc031153ce0d2485f8ba950a72df3f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://nine-patch-round.png"
dest_files=["res://.godot/imported/nine-patch-round.png-61bc031153ce0d2485f8ba950a72df3f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

24
opt_btn.gdshader Normal file
View File

@@ -0,0 +1,24 @@
shader_type canvas_item;
uniform float range: hint_range(0.0, 0.5);
uniform vec4 color: source_color;
const float ds = 0.01; /* Относительное расстояние на котором выполняется сглаживание краёв */
const vec2 center = vec2(0.125, 0.125); /* Центр должен быть в (0.5, 0.5), но это не так */
const float radius = 0.125 - ds * 2.0; /* Радиус должен быть 0.5, но это не так */
float smooth_px(float r, float R)
{
return 1.0 - smoothstep(R - ds, R + ds, r);
}
void fragment()
{
vec2 centere = vec2(0.5);
float df = distance(UV, centere);
float circlee = step(range, df);
COLOR *= color * smooth_px(circlee, radius);
}

View File

@@ -11,6 +11,7 @@ var flag_yau_control: bool
var CONTROL_TABLE: Array
var isa: Array = []
func _ready() -> void:
# Таблица УКП_1
node_select1 = $TabContainer/PRD/scroll1/table1
@@ -39,15 +40,6 @@ func _ready() -> void:
node_select_device.get_node2(0,0).text = 'ПРИБОР'
node_select_device.set_columns_min_size([100, 100])
# Контроль
var node_control_device = $TabContainer/ControlPanel/control_tbl
for i in Constants.CONTROL_DEVICE.size():
CONTROL_TABLE.append([Constants.TableNode])
draw_tabl(node_control_device, CONTROL_TABLE, CONTROL_TABLE.size())
for i in Constants.CONTROL_DEVICE.size():
node_control_device.get_node2(0, i).text = Constants.CONTROL_DEVICE[i]
node_control_device.set_columns_min_size([300])
$TabContainer/PRD/Zapret.connect('toggled', Callable(self, '_on_zapret').bind($TabContainer/PRD/Zapret))
$TabContainer/PRD/Zapret2.connect('toggled', Callable(self, '_on_zapret').bind($TabContainer/PRD/Zapret2))
Network.connect('yau_status_line', Callable(self, '_on_yau_status'))
@@ -58,12 +50,12 @@ func _ready() -> void:
## From Network status about yau-07
func _on_yau_status(yau_status):
if yau_status:
$TabContainer/ControlPanel/control_tbl.get_node2(0, 0).text = 'ЯУ-07Б НА СВЯЗИ'
$TabContainer/ControlPanel/control_tbl.get_node2(0, 0).modulate = Color.GREEN
$TabContainer/ControlPanel/sockets/ref_A26/light_ind.button_pressed = true
$TabContainer/ControlPanel/sockets/ref_A26/light_ind.disabled = false
flag_yau_control = true
else:
$TabContainer/ControlPanel/control_tbl.get_node2(0, 0).text = 'НЕТ СВЯЗИ С ЯУ-07Б'
$TabContainer/ControlPanel/control_tbl.get_node2(0, 0).modulate = Color.RED
$TabContainer/ControlPanel/sockets/ref_A26/light_ind.button_pressed = false
$TabContainer/ControlPanel/sockets/ref_A26/light_ind.disabled = true
for dev in (Constants.CONTROL_DEVICE.size() - 1):
var node_board = $TabContainer/ControlPanel/control_tbl.get_node2(0, dev+1)
node_board.modulate = Color.RED
@@ -105,95 +97,43 @@ func _process(_delta: float) -> void:
func _on_data_received(data_from_yau_07):
if flag_yau_control:
var status_board = data_from_yau_07.decode_u8(Constants.DataIndices.STATUS_BOARD)
var in_blank: int = data_from_yau_07.decode_u16(Constants.DataIndices.IN_BLANK_PRD)
var in_imp: int = data_from_yau_07.decode_u16(Constants.DataIndices.IN_IMPULS_PRD)
var out_blank: int = data_from_yau_07.decode_u16(Constants.DataIndices.OUT_BLANK_PRD)
var out_imp: int = data_from_yau_07.decode_u16(Constants.DataIndices.OUT_IMPULS_PRD)
var dry_contact: int = data_from_yau_07.decode_u16(Constants.DataIndices.DRY_CONTACT) # Контроль сухих контактов (УГ)
var _DKM: int = data_from_yau_07.decode_u16(Constants.DataIndices.DKM) # ДКМ от УГ
## УГ
#node_select1.set_node_text(2, 0, '%d' % dry_contact)
var node_control_device = $TabContainer/ControlPanel/control_tbl
## SOCKETS BOARDS
for i in 4:
var node_board = node_control_device.get_node2(0, i+2)
var sockets_ind = [$TabContainer/ControlPanel/sockets/ref_A23/light_ind,
$TabContainer/ControlPanel/sockets/ref_A24/light_ind,
$TabContainer/ControlPanel/sockets/ref_A25/light_ind,
$TabContainer/ControlPanel/sockets/ref_A27/light_ind]
var j = int(status_board & (1 << i) == 0 and flag_yau_control)
node_board.text = Constants.CONTROL_BOARD[i][j]
node_board.modulate = [Color.GREEN, Color.RED][j]
if j == 0:
sockets_ind[i].button_pressed = true
sockets_ind[i].disabled = false
else:
sockets_ind[i].button_pressed = false
sockets_ind[i].disabled = true
## Блок ИП
for i in 8:
var node_power_supply = node_control_device.get_node2(0, i+6)
var node_power_ind = [$TabContainer/ControlPanel/kasseta_p_1/ref_A23/light_ind,
$TabContainer/ControlPanel/kasseta_p_1/ref_A24/light_ind,
$TabContainer/ControlPanel/kasseta_p_1/ref_A25/light_ind,
$TabContainer/ControlPanel/kasseta_p_1/ref_A26/light_ind,
$TabContainer/ControlPanel/kasseta_p_1/ref_A27/light_ind,
$TabContainer/ControlPanel/kasseta_p_1/ref_A28/light_ind,
$TabContainer/ControlPanel/kasseta_p_1/ref_A29/light_ind,
$TabContainer/ControlPanel/kasseta_p_1/ref_A30/light_ind]
var j = int(not(dry_contact & (1 << i) == 0 and flag_yau_control))
node_power_supply.text = Constants.CONTROL_POWER_SUPPLY[i][j]
node_power_supply.modulate = [Color.GREEN, Color.RED][j]
## EMS G
var CONTROL_FRAME = [$TabContainer/ControlPanel/SZI_x, $TabContainer/ControlPanel/SZI_x2, $TabContainer/ControlPanel/SZI_x3, $TabContainer/ControlPanel/SZI_x4, $TabContainer/ControlPanel/SZI_x5]
for i in 5:
var node_ems_g = node_control_device.get_node2(0, i + 14)
var j: int = 0
var frame = Constants.Frame.WORK
var in_bit_blank_UF = 1 if Constants.MODE.PRD_H == flag_mode else 3 if Constants.MODE.PRD_K == flag_mode else 6
var in_bit_blank_FS = 9 if Constants.MODE.PRD_H == flag_mode else 11 if Constants.MODE.PRD_K == flag_mode else 13
var in_bit_impuls_UF = 1 if Constants.MODE.PRD_H == flag_mode else 3 if Constants.MODE.PRD_K == flag_mode else 6
var in_bit_impuls_FS = 9 if Constants.MODE.PRD_H == flag_mode else 11 if Constants.MODE.PRD_K == flag_mode else 13
###
var out_bit_blank_UF = 1 if Constants.MODE.PRD_H == flag_mode else 1 if Constants.MODE.PRD_K == flag_mode else 0
var out_bit_blank_MODUL = 4 if Constants.MODE.PRD_H == flag_mode else 4 if Constants.MODE.PRD_K == flag_mode else 4
var out_bit_blank_FGOZ = 9 if Constants.MODE.PRD_H == flag_mode else 8 if Constants.MODE.PRD_K == flag_mode else 8
var out_bit_impuls_UF = 1 if Constants.MODE.PRD_H == flag_mode else 1 if Constants.MODE.PRD_K == flag_mode else 0
var out_bit_impuls_MODUL = 4 if Constants.MODE.PRD_H == flag_mode else 4 if Constants.MODE.PRD_K == flag_mode else 4
var out_bit_impuls_FGOZ = 9 if Constants.MODE.PRD_H == flag_mode else 8 if Constants.MODE.PRD_K == flag_mode else 8
if (in_blank & (1 << in_bit_blank_UF) != 0) and flag_yau_control:
j = 1 if i == 0 else 0
frame = Constants.Frame.CONSTANT if i == 0 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
elif (in_imp & (1 << in_bit_impuls_UF) != 0) and flag_yau_control:
j = 1 if i == 0 else 0
frame = Constants.Frame.VARIABLE if i == 0 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
elif (in_blank & (1 << in_bit_blank_FS) != 0) and flag_yau_control:
j = 1 if i == 1 else 0
frame = Constants.Frame.CONSTANT if i == 1 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
elif (in_imp & (1 << in_bit_impuls_FS) != 0) and flag_yau_control:
j = 1 if i == 1 else 0
frame = Constants.Frame.VARIABLE if i == 1 else Constants.Frame.WORK
elif (out_blank & (1 << out_bit_blank_UF) != 0) and flag_yau_control:
j = 1 if i == 2 else 0
frame = Constants.Frame.CONSTANT if i == 2 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
elif (out_imp & (1 << out_bit_impuls_UF) != 0) and flag_yau_control:
j = 1 if i == 2 else 0
frame = Constants.Frame.VARIABLE if i == 2 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
elif (out_blank & (1 << out_bit_blank_MODUL) != 0) and flag_yau_control:
j = 1 if i == 3 else 0
frame = Constants.Frame.CONSTANT if i == 3 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
elif (out_imp & (1 << out_bit_impuls_MODUL) != 0) and flag_yau_control:
j = 1 if i == 3 else 0
frame = Constants.Frame.VARIABLE if i == 3 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
elif (out_blank & (1 << out_bit_blank_FGOZ) != 0) and flag_yau_control:
j = 1 if i == 4 else 0
frame = Constants.Frame.CONSTANT if i == 4 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
elif (out_imp & (1 << out_bit_impuls_FGOZ) != 0) and flag_yau_control:
j = 1 if i == 4 else 0
frame = Constants.Frame.VARIABLE if i == 4 else Constants.Frame.WORK
set_frame(CONTROL_FRAME[i], frame)
node_ems_g.text = Constants.EMS_G_CONTROL_PANEL[i][j]
node_ems_g.modulate = [Color.RED, Color.GREEN][j]
#set_frame(CONTROL_FRAME[i], frame)
if j == 0:
node_power_ind[i].button_pressed = true
else:
node_power_ind[i].button_pressed = false
#node_select1.set_node_text(3, 0, '%d' % DKM)
## УКП

View File

@@ -48,20 +48,6 @@ const ADDRESSES: Array = [
['ПРД-К2', '10.1.1.23', 50023, MODE.PRD_K],
['ПРД-К3', '10.1.1.33', 50033, MODE.PRD_K],
['ПРД-К4', '10.1.1.43', 50043, MODE.PRD_K]]
var CONTROL_BOARD: Array = [
['ЯЧЕЙКА ЭМС-Г НА СВЯЗИ', 'ЯЧЕЙКИ ЭМС-Г НЕТ НА СВЯЗИ'],
['ЯЧЕЙКА УГ НА СВЯЗИ','ЯЧЕЙКИ УГ НЕТ НА СВЯЗИ'],
['ЯЧЕЙКА УКП №1 НА СВЯЗИ', 'ЯЧЕЙКИ УКП №1 НЕТ НА СВЯЗИ'],
['ЯЧЕЙКА УКП №2 НА СВЯЗИ', 'ЯЧЕЙКИ УКП №2 НЕТ НА СВЯЗИ']]
var CONTROL_POWER_SUPPLY: Array = [
['ИП МАА №1', 'ОШИБКА. КОНТРОЛЬ ИП МАА №1'],
['ИП МАА №2', 'ОШИБКА. КОНТРОЛЬ ИП МАА №2'],
['ИП9-50 №1', 'ОШИБКА. КОНТРОЛЬ ИП9-50 №1'],
['ИП9-50 №2', 'ОШИБКА. КОНТРОЛЬ ИП9-50 №2'],
['ИП12-50 №1', 'ОШИБКА. КОНТРОЛЬ ИП12-50 №1'],
['ИП9-50 №3', 'ОШИБКА. КОНТРОЛЬ ИП9-50 №3'],
['ИП12-50 №2', 'ОШИБКА. КОНТРОЛЬ ИП12-50 №2'],
['ИП5-25', 'ОШИБКА. КОНТРОЛЬ ИП5-25']]
const EMS_G_CONTROL_PANEL: Array = [
['Нет Х3:2(СЗИ2 от УФ)', 'Есть Х3:2(СЗИ2 от УФ)'],
['Нет Х3:19(СИ2 от ФС)', 'Есть Х3:19(СИ2 от ФС)'],

View File

@@ -39,7 +39,8 @@ func poll_receive(sock: Socket) -> bool: ## Приёмник
if sock.get_available_packet_count():
last_update_time = 0.0
return false
func _ready() -> void:
# Привязка для принятия широковещательного канала

18
scripts/кассета.gd Normal file
View File

@@ -0,0 +1,18 @@
@tool
extends NinePatchRect
"""
Для кассет
"""
@export var fname: String:
set(v):
fname = v
if is_inside_tree():
$lbl_fname.text = v
@export var rname: String:
set(v):
rname = v

20
scripts/прибор.gd Normal file
View File

@@ -0,0 +1,20 @@
@tool
extends Control
"""
Для приборов
"""
@export var fname: String:
set(v):
fname = v
@export var rname: String:
set(v):
rname = v
func set_header_text(header_text: String):
$lbl_header.text = header_text

BIN
table/off.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

34
table/off.png.import Normal file
View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cfktmk2rowmul"
path="res://.godot/imported/off.png-1e39e374275baa601325fa6406753589.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://table/off.png"
dest_files=["res://.godot/imported/off.png-1e39e374275baa601325fa6406753589.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
table/on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

34
table/on.png.import Normal file
View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cdxdluvyb5uei"
path="res://.godot/imported/on.png-206ee6e6bfd662244aa1e9ef9d746f4b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://table/on.png"
dest_files=["res://.godot/imported/on.png-206ee6e6bfd662244aa1e9ef9d746f4b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -20,7 +20,7 @@ script = ExtResource("1_h0k6p")
[node name="ColorRect" type="ColorRect" parent="."]
layout_mode = 2
color = Color(0, 0, 0, 0.490196)
color = Color(0, 0, 0, 0.011)
[node name="CheckButton" type="CheckButton" parent="."]
layout_mode = 2
@@ -30,3 +30,4 @@ theme_override_styles/focus = SubResource("StyleBoxTexture_b6sp7")
theme_override_styles/hover = SubResource("StyleBoxTexture_bc33d")
theme_override_styles/pressed = SubResource("StyleBoxTexture_46fou")
theme_override_styles/normal = SubResource("StyleBoxTexture_o64tc")
metadata/_edit_lock_ = true

View File

@@ -0,0 +1,195 @@
[gd_scene load_steps=15 format=3 uid="uid://p2suppildvq0"]
[ext_resource type="Texture2D" uid="uid://cgtg4gbqnuxrc" path="res://nine-patch-round.png" id="2_4b43i"]
[ext_resource type="Shader" path="res://opt_btn.gdshader" id="2_ecsml"]
[ext_resource type="Texture2D" uid="uid://dkef6xwxwdxi8" path="res://эмс-бланк.png" id="3_4kmgr"]
[ext_resource type="Texture2D" uid="uid://b15flrfytxkop" path="res://эмс-бланк-пост.png" id="4_omove"]
[ext_resource type="Texture2D" uid="uid://ijdfo2mml54" path="res://эмс-бланк-перем.png" id="5_jia67"]
[sub_resource type="GDScript" id="GDScript_fbktk"]
script/source = "@tool
extends Control
@export var margins: Array[int] = [8, 8, 8, 8] # top, left, bottom, right
@export var textures: Array[Texture]
@export var self_size: Vector2i = Vector2i(50, 150):
set(v):
self_size = v
size = v
$np_rect.size = v
_resize_children()
get: return size
@export var fname: String:
set(v):
fname = v
$lbl_fname.text = v
@export var rname: String:
set(v):
rname = v
$lbl_rname.text = v
func _resize_children() -> void:
$lbl_rname.size.x = size.x
$lbl_rname.position.y = margins[0]
$lbl_fname.size.y = size.x
$lbl_fname.position.y = size.y / 2 + $lbl_fname.size.x / 2
$light_ind.position.x = size.x / 2 - ($light_ind.size.x * $light_ind.scale.x) / 2
$light_ind.position.y = size.y - $light_ind.size.y * $light_ind.scale.x - margins[2]
func _on_nine_patch_rect_resized() -> void:
size = $np_rect.size
self_size = $np_rect.size
_resize_children()
func _on_resized() -> void:
$np_rect.size = size
self_size = size
_resize_children()
@export var state: int:
set(v):
v = 0 if v < 0 else v
v %= textures.size()
state = v
$txr_state.texture = textures[v]
get:
return state
"
[sub_resource type="ShaderMaterial" id="ShaderMaterial_45ast"]
shader = ExtResource("2_ecsml")
shader_parameter/range = 0.4
shader_parameter/color = Color(0.764706, 0.764706, 0.764706, 1)
[sub_resource type="Gradient" id="Gradient_x8k3w"]
colors = PackedColorArray(1, 1, 1, 1, 0.393086, 0.393086, 0.393085, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_cgu2r"]
gradient = SubResource("Gradient_x8k3w")
width = 25
height = 25
fill = 1
fill_from = Vector2(0.5, 0.5)
fill_to = Vector2(1.125, 0)
[sub_resource type="Gradient" id="Gradient_1tk1g"]
colors = PackedColorArray(0.1, 1, 0.1, 1, 0.124744, 0.328804, 0.202483, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_d3qtt"]
gradient = SubResource("Gradient_1tk1g")
width = 25
height = 25
fill = 1
fill_from = Vector2(0.5, 0.5)
[sub_resource type="Gradient" id="Gradient_6e32x"]
colors = PackedColorArray(1, 0.1, 0.1, 1, 0.329, 0.125, 0.202, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_k8o6s"]
gradient = SubResource("Gradient_6e32x")
width = 25
height = 25
fill = 1
fill_from = Vector2(0.5, 0.5)
[sub_resource type="SpriteFrames" id="SpriteFrames_nofpw"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("3_4kmgr")
}, {
"duration": 1.0,
"texture": ExtResource("4_omove")
}, {
"duration": 1.0,
"texture": ExtResource("5_jia67")
}, {
"duration": 1.0,
"texture": null
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[node name="yelement_v" type="Control"]
editor_description = "Элемент замены из ЗИП"
layout_mode = 3
anchors_preset = 0
offset_right = 50.0
offset_bottom = 150.0
script = SubResource("GDScript_fbktk")
textures = Array[Texture]([ExtResource("2_4b43i"), ExtResource("2_4b43i"), ExtResource("2_4b43i")])
metadata/ref_des = ""
metadata/dec_num = ""
[node name="lbl_rname" type="Label" parent="."]
layout_mode = 0
offset_top = 8.0
offset_right = 50.0
offset_bottom = 34.0
theme_override_colors/font_color = Color(0.991, 0.991, 0.991, 0.675)
theme_override_font_sizes/font_size = 17
text = "A1"
horizontal_alignment = 1
vertical_alignment = 1
[node name="lbl_fname" type="Label" parent="."]
self_modulate = Color(1, 1, 1, 0.627451)
layout_mode = 0
offset_top = 123.0
offset_right = 94.0
offset_bottom = 173.0
rotation = -1.5708
theme_override_font_sizes/font_size = 17
text = "Ячейка"
horizontal_alignment = 1
vertical_alignment = 1
[node name="light_ind" type="TextureButton" parent="."]
material = SubResource("ShaderMaterial_45ast")
layout_mode = 0
offset_left = 13.0
offset_top = 114.0
offset_right = 38.0
offset_bottom = 139.0
size_flags_vertical = 6
toggle_mode = true
button_mask = 0
texture_normal = SubResource("GradientTexture2D_cgu2r")
texture_pressed = SubResource("GradientTexture2D_d3qtt")
texture_disabled = SubResource("GradientTexture2D_k8o6s")
[node name="np_rect" type="NinePatchRect" parent="."]
layout_mode = 0
offset_right = 50.0
offset_bottom = 150.0
texture = ExtResource("2_4b43i")
region_rect = Rect2(0, 0, 63, 63)
patch_margin_left = 16
patch_margin_top = 16
patch_margin_right = 16
patch_margin_bottom = 16
[node name="SZI_x" type="AnimatedSprite2D" parent="."]
visible = false
position = Vector2(524, 454)
sprite_frames = SubResource("SpriteFrames_nofpw")
metadata/_edit_lock_ = true
[connection signal="resized" from="." to="." method="_on_resized"]
[connection signal="resized" from="np_rect" to="." method="_on_nine_patch_rect_resized"]

View File

@@ -0,0 +1,140 @@
[gd_scene load_steps=7 format=3 uid="uid://bnlkbbn7b4a3k"]
[ext_resource type="Texture2D" uid="uid://cgtg4gbqnuxrc" path="res://nine-patch-round.png" id="1_lmmwb"]
[ext_resource type="Texture2D" uid="uid://dkef6xwxwdxi8" path="res://эмс-бланк.png" id="3_2trq1"]
[ext_resource type="Texture2D" uid="uid://b15flrfytxkop" path="res://эмс-бланк-пост.png" id="4_vgjvf"]
[ext_resource type="Texture2D" uid="uid://ijdfo2mml54" path="res://эмс-бланк-перем.png" id="5_1heoc"]
[sub_resource type="GDScript" id="GDScript_fbktk"]
script/source = "@tool
extends Control
@export var margins: Array[int] = [8, 8, 8, 8] # top, left, bottom, right
@export var textures: Array[Texture]
@export var self_size: Vector2i = Vector2i(50, 150):
set(v):
self_size = v
size = v
$np_rect.size = v
_resize_children()
get: return size
@export var fname: String:
set(v):
fname = v
$lbl_fname.text = v
@export var rname: String:
set(v):
rname = v
$lbl_rname.text = v
func _resize_children() -> void:
$lbl_rname.size.x = size.x
$lbl_rname.position.y = margins[0]
$lbl_fname.size.y = size.x
$lbl_fname.position.y = size.y / 2 + $lbl_fname.size.x / 2
func _on_nine_patch_rect_resized() -> void:
size = $np_rect.size
self_size = $np_rect.size
_resize_children()
func _on_resized() -> void:
$np_rect.size = size
self_size = size
_resize_children()
@export var state: int:
set(v):
v = 0 if v < 0 else v
v %= textures.size()
state = v
$txr_state.texture = textures[v]
get:
return state
"
[sub_resource type="SpriteFrames" id="SpriteFrames_nofpw"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("3_2trq1")
}, {
"duration": 1.0,
"texture": ExtResource("4_vgjvf")
}, {
"duration": 1.0,
"texture": ExtResource("5_1heoc")
}, {
"duration": 1.0,
"texture": null
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[node name="yelement_ems" type="Control"]
editor_description = "Элемент замены из ЗИП"
layout_mode = 3
anchors_preset = 0
offset_right = 50.0
offset_bottom = 150.0
script = SubResource("GDScript_fbktk")
textures = Array[Texture]([ExtResource("1_lmmwb"), ExtResource("1_lmmwb"), ExtResource("1_lmmwb")])
metadata/ref_des = ""
metadata/dec_num = ""
[node name="lbl_rname" type="Label" parent="."]
layout_mode = 0
offset_top = 8.0
offset_right = 50.0
offset_bottom = 34.0
theme_override_colors/font_color = Color(0.991, 0.991, 0.991, 0.675)
theme_override_font_sizes/font_size = 17
text = "A1"
horizontal_alignment = 1
vertical_alignment = 1
[node name="lbl_fname" type="Label" parent="."]
self_modulate = Color(1, 1, 1, 0.627451)
layout_mode = 0
offset_top = 123.0
offset_right = 94.0
offset_bottom = 173.0
rotation = -1.5708
theme_override_font_sizes/font_size = 17
text = "Ячейка"
horizontal_alignment = 1
vertical_alignment = 1
[node name="np_rect" type="NinePatchRect" parent="."]
layout_mode = 0
offset_right = 50.0
offset_bottom = 150.0
texture = ExtResource("1_lmmwb")
region_rect = Rect2(0, 0, 63, 63)
patch_margin_left = 16
patch_margin_top = 16
patch_margin_right = 16
patch_margin_bottom = 16
[node name="SZI_x" type="AnimatedSprite2D" parent="."]
position = Vector2(25, 155)
sprite_frames = SubResource("SpriteFrames_nofpw")
[connection signal="resized" from="." to="." method="_on_resized"]
[connection signal="resized" from="np_rect" to="." method="_on_nine_patch_rect_resized"]

193
threads.txt Normal file
View File

@@ -0,0 +1,193 @@
'BackgroundThread.gd'
extends Node
var semaphore: Semaphore
var mutex: Mutex
var thread: Thread
var exit_thread: bool = false
var nodeWhoRequestedJob: Node
var delta: float = 0.0
var address: String = ""
var port: int = 0
var soc_brodcast: PacketPeerUDP
var soc_unicast: PacketPeerUDP
var unit: Object
func _enter_tree():
semaphore = Semaphore.new()
mutex = Mutex.new()
exit_thread = false
thread = Thread.new()
thread.start(_thread_function)
func _thread_function():
while true:
semaphore.wait() # Wait until posted.
mutex.lock()
var should_exit = exit_thread # Protect with Mutex.
mutex.unlock()
if should_exit:
break
mutex.lock()
var local_delta = delta
var local_address = address
var local_port = port
var local_soc_brodcast = soc_brodcast
var local_soc_unicast = soc_unicast
var local_unit = unit
mutex.unlock()
# Выполнение задач
local_unit.poll_receive(local_soc_brodcast)
local_unit.poll_receive(local_soc_unicast)
local_unit.state_machine()
match local_unit.process(local_delta):
Error.OK:
nodeWhoRequestedJob.call_deferred('data_sent', local_address, local_port, local_unit.tx_data.slice(0, local_unit.tx_len))
Error.FAILED:
nodeWhoRequestedJob.call_deferred('data_send_failed')
func tellTheThreadToDoSomething(requester, delta, address, port, soc_brodcast, soc_unicast, unit):
mutex.lock()
nodeWhoRequestedJob = requester
self.delta = delta
self.address = address
self.port = port
self.soc_brodcast = soc_brodcast
self.soc_unicast = soc_unicast
self.unit = unit
mutex.unlock()
semaphore.post()
func _exit_tree():
# Set exit condition to true.
mutex.lock()
exit_thread = true # Protect with Mutex.
mutex.unlock()
# Post to semaphore to wake up the thread.
semaphore.post()
# Wait until it exits.
thread.wait_to_finish()
'Network.gd'
extends Node
var unit = Yau07.YaU07.new('ЯУ07')
var soc_unicast: PacketPeerUDP
var soc_brodcast: PacketPeerUDP
var address: String = Constants.ADDRESSES[0][1]
var port: int = Constants.ADDRESSES[0][2]
var timeout: float = Yau07.ONLINE_TIMEOUT
var last_update_time: float = 0.0
var broadcast_packet: PackedByteArray
var state = Constants.STATE.WAIT
var send_array: Array = []
signal yau_status_line(_status) ## Вызывается когда меняется состояние связи с ячейкой
signal yau_receive(_data_from_yau) ##
signal yau_read_isa(_unit_isa_ports)
## Класс для отправки данных в сокет
class Socket extends PacketPeerUDP:
func send_to(addr: String, port: int, data: PackedByteArray):
self.set_dest_address(addr, port)
self.put_packet(data)
func poll_receive(sock: PacketPeerUDP) -> bool: ## Приёмник
if timeout - last_update_time > 0:
while sock.get_available_packet_count() > 0:
broadcast_packet = sock.get_packet()
var addr_receive = sock.get_packet_ip()
var port_receive = sock.get_packet_port()
if (address == addr_receive) and (port == port_receive):
last_update_time = 0.0
unit.parse(broadcast_packet)
var data_from_yau_07 = unit.status
emit_signal('yau_receive', data_from_yau_07)
else:
if sock.get_available_packet_count():
last_update_time = 0.0
return false
func _ready() -> void:
# Привязка для принятия широковещательного канала
soc_brodcast = Socket.new()
var rc = soc_brodcast.bind(Constants.BROADCAST_PORT, '*')
if rc != OK:
print('Ошибка: Неудачная привязка широковещательного адреса')
soc_unicast = Socket.new()
rc = soc_unicast.bind(Constants.UNICAST_PORT, Constants.UNICAST_ADDRESS)
if rc != OK:
print('Ошибка: неудачная привязка адреса: ', address)
unit.connect('line_changed', Callable(self, 'on_line_changed'))
unit.connect('command_fail', Callable(self, 'on_command_fail'))
# Создание и запуск фонового потока
var background_thread_node = BackgroundThread.new()
add_child(background_thread_node)
background_thread_node.name = "BackgroundThreadNode"
func _process(delta: float) -> void:
last_update_time += delta
background_thread_node.tellTheThreadToDoSomething(self, delta, address, port, soc_brodcast, soc_unicast, unit)
func state_machine():
var fl_done = (unit.cmd_state == unit.CmdState.DONE)
## Режим ожидания
if state == Constants.STATE.WAIT and fl_done:
if send_array.size():
state = Constants.STATE.READ_ISA if send_array[0][0] == 'rd' else Constants.STATE.WRITE_ISA
## Режим чтения из ИСА
elif state == Constants.STATE.READ_ISA and fl_done:
var ports_read = send_array.pop_front()
unit.send_isa(unit.CmdCode.READ_ISA, ports_read[1])
state = Constants.STATE.DONE
## Режим записи в ИСА
elif state == Constants.STATE.WRITE_ISA and fl_done:
var ports_write = send_array.pop_front()
var key = ports_write[1].keys()
unit.send_isa(unit.CmdCode.WRITE_ISA, [key[0], ports_write[1][key[0]]])
state = Constants.STATE.WAIT
elif state == Constants.STATE.DONE and fl_done:
emit_signal('yau_read_isa', unit.isa_ports)
state = Constants.STATE.WAIT
func on_line_changed(_unit) -> void:
emit_signal('yau_status_line', unit.online)
## Если отсутствует подключение к ячейке ЯУ-07
func on_command_fail(_unit) -> void:
print_debug('Command send fail')
func data_sent(address, port, data):
soc_unicast.send_to(address, port, data)
func data_send_failed():
print('Ошибка отправки данных')

View File

@@ -1,51 +0,0 @@
[gd_scene load_steps=6 format=3 uid="uid://cf500m6u46dqe"]
[ext_resource type="Texture2D" uid="uid://dkef6xwxwdxi8" path="res://эмс-бланк.png" id="2_don4l"]
[ext_resource type="Texture2D" uid="uid://b15flrfytxkop" path="res://эмс-бланк-пост.png" id="3_lu634"]
[ext_resource type="Texture2D" uid="uid://ijdfo2mml54" path="res://эмс-бланк-перем.png" id="4_b33qw"]
[sub_resource type="GDScript" id="GDScript_q347l"]
script/source = "extends Control
var align : get = get_align, set = set_align
var _align: int = 0
func set_align(val: int): _align = val
func get_align(): return _align
func set_frame(val: int): $sprite.set_frame(val)
func get_frame(): return $sprite.get_frame()
"
[sub_resource type="SpriteFrames" id="SpriteFrames_ow7xh"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("2_don4l")
}, {
"duration": 1.0,
"texture": ExtResource("3_lu634")
}, {
"duration": 1.0,
"texture": ExtResource("4_b33qw")
}, {
"duration": 1.0,
"texture": null
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[node name="Control" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_right = -1540.0
offset_bottom = -1182.0
grow_horizontal = 2
grow_vertical = 2
script = SubResource("GDScript_q347l")
[node name="sprite" type="AnimatedSprite2D" parent="."]
position = Vector2(32, 226)
sprite_frames = SubResource("SpriteFrames_ow7xh")
frame = 2