using Godot; using System; using System.Threading; using System.Timers; using Cysharp.Threading.Tasks; using SharpModbus; using Timer = System.Timers.Timer; namespace BITFactory; public partial class 温湿度Reader : Node { [ExportCategory("参数")] [Export(PropertyHint.Range,"100,1000")] 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 Label temperatureLabel; [Export] private Label humidityLabel; private ModbusMaster _modbus; private System.Timers.Timer timer; private CancellationTokenSource _CancellationTokenSource; public override void _Ready() { _CancellationTokenSource = new CancellationTokenSource(); _modbus = ModbusMaster.TCP(ip, port); timer = new Timer(); timer.Interval = interval; timer.Elapsed += OnTimerElapsed; timer.AutoReset = true; timer.Start(); } public override void _ExitTree() { timer.Stop(); } private async void OnTimerElapsed(object sender, ElapsedEventArgs e) { _CancellationTokenSource.Cancel(); await UniTask.SwitchToTaskPool(); try { _CancellationTokenSource.Token.ThrowIfCancellationRequested(); var vs = _modbus.ReadInputRegisters(1, 0, 2); _CancellationTokenSource.Token.ThrowIfCancellationRequested(); if (vs is not { Length: 2 }) return; temperature = vs[0] / 10.0; humidity = vs[1] / 10.0; } catch (OperationCanceledException) { } catch (Exception ex) { GD.Print("ex:" + ex); } } }