feat: 增加特殊地址变量,方便用户自定义设备状态变量或当前设备计算点
This commit is contained in:
@@ -53,5 +53,32 @@ VS的bug导致的,可以尝试升级vs,把工程目录下的.vs文件夹已
|
||||
选择一种解决方案:
|
||||
|
||||
1、升级操作系统,
|
||||
|
||||
2、升级sqlite版本,(感谢群友的文章)查看博客 (https://blog.csdn.net/qq_40817472/article/details/141648765)
|
||||
3、使用net6发布ThingsGateway项目
|
||||
|
||||
3、使用net6发布ThingsGateway项目
|
||||
|
||||
|
||||
#### 7、我想在当前设备中添加变量,该变量表示设备是否在线,不参与通讯
|
||||
|
||||
在变量地址中填写``DeviceStatus``,固定值为``DeviceStatusEnum``类型,如果需要bool类型,还可以在读取表达式中写
|
||||
```
|
||||
(DeviceStatusEnum)raw==DeviceStatusEnum.OnLine
|
||||
```
|
||||
|
||||
|
||||
#### 8、我想在当前设备中添加变量,该变量作为计算点,不参与通讯
|
||||
|
||||
在变量地址中填写``Script``,在读取表达式中填写所需计算过程
|
||||
|
||||
```
|
||||
|
||||
不限制是否当前设备,只要变量名称存在,就可以正常运算
|
||||
下面示例是 两个变量值相加
|
||||
|
||||
|
||||
GlobalData.ReadOnlyVariables["变量名称1"].Value.ToInt()+GlobalData.ReadOnlyVariables["变量名称2"].Value.ToInt()
|
||||
|
||||
```
|
||||
|
||||
同理,在内存变量插件中,也可以这样写。
|
||||
|
@@ -147,4 +147,6 @@ public class TestCollectProperty : CollectPropertyBase
|
||||
|
||||
## 三、插件实现目的
|
||||
|
||||
从上面可以看出,插件需开发者继承对应基类后,自行实现设备通讯,最终目的是按需更新设备/变量状态值
|
||||
从上面可以看出,插件需开发者继承对应基类后,自行实现设备通讯,最终目的是按需更新设备/变量状态值
|
||||
|
||||
CollectBase基类中,已经包含当前设备``CurrentDevice``,当前变量``CurrentDevice.VariableRunTimes``
|
@@ -50,4 +50,13 @@ public class CollectDeviceRunTime : DeviceRunTime
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
[AdaptIgnore]
|
||||
public List<VariableSourceRead>? VariableSourceReads { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 特殊地址变量
|
||||
/// </summary>
|
||||
[System.Text.Json.Serialization.JsonIgnore]
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
[AdaptIgnore]
|
||||
public List<VariableRunTime>? OtherVariableRunTimes { get; set; }
|
||||
}
|
||||
|
@@ -62,9 +62,24 @@ public abstract class CollectBase : DriverBase
|
||||
var tags = collectVariableRunTimes
|
||||
.Where(it => it.ProtectType != ProtectTypeEnum.WriteOnly
|
||||
&& string.IsNullOrEmpty(it.OtherMethod)
|
||||
&& !string.IsNullOrEmpty(it.RegisterAddress)).ToList();
|
||||
&& !string.IsNullOrEmpty(it.RegisterAddress));
|
||||
|
||||
|
||||
//筛选特殊变量地址
|
||||
//1、DeviceStatus
|
||||
Func<VariableRunTime, bool> source = (a =>
|
||||
{
|
||||
return a.RegisterAddress != nameof(DeviceRunTime.DeviceStatus) &&
|
||||
a.RegisterAddress != "Script"
|
||||
;
|
||||
|
||||
});
|
||||
|
||||
|
||||
currentDevice.OtherVariableRunTimes = tags.Where(a => !source(a)).ToList();
|
||||
|
||||
// 将打包后的结果存储在当前设备的 VariableSourceReads 属性中
|
||||
currentDevice.VariableSourceReads = ProtectedLoadSourceRead(tags);
|
||||
currentDevice.VariableSourceReads = ProtectedLoadSourceRead(tags.Where(source).ToList());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -214,9 +229,14 @@ public abstract class CollectBase : DriverBase
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 如果所有方法和变量读取都成功,则清零错误计数器
|
||||
if (readResultCount.deviceMethodsVariableFailedNum == 0 && readResultCount.deviceSourceVariableFailedNum == 0 && (readResultCount.deviceMethodsVariableSuccessNum != 0 || readResultCount.deviceSourceVariableSuccessNum != 0))
|
||||
{
|
||||
ScriptVariableRun(cancellationToken);
|
||||
|
||||
//只有成功读取一次,失败次数都会清零
|
||||
CurrentDevice.SetDeviceStatus(TimerX.Now, 0);
|
||||
}
|
||||
@@ -430,6 +450,28 @@ public abstract class CollectBase : DriverBase
|
||||
}
|
||||
}
|
||||
|
||||
protected void ScriptVariableRun(CancellationToken cancellationToken)
|
||||
{
|
||||
DateTime dateTime = TimerX.Now;
|
||||
//特殊地址变量
|
||||
for (int i = 0; i < CurrentDevice.OtherVariableRunTimes.Count; i++)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
var variableRunTime = CurrentDevice.OtherVariableRunTimes[i];
|
||||
if (variableRunTime.RegisterAddress == nameof(DeviceRunTime.DeviceStatus))
|
||||
{
|
||||
variableRunTime.SetValue(variableRunTime.CollectDeviceRunTime.DeviceStatus, dateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
variableRunTime.SetValue(default, dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连读打包,返回实际通讯包信息<see cref="VariableSourceRead"/>
|
||||
/// <br></br>每个驱动打包方法不一样,所以需要实现这个接口
|
||||
|
@@ -240,6 +240,7 @@ public partial class MqttCollect : CollectBase
|
||||
CurrentDevice.SetDeviceStatus(TimerX.Now, 999);
|
||||
}
|
||||
|
||||
ScriptVariableRun(cancellationToken);
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -111,6 +111,9 @@ public class OpcDaMaster : CollectBase
|
||||
{
|
||||
CurrentDevice.SetDeviceStatus(TimerX.Now, 999);
|
||||
}
|
||||
|
||||
ScriptVariableRun(cancellationToken);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -83,7 +83,6 @@ public class OpcUaMaster : CollectBase
|
||||
return $"{_driverProperties.OpcUrl}";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
@@ -142,6 +141,8 @@ public class OpcUaMaster : CollectBase
|
||||
}
|
||||
if (_driverProperties.ActiveSubscribe)
|
||||
{
|
||||
ScriptVariableRun(cancellationToken);
|
||||
|
||||
//获取设备连接状态
|
||||
if (IsConnected())
|
||||
{
|
||||
|
@@ -108,6 +108,7 @@ public static class ExpressionEvaluatorExtension
|
||||
using System.Collections.Generic;
|
||||
using ThingsGateway.NewLife.X;
|
||||
using ThingsGateway.Gateway.Application.Extensions;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
{_using}
|
||||
public class Script:ReadWriteExpressions
|
||||
{{
|
||||
|
Reference in New Issue
Block a user