diff --git a/BITKit/Scripts/UX/UXAnimateButton.cs b/BITKit/Scripts/UX/UXAnimateButton.cs new file mode 100644 index 0000000..72a0b07 --- /dev/null +++ b/BITKit/Scripts/UX/UXAnimateButton.cs @@ -0,0 +1,18 @@ +using Godot; +using System; + +namespace BITKit; +public partial class UXAnimateButton : Button +{ + [ExportCategory(nameof(ProgressBar))] + [Export] private ProgressBar progressBar; + [Export] private float progressDuration = 1f; + public override void _Ready() + { + } + + private void OnPressed() + { + + } +} diff --git a/Mods/工业数据采集与分析应用分享/Scripts/IDIS_Service.cs b/Mods/工业数据采集与分析应用分享/Scripts/IDIS_Service.cs index c5620eb..733bc5a 100644 --- a/Mods/工业数据采集与分析应用分享/Scripts/IDIS_Service.cs +++ b/Mods/工业数据采集与分析应用分享/Scripts/IDIS_Service.cs @@ -210,25 +210,16 @@ public class IDIS_DBContext:DbContext SaveChanges(); } - public void Update(string handle, string format, string value) + public bool Update(string handle, string format, string value) { - // var datas =Datas.ToList(); - // var result = datas.Where(x => x.Handle == handle && x.Format == format).ToArray(); - // foreach (var x in result) - // { - // Datas.Remove(x); - // } - // foreach (var element in result) - // { - // element.Value = value; - // element.UpdateTime=DateTime.Now; - // Datas.Add(element); - // } - // SaveChanges(); - var result = Datas.Single(x => x.Handle == handle && x.Format == format); - result.UpdateTime=DateTime.Now; - result.Value = value; - SaveChanges(); + var result = Datas.FirstOrDefault(x => x.Handle == handle && x.Format == format); + if (result is not null) + { + result.UpdateTime=DateTime.Now; + result.Value = value; + SaveChanges(); + } + return result is not null; } } // ReSharper disable once IdentifierTypo @@ -250,5 +241,5 @@ public partial class IDIS_Service:Node public void RegisterReference(string handle,string refenceHandle) => Context.RegisterReference(handle,refenceHandle); public static string GenerateHandle() => $"88.123.99/{Mathf.Abs(Guid.NewGuid().GetHashCode())}"; public bool Query(string key, out IDIS_Query query) => Context.Query(key, out query); - public void Update(string handle, string format, string value) => Context.Update(handle, format, value); + public bool Update(string handle, string format, string value) => Context.Update(handle, format, value); } \ No newline at end of file diff --git a/Mods/工业数据采集与分析应用分享/Scripts/IDIS_UpdateService.cs b/Mods/工业数据采集与分析应用分享/Scripts/IDIS_UpdateService.cs index 00850c7..c3dab81 100644 --- a/Mods/工业数据采集与分析应用分享/Scripts/IDIS_UpdateService.cs +++ b/Mods/工业数据采集与分析应用分享/Scripts/IDIS_UpdateService.cs @@ -12,17 +12,37 @@ public partial class IDIS_UpdateService : Node [Export] private LineEdit handleEdit; [Export] private LineEdit temperatureEdit; [Export] private LineEdit humidityEdit; - [Export] private Label hintsLabel; + [Export] private RichTextLabel hintsLabel; public override void _Ready() { submitButton.Pressed += Submit; } private void Submit() { + switch (handleEdit.Text, temperatureEdit.Text, humidityEdit.Text) + { + case ("", _, _): + hintsLabel.Text = "请输入标识码"; + return; + case (_, "", _): + hintsLabel.Text = "请输入温度"; + return; + case (_, _, ""): + hintsLabel.Text = "请输入湿度"; + return; + } try { - service.Update(handleEdit.Text, "温度", humidityEdit.Text); - service.Update(handleEdit.Text, "湿度", temperatureEdit.Text); + if (service.Update(handleEdit.Text, "温度", humidityEdit.Text) is false) + { + hintsLabel.Text = "温度更新失败: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + return; + } + if (service.Update(handleEdit.Text, "湿度", temperatureEdit.Text) is false) + { + hintsLabel.Text = "湿度更新失败: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + return; + } hintsLabel.Text = "更新成功: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } catch (Exception e) @@ -30,6 +50,5 @@ public partial class IDIS_UpdateService : Node hintsLabel.Text = e.Message; throw; } - } } diff --git a/Mods/工业数据采集与分析应用分享/Scripts/温湿度Reader.cs b/Mods/工业数据采集与分析应用分享/Scripts/温湿度Reader.cs index 154ac09..fe75bd5 100644 --- a/Mods/工业数据采集与分析应用分享/Scripts/温湿度Reader.cs +++ b/Mods/工业数据采集与分析应用分享/Scripts/温湿度Reader.cs @@ -1,7 +1,10 @@ using Godot; using System; +using System.Globalization; +using System.Runtime.InteropServices; using System.Threading; using System.Timers; +using BITKit; using Cysharp.Threading.Tasks; using SharpModbus; using Timer = System.Timers.Timer; @@ -21,8 +24,11 @@ public partial class 温湿度Reader : Node [Export]public double temperature = 26.0; [ExportCategory("UI 绑定")] - [Export] private Label temperatureLabel; - [Export] private Label humidityLabel; + [Export] private UXContainer temperatureContaier; + [Export] private UXContainer humidityContainer; + [Export] private LineEdit ipEdit; + [Export] private LineEdit portEdit; + [Export] private RichTextLabel hintsLabel; private ModbusMaster _modbus; private System.Timers.Timer timer; @@ -30,7 +36,37 @@ public partial class 温湿度Reader : Node public override void _Ready() { _CancellationTokenSource = new CancellationTokenSource(); - _modbus = ModbusMaster.TCP(ip, port); + try + { + _modbus = ModbusMaster.TCP(ip, port); + } + catch (Exception e) + { + hintsLabel.Text = e.Message; + } + + + if (ipEdit is not null) + { + ipEdit.TextChanged += s => ip = s; + ipEdit.TextSubmitted +=s=> UpdatePortAndIP(); + } + if(portEdit is not null) + { + portEdit.TextSubmitted += OnPortChanged; + void OnPortChanged(string s) + { + UpdatePortAndIP(); + if (int.TryParse(s,out var newPort)) + { + } + else + { + portEdit.Text=string.Empty; + portEdit.PlaceholderText = "请输入正确的端口号"; + } + } + } timer = new Timer(); timer.Interval = interval; @@ -43,9 +79,16 @@ public partial class 温湿度Reader : Node { timer.Stop(); } + + private void UpdatePortAndIP() + { + _modbus.Dispose(); + _modbus = ModbusMaster.TCP(ip, port); + } private async void OnTimerElapsed(object sender, ElapsedEventArgs e) { + SetHints( "正在获取温湿度数据..."+DateTime.Now); _CancellationTokenSource.Cancel(); await UniTask.SwitchToTaskPool(); try @@ -56,16 +99,35 @@ public partial class 温湿度Reader : Node _CancellationTokenSource.Token.ThrowIfCancellationRequested(); - if (vs is not { Length: 2 }) return; + if (vs is not { Length: 2 }) + { + SetHints(hintsLabel.Text = $"获取温湿度数据失败:数据长度为:{vs.Length}"+DateTime.Now); + + return; + } + temperature = vs[0] / 10.0; humidity = vs[1] / 10.0; + + SetHints("已获取到温湿度数据:"+DateTime.Now); + + temperatureContaier.Text = temperature.ToString(CultureInfo.InvariantCulture); + humidityContainer.Text = humidity.ToString(CultureInfo.InvariantCulture); } catch (OperationCanceledException) { + //SetHints("连接超时:"+DateTime.Now); } catch (Exception ex) { + SetHints(ex.Message); GD.Print("ex:" + ex); } } + + private async void SetHints(string hints) + { + await UniTask.SwitchToSynchronizationContext(BITApp.SynchronizationContext); + hintsLabel.Text = hints; + } } diff --git a/Mods/工业数据采集与分析应用分享/Templates/传感器数据模板.tscn b/Mods/工业数据采集与分析应用分享/Templates/传感器数据模板.tscn index 6448b67..3333643 100644 --- a/Mods/工业数据采集与分析应用分享/Templates/传感器数据模板.tscn +++ b/Mods/工业数据采集与分析应用分享/Templates/传感器数据模板.tscn @@ -4,8 +4,8 @@ [node name="传感器数据模板" type="PanelContainer" node_paths=PackedStringArray("label", "titleLabel", "labels", "lineEdits")] script = ExtResource("1_6fjlu") -label = NodePath("") -titleLabel = NodePath("") +label = NodePath("VBoxContainer/MarginContainer/HBoxContainer/Label") +titleLabel = NodePath("VBoxContainer/Label") labels = [] lineEdits = [] diff --git a/Mods/工业数据采集与分析应用分享/标识注册与解析.tscn b/Mods/工业数据采集与分析应用分享/标识注册与解析.tscn index 31e4d0d..d28b6ed 100644 --- a/Mods/工业数据采集与分析应用分享/标识注册与解析.tscn +++ b/Mods/工业数据采集与分析应用分享/标识注册与解析.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=31 format=3 uid="uid://cngf2h2a5ne4a"] +[gd_scene load_steps=32 format=3 uid="uid://cngf2h2a5ne4a"] [ext_resource type="Script" path="res://BITKit/Scripts/UX/UXPanel.cs" id="1_c78kh"] [ext_resource type="PackedScene" uid="uid://d1po2qljd0jh2" path="res://Mods/教育平台/教程header.tscn" id="2_mn1rn"] @@ -26,6 +26,7 @@ [ext_resource type="PackedScene" uid="uid://d1rpv4oovnljv" path="res://Mods/工业数据采集与分析应用分享/Templates/传感器数据模板.tscn" id="19_qxvds"] [ext_resource type="PackedScene" uid="uid://cccx8fmmfttth" path="res://Mods/工业数据采集与分析应用分享/Templates/标识数据模板.tscn" id="20_kicyn"] [ext_resource type="Script" path="res://Mods/工业数据采集与分析应用分享/Scripts/IDIS_UpdateService.cs" id="26_a6qku"] +[ext_resource type="Script" path="res://Mods/工业数据采集与分析应用分享/Scripts/温湿度Reader.cs" id="27_q8j7q"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nfm72"] bg_color = Color(0.172549, 0.168627, 0.188235, 1) @@ -678,77 +679,122 @@ columns = 2 [node name="温湿度传感器" type="MarginContainer" parent="Layout/UX Window Service/Horizontal Layout/内容"] layout_mode = 2 theme_override_constants/margin_left = 64 -theme_override_constants/margin_top = 64 +theme_override_constants/margin_top = 100 theme_override_constants/margin_right = 64 theme_override_constants/margin_bottom = 64 [node name="VBoxContainer" type="VBoxContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器"] layout_mode = 2 size_flags_horizontal = 0 +theme_override_constants/separation = 32 -[node name="Label" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] +[node name="VBoxContainer" type="VBoxContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] layout_mode = 2 + +[node name="Label" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer"] +layout_mode = 2 +theme_type_variation = &"HeaderLarge" +theme_override_colors/font_color = Color(0.509804, 0.509804, 0.509804, 1) text = "已获取的传感器数据" -[node name="GridContainer" type="GridContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] +[node name="GridContainer2" type="GridContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="Label" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer2"] +layout_mode = 2 +text = "IP:" + +[node name="LineEdit" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "传感器的IP" + +[node name="Label2" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer2"] +layout_mode = 2 +text = "Port:" + +[node name="LineEdit2" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "传感器的端口" + +[node name="GridContainer" type="GridContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer"] layout_mode = 2 theme_override_constants/h_separation = 32 theme_override_constants/v_separation = 32 columns = 3 -[node name="传感器数据模板" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer" instance=ExtResource("19_qxvds")] +[node name="传感器数据模板" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer" instance=ExtResource("19_qxvds")] layout_mode = 2 -[node name="传感器数据模板2" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer" instance=ExtResource("19_qxvds")] +[node name="传感器数据模板2" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer" instance=ExtResource("19_qxvds")] layout_mode = 2 -[node name="更新温湿度-button" type="Button" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] +[node name="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer/传感器数据模板2/VBoxContainer" index="0"] +text = "湿度" + +[node name="Label2" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer/传感器数据模板2/VBoxContainer/MarginContainer/HBoxContainer" index="1"] +text = "%" + +[node name="RichTextLabel" type="RichTextLabel" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "正在等待连接到温湿度传感器..." +fit_content = true + +[node name="更新温湿度-button" type="Button" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer"] layout_mode = 2 text = "更新温湿度" -[node name="Label2" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] +[node name="VBoxContainer2" type="VBoxContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] layout_mode = 2 + +[node name="Label2" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2"] +layout_mode = 2 +theme_type_variation = &"HeaderLarge" +theme_override_colors/font_color = Color(0.509804, 0.509804, 0.509804, 1) text = "手动提交数据" -[node name="GridContainer2" type="GridContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] +[node name="GridContainer2" type="GridContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2"] custom_minimum_size = Vector2(512, 0) layout_mode = 2 columns = 2 -[node name="Label" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2"] +[node name="Label" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2"] layout_mode = 2 text = "标识码:" -[node name="LineEdit" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2"] +[node name="LineEdit" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2"] layout_mode = 2 size_flags_horizontal = 3 placeholder_text = "88.123.99/xxxxxxxxxxxxxxxx" -[node name="Label2" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2"] +[node name="Label2" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2"] layout_mode = 2 text = "温度:" -[node name="LineEdit2" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2"] +[node name="LineEdit2" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2"] layout_mode = 2 size_flags_horizontal = 3 placeholder_text = "42" -[node name="Label3" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2"] +[node name="Label3" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2"] layout_mode = 2 text = "湿度:" -[node name="LineEdit3" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2"] +[node name="LineEdit3" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2"] layout_mode = 2 size_flags_horizontal = 3 placeholder_text = "50" -[node name="更新温湿度-button2" type="Button" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] +[node name="更新温湿度-button2" type="Button" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2"] layout_mode = 2 text = "更新温湿度标识" -[node name="Label3" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer"] +[node name="Label3" type="RichTextLabel" parent="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2"] layout_mode = 2 text = "等待更新中" +fit_content = true [node name="Control" type="Control" parent="Layout/UX Window Service/Horizontal Layout"] layout_mode = 2 @@ -801,11 +847,21 @@ categoryTemplate = ExtResource("20_kicyn") [node name="温湿度标识更新服务" type="Node" parent="." node_paths=PackedStringArray("service", "submitButton", "handleEdit", "temperatureEdit", "humidityEdit", "hintsLabel")] script = ExtResource("26_a6qku") service = NodePath("../标识解析服务") -submitButton = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/更新温湿度-button2") -handleEdit = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2/LineEdit") -temperatureEdit = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2/LineEdit2") -humidityEdit = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/GridContainer2/LineEdit3") -hintsLabel = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/Label3") +submitButton = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/更新温湿度-button2") +handleEdit = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2/LineEdit") +temperatureEdit = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2/LineEdit2") +humidityEdit = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/GridContainer2/LineEdit3") +hintsLabel = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer2/Label3") + +[node name="温湿度传感器Reader" type="Node" parent="." node_paths=PackedStringArray("temperatureContaier", "humidityContainer", "ipEdit", "portEdit", "hintsLabel")] +script = ExtResource("27_q8j7q") +temperatureContaier = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer/传感器数据模板") +humidityContainer = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer/传感器数据模板2") +ipEdit = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer2/LineEdit") +portEdit = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer2/LineEdit2") +hintsLabel = NodePath("../Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/RichTextLabel") [connection signal="pressed" from="Layout/UX Window Service/Horizontal Layout/导航栏/MarginContainer/Layout/Button5" to="Layout/UX Window Service/Horizontal Layout/导航栏/MarginContainer/Layout/Button5" method="Return"] [connection signal="draw" from="Layout/UX Window Service/Horizontal Layout/内容/标注注册" to="标识注册服务" method="Rebuild"] + +[editable path="Layout/UX Window Service/Horizontal Layout/内容/温湿度传感器/VBoxContainer/VBoxContainer/GridContainer/传感器数据模板2"]