using Godot; using System; using System.Collections.Generic; using System.Globalization; using System.Net.Mime; using System.Runtime.InteropServices; using System.Threading; using System.Timers; using BITKit; using Cysharp.Threading.Tasks; using SharpModbus; using Timer = System.Timers.Timer; namespace BITFactory; public partial class 温湿度Reader : Node { [ExportCategory("参数")] [Export(PropertyHint.Range,"100,2000")] private int interval=500; [ExportCategory("网络设置")] [Export] private string ip="192.168.3.7"; [Export] private int port=502; [ExportCategory("运行时")] [Export]public double humidity = 50.0; [Export]public double temperature = 26.0; [ExportCategory("UI 绑定")] [Export] private Button connectToModbusButton; [Export] private UXContainer temperatureContainer; [Export] private UXContainer humidityContainer; [Export] private LineEdit ipEdit; [Export] private LineEdit portEdit; [Export] private RichTextLabel hintsLabel; private ModbusMaster _modbus; private Timer timer; private CancellationTokenSource _CancellationTokenSource; public override void _Ready() { _CancellationTokenSource = new CancellationTokenSource(); try { _modbus = ModbusMaster.TCP(ip, port); } catch (Exception e) { hintsLabel.Text = e.Message; } ipEdit.TextChanged+=s=>ip=s; portEdit.TextChanged+=s=> { try { port = int.Parse(s); } catch (Exception e) { hintsLabel.SetTextAsync(e.Message); } }; connectToModbusButton.Pressed += Connect; Connect(); timer = new Timer(); timer.Interval = interval; timer.Elapsed += OnTimerElapsed; timer.AutoReset = false; timer.Start(); } public override void _ExitTree() { _CancellationTokenSource.Cancel(); timer.Stop(); } /// /// 连接到Modbus /// private void Connect() { _modbus?.Dispose(); try { _modbus = ModbusMaster.TCP(ip, port); } catch (Exception e) { BIT4Log.Log<温湿度Reader>(e.Message); hintsLabel.SetTextAsync(e.Message); } } /// /// 内部方法,定时器回调用于读取Modbus /// /// /// private async void OnTimerElapsed(object sender, ElapsedEventArgs e) { await UniTask.SwitchToTaskPool(); try { if (_modbus is null) { hintsLabel.SetTextAsync("Modbus未初始化"); timer.Start(); return; } _CancellationTokenSource.Token.ThrowIfCancellationRequested(); hintsLabel.SetTextAsync( "正在读取温湿度数据..."+DateTime.Now); var vs = _modbus.ReadInputRegisters(1, 0, 2); _CancellationTokenSource.Token.ThrowIfCancellationRequested(); hintsLabel.SetTextAsync( "已采集到数据,正在解析..."+DateTime.Now); if (vs is not { Length: 2 }) { hintsLabel.SetTextAsync(hintsLabel.Text = $"获取温湿度数据失败:数据长度为:{vs.Length}"+DateTime.Now); return; } temperature = vs[0] / 10.0; humidity = vs[1] / 10.0; hintsLabel.SetTextAsync("已获取到温湿度数据:"+DateTime.Now); temperatureContainer.label.SetTextAsync(temperature.ToString(CultureInfo.InvariantCulture)); ; humidityContainer.label.SetTextAsync(humidity.ToString(CultureInfo.InvariantCulture)); timer.Start(); } catch (OperationCanceledException) { BIT4Log.Log<温湿度Reader>($"Modbus读取任务已取消"); } catch (Exception ex) { hintsLabel.SetTextAsync(ex.Message); timer.Start(); } } }