2023-07-10 00:00:20 +08:00
|
|
|
using Godot;
|
|
|
|
using System;
|
2023-07-12 12:11:10 +08:00
|
|
|
using System.Collections.Generic;
|
2023-07-10 15:50:11 +08:00
|
|
|
using System.Globalization;
|
2023-07-12 12:11:10 +08:00
|
|
|
using System.Net.Mime;
|
2023-07-10 15:50:11 +08:00
|
|
|
using System.Runtime.InteropServices;
|
2023-07-10 00:00:20 +08:00
|
|
|
using System.Threading;
|
|
|
|
using System.Timers;
|
2023-07-10 15:50:11 +08:00
|
|
|
using BITKit;
|
2023-07-10 00:00:20 +08:00
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
using SharpModbus;
|
|
|
|
using Timer = System.Timers.Timer;
|
|
|
|
|
|
|
|
namespace BITFactory;
|
|
|
|
public partial class 温湿度Reader : Node
|
|
|
|
{
|
|
|
|
[ExportCategory("参数")]
|
2023-07-12 12:11:10 +08:00
|
|
|
[Export(PropertyHint.Range,"100,2000")] private int interval=500;
|
2023-07-10 00:00:20 +08:00
|
|
|
|
|
|
|
[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 绑定")]
|
2023-07-10 15:50:11 +08:00
|
|
|
[Export] private UXContainer temperatureContaier;
|
|
|
|
[Export] private UXContainer humidityContainer;
|
|
|
|
[Export] private LineEdit ipEdit;
|
|
|
|
[Export] private LineEdit portEdit;
|
|
|
|
[Export] private RichTextLabel hintsLabel;
|
2023-07-10 00:00:20 +08:00
|
|
|
|
|
|
|
private ModbusMaster _modbus;
|
|
|
|
private System.Timers.Timer timer;
|
|
|
|
private CancellationTokenSource _CancellationTokenSource;
|
2023-07-12 12:11:10 +08:00
|
|
|
|
2023-07-10 00:00:20 +08:00
|
|
|
public override void _Ready()
|
|
|
|
{
|
|
|
|
_CancellationTokenSource = new CancellationTokenSource();
|
2023-07-10 15:50:11 +08:00
|
|
|
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 = "请输入正确的端口号";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-07-12 12:11:10 +08:00
|
|
|
|
|
|
|
UpdatePortAndIP();
|
2023-07-10 00:00:20 +08:00
|
|
|
|
|
|
|
timer = new Timer();
|
|
|
|
timer.Interval = interval;
|
|
|
|
timer.Elapsed += OnTimerElapsed;
|
2023-07-12 12:11:10 +08:00
|
|
|
timer.AutoReset = false;
|
2023-07-10 00:00:20 +08:00
|
|
|
timer.Start();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void _ExitTree()
|
|
|
|
{
|
2023-07-12 15:27:27 +08:00
|
|
|
_CancellationTokenSource.Cancel();
|
2023-07-10 00:00:20 +08:00
|
|
|
timer.Stop();
|
|
|
|
}
|
2023-07-12 12:11:10 +08:00
|
|
|
/// <summary>
|
|
|
|
/// 内部方法,用于更新IP和端口
|
|
|
|
/// </summary>
|
2023-07-10 15:50:11 +08:00
|
|
|
private void UpdatePortAndIP()
|
|
|
|
{
|
2023-07-12 12:11:10 +08:00
|
|
|
_modbus?.Dispose();
|
|
|
|
try
|
|
|
|
{
|
|
|
|
_modbus = ModbusMaster.TCP(ip, port);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
BIT4Log.Log<温湿度Reader>(e.Message);
|
2023-07-18 21:14:22 +08:00
|
|
|
hintsLabel.SetTextAsync(e.Message);
|
2023-07-12 12:11:10 +08:00
|
|
|
}
|
|
|
|
|
2023-07-10 15:50:11 +08:00
|
|
|
}
|
2023-07-12 12:11:10 +08:00
|
|
|
/// <summary>
|
|
|
|
/// 内部方法,定时器回调用于读取Modbus
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="sender"></param>
|
|
|
|
/// <param name="e"></param>
|
2023-07-10 00:00:20 +08:00
|
|
|
private async void OnTimerElapsed(object sender, ElapsedEventArgs e)
|
|
|
|
{
|
|
|
|
await UniTask.SwitchToTaskPool();
|
|
|
|
try
|
|
|
|
{
|
2023-07-18 20:57:02 +08:00
|
|
|
if (_modbus is null)
|
|
|
|
{
|
|
|
|
hintsLabel.SetTextAsync("Modbus未初始化");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-07-12 15:27:27 +08:00
|
|
|
_CancellationTokenSource.Token.ThrowIfCancellationRequested();
|
2023-07-12 12:11:10 +08:00
|
|
|
hintsLabel.SetTextAsync( "正在读取温湿度数据..."+DateTime.Now);
|
2023-07-10 00:00:20 +08:00
|
|
|
|
|
|
|
var vs = _modbus.ReadInputRegisters(1, 0, 2);
|
2023-07-12 12:11:10 +08:00
|
|
|
|
2023-07-12 15:27:27 +08:00
|
|
|
_CancellationTokenSource.Token.ThrowIfCancellationRequested();
|
|
|
|
|
2023-07-12 12:11:10 +08:00
|
|
|
hintsLabel.SetTextAsync( "已采集到数据,正在解析..."+DateTime.Now);
|
2023-07-10 00:00:20 +08:00
|
|
|
|
2023-07-10 15:50:11 +08:00
|
|
|
if (vs is not { Length: 2 })
|
|
|
|
{
|
2023-07-12 12:11:10 +08:00
|
|
|
hintsLabel.SetTextAsync(hintsLabel.Text = $"获取温湿度数据失败:数据长度为:{vs.Length}"+DateTime.Now);
|
2023-07-10 15:50:11 +08:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-07-10 00:00:20 +08:00
|
|
|
temperature = vs[0] / 10.0;
|
|
|
|
humidity = vs[1] / 10.0;
|
2023-07-10 15:50:11 +08:00
|
|
|
|
2023-07-12 12:11:10 +08:00
|
|
|
hintsLabel.SetTextAsync("已获取到温湿度数据:"+DateTime.Now);
|
2023-07-10 15:50:11 +08:00
|
|
|
|
2023-07-12 12:11:10 +08:00
|
|
|
temperatureContaier.label.SetTextAsync(temperature.ToString(CultureInfo.InvariantCulture)); ;
|
|
|
|
humidityContainer.label.SetTextAsync(humidity.ToString(CultureInfo.InvariantCulture));
|
2023-07-12 15:27:27 +08:00
|
|
|
|
|
|
|
timer.Start();
|
2023-07-10 00:00:20 +08:00
|
|
|
}
|
|
|
|
catch (OperationCanceledException)
|
|
|
|
{
|
2023-07-12 15:27:27 +08:00
|
|
|
BIT4Log.Log<温湿度Reader>($"Modbus读取任务已取消");
|
2023-07-10 00:00:20 +08:00
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
2023-07-12 12:11:10 +08:00
|
|
|
hintsLabel.SetTextAsync(ex.Message);
|
2023-07-12 15:27:27 +08:00
|
|
|
timer.Start();
|
2023-07-10 00:00:20 +08:00
|
|
|
}
|
2023-07-12 15:27:27 +08:00
|
|
|
|
2023-07-10 00:00:20 +08:00
|
|
|
}
|
2023-07-10 15:50:11 +08:00
|
|
|
|
2023-07-10 00:00:20 +08:00
|
|
|
}
|