Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65c695d9ce | ||
|
|
57253fe46a | ||
|
|
4e5c443440 | ||
|
|
0b3b73d8ec | ||
|
|
921eabc134 | ||
|
|
0faa428751 | ||
|
|
f71a2fdd63 | ||
|
|
4eb9ed8aba | ||
|
|
d7b549abb8 | ||
|
|
95d723c578 | ||
|
|
2fcd853e86 | ||
|
|
07eef7c812 | ||
|
|
b01e0757fa |
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Version>2.0.9.2</Version>
|
||||
<Version>2.1.0.0</Version>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.40" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.40" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.8.8.40" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.99" />
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.41" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.41" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.8.8.41" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.102" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
<PackageReference Include="MiniExcel" Version="1.31.2" />
|
||||
|
||||
@@ -89,13 +89,8 @@ public class RpcControler : IDynamicApiController
|
||||
[Description("写入变量")]
|
||||
public async Task<Dictionary<string, OperResult>> WriteDeviceMethods(Dictionary<string, string> objs)
|
||||
{
|
||||
Dictionary<string, OperResult> operResultDict = new();
|
||||
foreach (KeyValuePair<string, string> obj in objs)
|
||||
{
|
||||
var result = await RpcCore.InvokeDeviceMethodAsync($"WebApi-{UserManager.UserAccount}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", obj);
|
||||
operResultDict.Add(obj.Key, result);
|
||||
}
|
||||
return operResultDict;
|
||||
var result = await RpcCore.InvokeDeviceMethodAsync($"WebApi-{UserManager.UserAccount}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", objs);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@ public abstract class CollectBase : DriverBase
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool IsSupportRequest { get; }
|
||||
/// <summary>
|
||||
/// 一般底层驱动,也有可能为null
|
||||
/// </summary>
|
||||
protected abstract IReadWriteDevice PLC { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据转换器
|
||||
@@ -177,10 +181,22 @@ public abstract class CollectBase : DriverBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入变量值
|
||||
/// 批量写入变量值,需返回变量名称/结果
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token);
|
||||
public virtual async Task<Dictionary<string, OperResult>> WriteValuesAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token)
|
||||
{
|
||||
if (PLC == null)
|
||||
throw new("未初始化成功");
|
||||
Dictionary<string, OperResult> operResults = new();
|
||||
foreach (var writeInfo in writeInfoLists)
|
||||
{
|
||||
var result = await PLC.WriteAsync(writeInfo.Key.VariableAddress, writeInfo.Key.DataType, writeInfo.Value.ToString(), token);
|
||||
await Task.Delay(10, token); //防止密集写入
|
||||
operResults.Add(writeInfo.Key.Name, result);
|
||||
}
|
||||
return operResults;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
|
||||
@@ -48,92 +48,172 @@ public class RpcSingletonService : ISingleton
|
||||
/// 反向RPC入口方法
|
||||
/// </summary>
|
||||
/// <param name="sourceDes">触发该方法的源说明</param>
|
||||
/// <param name="item">指定键为变量名称,值为附带方法参数或写入值</param>
|
||||
/// <param name="items">指定键为变量名称,值为附带方法参数或写入值</param>
|
||||
/// <param name="isBlazor">如果是true,不检查<see cref="MemoryVariable.RpcWriteEnable"/>字段</param>
|
||||
/// <param name="token"><see cref="CancellationToken"/> 取消源</param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> InvokeDeviceMethodAsync(string sourceDes, KeyValuePair<string, string> item, bool isBlazor = false, CancellationToken token = default)
|
||||
public async Task<Dictionary<string, OperResult>> InvokeDeviceMethodAsync(string sourceDes, Dictionary<string, string> items, bool isBlazor = false, CancellationToken token = default)
|
||||
{
|
||||
//避免并发过高,这里延时10ms
|
||||
await Task.Delay(10, token);
|
||||
OperResult data = new();
|
||||
var tag = _globalDeviceData.AllVariables.FirstOrDefault(it => it.Name == item.Key);
|
||||
if (tag == null) return new OperResult("不存在变量:" + item.Key);
|
||||
if (tag.ProtectTypeEnum == ProtectTypeEnum.ReadOnly) return new OperResult("只读变量");
|
||||
if (!tag.RpcWriteEnable && !isBlazor) return new OperResult("不允许远程写入");
|
||||
|
||||
if (tag.IsMemoryVariable == true)
|
||||
Dictionary<CollectDeviceCore, Dictionary<DeviceVariableRunTime, JToken>> WriteVariables = new();
|
||||
Dictionary<CollectDeviceCore, Dictionary<DeviceVariableRunTime, string>> WriteMethods = new();
|
||||
Dictionary<string, OperResult> results = new();
|
||||
foreach (var item in items)
|
||||
{
|
||||
return tag.SetValue(item.Value);
|
||||
}
|
||||
var dev = _collectDeviceHostService.CollectDeviceCores.FirstOrDefault(it => it.Device.Id == tag.DeviceId);
|
||||
if (dev == null) return new OperResult("系统错误,不存在对应采集设备,请稍候重试");
|
||||
if (dev.Device.DeviceStatus == DeviceStatusEnum.OffLine) return new OperResult("设备已离线");
|
||||
if (dev.Device.DeviceStatus == DeviceStatusEnum.Pause) return new OperResult("设备已暂停");
|
||||
if (string.IsNullOrEmpty(tag.OtherMethod))
|
||||
{
|
||||
//写入变量
|
||||
JToken tagValue;
|
||||
try
|
||||
{
|
||||
tagValue = JToken.Parse(item.Value);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
tagValue = JToken.Parse("\"" + item.Value + "\"");
|
||||
}
|
||||
|
||||
data = await dev.InVokeWriteAsync(tag, tagValue, token);
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
OperResult data = new();
|
||||
var tag = _globalDeviceData.AllVariables.FirstOrDefault(it => it.Name == item.Key);
|
||||
if (tag == null)
|
||||
results.Add(item.Key, new("不存在变量:" + item.Key));
|
||||
if (tag.ProtectTypeEnum == ProtectTypeEnum.ReadOnly)
|
||||
results.Add(item.Key, new("只读变量:" + item.Key));
|
||||
if (!tag.RpcWriteEnable && !isBlazor)
|
||||
results.Add(item.Key, new("不允许远程写入:" + item.Key));
|
||||
|
||||
if (tag.IsMemoryVariable == true)
|
||||
{
|
||||
results.Add(item.Key, tag.SetValue(item.Value));
|
||||
}
|
||||
var dev = _collectDeviceHostService.CollectDeviceCores.FirstOrDefault(it => it.Device.Id == tag.DeviceId);
|
||||
if (dev == null)
|
||||
results.Add(item.Key, new OperResult("系统错误,不存在对应采集设备,请稍候重试"));
|
||||
if (dev.Device.DeviceStatus == DeviceStatusEnum.OffLine)
|
||||
results.Add(item.Key, new OperResult("设备已离线"));
|
||||
if (dev.Device.DeviceStatus == DeviceStatusEnum.Pause)
|
||||
results.Add(item.Key, new OperResult("设备已暂停"));
|
||||
|
||||
if (!results.ContainsKey(item.Key))
|
||||
{
|
||||
if (string.IsNullOrEmpty(tag.OtherMethod))
|
||||
{
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
OperateMessage = data.Exception,
|
||||
IsSuccess = data.IsSuccess,
|
||||
OperateMethod = WriteVariable,
|
||||
OperateObject = tag.Name,
|
||||
OperateSource = sourceDes,
|
||||
ParamJson = item.Value,
|
||||
ResultJson = data.Message
|
||||
//写入变量
|
||||
JToken tagValue;
|
||||
try
|
||||
{
|
||||
tagValue = JToken.Parse(item.Value);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
tagValue = JToken.Parse("\"" + item.Value + "\"");
|
||||
}
|
||||
if (WriteVariables.ContainsKey(dev))
|
||||
{
|
||||
|
||||
WriteVariables[dev].Add(tag, tagValue);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteVariables.Add(dev, new());
|
||||
WriteVariables[dev].Add(tag, tagValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WriteMethods.ContainsKey(dev))
|
||||
{
|
||||
|
||||
WriteMethods[dev].Add(tag, item.Value);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteVariables.Add(dev, new());
|
||||
WriteVariables[dev].Add(tag, item.Value);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (!data.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning($"写入变量[{tag.Name}]失败:{data.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
foreach (var item in WriteVariables)
|
||||
{
|
||||
//执行变量附带的方法
|
||||
var method = dev.DeviceVariableMethodSources.FirstOrDefault(it => it.DeviceVariable == tag);
|
||||
try
|
||||
{
|
||||
data = await dev.InvokeMethodAsync(method, false, item.Value, token);
|
||||
var result = await item.Key.InVokeWriteAsync(item.Value, token);
|
||||
foreach (var resultItem in result)
|
||||
{
|
||||
string operObj;
|
||||
string parJson;
|
||||
if (resultItem.Key.IsNullOrEmpty())
|
||||
{
|
||||
operObj = items.Select(x => x.Key).ToJsonString();
|
||||
parJson = items.Select(x => x.Value).ToJsonString();
|
||||
}
|
||||
else
|
||||
{
|
||||
operObj = resultItem.Key;
|
||||
parJson = items[resultItem.Key];
|
||||
|
||||
}
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
{
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
OperateMessage = resultItem.Value.Exception,
|
||||
IsSuccess = resultItem.Value.IsSuccess,
|
||||
OperateMethod = WriteVariable,
|
||||
OperateObject = operObj,
|
||||
OperateSource = sourceDes,
|
||||
ParamJson = parJson,
|
||||
ResultJson = resultItem.Value.Message
|
||||
}
|
||||
);
|
||||
if (!resultItem.Value.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning($"写入变量[{resultItem.Key}]失败:{resultItem.Value.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
results.AddRange(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
data = new OperResult<string>(ex);
|
||||
}
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
{
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
OperateMessage = data.Exception,
|
||||
IsSuccess = data.IsSuccess,
|
||||
OperateMethod = tag.OtherMethod,
|
||||
OperateObject = tag.Name,
|
||||
OperateSource = sourceDes,
|
||||
ParamJson = item.Value?.ToString(),
|
||||
ResultJson = data.Message
|
||||
}
|
||||
);
|
||||
if (!data.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning($"执行变量[{tag.Name}]方法[{tag.OtherMethod}]失败:{data.Message}");
|
||||
_logger.LogWarning($"写入变量异常:{ex.Message + Environment.NewLine + ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
return data;
|
||||
foreach (var item in WriteMethods)
|
||||
{
|
||||
foreach (var writeMethod in item.Value)
|
||||
{
|
||||
|
||||
//执行变量附带的方法
|
||||
var method = item.Key.DeviceVariableMethodSources.FirstOrDefault(it => it.DeviceVariable == writeMethod.Key);
|
||||
OperResult<string> result;
|
||||
try
|
||||
{
|
||||
result = await item.Key.InvokeMethodAsync(method, false, writeMethod.Value, token);
|
||||
results.Add(writeMethod.Key.Name, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = new OperResult<string>(ex);
|
||||
results.Add(writeMethod.Key.Name, result);
|
||||
}
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
{
|
||||
LogTime = SysDateTimeExtensions.CurrentDateTime,
|
||||
OperateMessage = result.Exception,
|
||||
IsSuccess = result.IsSuccess,
|
||||
OperateMethod = writeMethod.Key.OtherMethod,
|
||||
OperateObject = writeMethod.Key.Name,
|
||||
OperateSource = sourceDes,
|
||||
ParamJson = writeMethod.Value?.ToString(),
|
||||
ResultJson = result.Message
|
||||
}
|
||||
);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
_logger.LogWarning($"执行变量[{writeMethod.Key.Name}]方法[{writeMethod.Key.OtherMethod}]失败:{result.Message}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async Task RpcLogInsertAsync()
|
||||
{
|
||||
|
||||
@@ -319,6 +319,39 @@
|
||||
"UpdateUserId": null,
|
||||
"SortCode": 0,
|
||||
"ExtJson": null
|
||||
},
|
||||
|
||||
{
|
||||
"Id": 442505,
|
||||
"FileName": "ThingsGateway.DLT645",
|
||||
"AssembleName": "DLT645_2007",
|
||||
"DriverTypeEnum": "Collect",
|
||||
"FilePath": "Plugins/ThingsGateway.DLT645/ThingsGateway.DLT645.dll",
|
||||
"CreateTime": "2023/8/6 18:22:33",
|
||||
"CreateUser": "superAdmin",
|
||||
"CreateUserId": 212725263002001,
|
||||
"IsDelete": 0,
|
||||
"UpdateTime": null,
|
||||
"UpdateUser": null,
|
||||
"UpdateUserId": null,
|
||||
"SortCode": 0,
|
||||
"ExtJson": null
|
||||
},
|
||||
{
|
||||
"Id": 442506,
|
||||
"FileName": "ThingsGateway.DLT645",
|
||||
"AssembleName": "DLT645_2007OverTcp",
|
||||
"DriverTypeEnum": "Collect",
|
||||
"FilePath": "Plugins/ThingsGateway.DLT645/ThingsGateway.DLT645.dll",
|
||||
"CreateTime": "2023/8/6 18:22:33",
|
||||
"CreateUser": "superAdmin",
|
||||
"CreateUserId": 212725263002001,
|
||||
"IsDelete": 0,
|
||||
"UpdateTime": null,
|
||||
"UpdateUser": null,
|
||||
"UpdateUserId": null,
|
||||
"SortCode": 0,
|
||||
"ExtJson": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -37,7 +37,7 @@
|
||||
<PackageReference Include="Hardware.Info" Version="11.1.1.1" />
|
||||
<PackageReference Include="CS-Script" Version="4.8.1" />
|
||||
<!--CS-Script与Furion冲突,直接安装覆盖版本-->
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.6.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1855,6 +1855,11 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.CollectBase.PLC">
|
||||
<summary>
|
||||
一般底层驱动,也有可能为null
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Application.CollectBase.ThingsGatewayBitConverter">
|
||||
<summary>
|
||||
数据转换器
|
||||
@@ -1906,9 +1911,9 @@
|
||||
采集驱动读取
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.CollectBase.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.Application.CollectBase.WriteValuesAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
写入变量值
|
||||
批量写入变量值,需返回变量名称/结果
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
@@ -2242,12 +2247,12 @@
|
||||
<member name="M:ThingsGateway.Application.RpcSingletonService.#ctor(Microsoft.Extensions.Logging.ILogger{ThingsGateway.Application.RpcSingletonService})">
|
||||
<inheritdoc cref="T:ThingsGateway.Application.RpcSingletonService"/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.RpcSingletonService.InvokeDeviceMethodAsync(System.String,System.Collections.Generic.KeyValuePair{System.String,System.String},System.Boolean,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.Application.RpcSingletonService.InvokeDeviceMethodAsync(System.String,System.Collections.Generic.Dictionary{System.String,System.String},System.Boolean,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
反向RPC入口方法
|
||||
</summary>
|
||||
<param name="sourceDes">触发该方法的源说明</param>
|
||||
<param name="item">指定键为变量名称,值为附带方法参数或写入值</param>
|
||||
<param name="items">指定键为变量名称,值为附带方法参数或写入值</param>
|
||||
<param name="isBlazor">如果是true,不检查<see cref="P:ThingsGateway.Application.MemoryVariable.RpcWriteEnable"/>字段</param>
|
||||
<param name="token"><see cref="T:System.Threading.CancellationToken"/> 取消源</param>
|
||||
<returns></returns>
|
||||
@@ -3505,7 +3510,7 @@
|
||||
执行特殊方法
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceCore.InVokeWriteAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.Application.CollectDeviceCore.InVokeWriteAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
执行变量写入
|
||||
</summary>
|
||||
|
||||
@@ -433,11 +433,11 @@ public class CollectDeviceCore
|
||||
if (_driver.IsConnected())
|
||||
{
|
||||
//更新设备活动时间
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, 0);
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, errorCount: 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, 999);
|
||||
Device.SetDeviceStatus(errorCount: 999);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,46 +712,46 @@ public class CollectDeviceCore
|
||||
/// 执行变量写入
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal async Task<OperResult> InVokeWriteAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
internal async Task<Dictionary<string, OperResult>> InVokeWriteAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
await easyLock.WaitAsync();
|
||||
if (IsShareChannel) _driver.InitDataAdapter();
|
||||
Dictionary<string, OperResult> results = new();
|
||||
foreach (var deviceVariable in writeInfoLists.Keys)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(deviceVariable.WriteExpressions))
|
||||
{
|
||||
var jToken = writeInfoLists[deviceVariable];
|
||||
object rawdata;
|
||||
if (jToken is JValue jValue)
|
||||
{
|
||||
rawdata = jValue.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawdata = jToken.ToString();
|
||||
}
|
||||
object data;
|
||||
try
|
||||
{
|
||||
data = deviceVariable.WriteExpressions.GetExpressionsResult(rawdata);
|
||||
writeInfoLists[deviceVariable] = JToken.FromObject(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
results.Add(deviceVariable.Name, new OperResult(deviceVariable.Name + " 转换写入表达式失败:" + ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(deviceVariable.WriteExpressions))
|
||||
{
|
||||
var jToken = value;
|
||||
object rawdata;
|
||||
if (jToken is JValue jValue)
|
||||
{
|
||||
rawdata = jValue.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawdata = jToken.ToString();
|
||||
}
|
||||
object data;
|
||||
try
|
||||
{
|
||||
data = deviceVariable.WriteExpressions.GetExpressionsResult(rawdata);
|
||||
var result = await _driver.WriteValueAsync(deviceVariable, JToken.FromObject(data), token);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(deviceVariable.Name + " 转换写入表达式失败:" + ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = await _driver.WriteValueAsync(deviceVariable, value, token);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
var result = await _driver.WriteValuesAsync(writeInfoLists.
|
||||
Where(a => !results.Any(b => b.Key == a.Key.Name)).
|
||||
ToDictionary(item => item.Key, item => item.Value),
|
||||
token);
|
||||
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -759,6 +759,8 @@ public class CollectDeviceCore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行轮询特殊方法,并设置变量值
|
||||
/// </summary>
|
||||
|
||||
@@ -149,10 +149,18 @@ public partial class DeviceVariableRunTimePage
|
||||
private EventCallback<string> WriteValueAsync;
|
||||
private async Task OnWriteValueAsync(DeviceVariableRunTime tag, string value)
|
||||
{
|
||||
var data = await RpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", new KeyValuePair<string, string>(tag.Name, value), true);
|
||||
if (!data.IsSuccess)
|
||||
var data = await RpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}",
|
||||
|
||||
new Dictionary<string, string>()
|
||||
{
|
||||
|
||||
{ tag.Name, value}
|
||||
}
|
||||
|
||||
, true);
|
||||
if (data.Count > 0 && !data.FirstOrDefault().Value.IsSuccess)
|
||||
{
|
||||
throw new(data.Message);
|
||||
throw new(data.FirstOrDefault().Value.Message);
|
||||
}
|
||||
}
|
||||
private async Task WriteAsync(DeviceVariableRunTime collectVariableRunTime)
|
||||
|
||||
@@ -46,19 +46,6 @@ public static class StringExtensions
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将16进制的字符转换为int32。
|
||||
/// </summary>
|
||||
/// <param name="hexString"></param>
|
||||
/// <returns></returns>
|
||||
public static int ByHexStringToInt32(this string hexString)
|
||||
{
|
||||
if (string.IsNullOrEmpty(hexString))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
return int.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
|
||||
}
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="Path.Combine(string[])"/>
|
||||
/// 并把\\转为/
|
||||
|
||||
@@ -1289,13 +1289,6 @@
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Extension.String.StringExtensions.ByHexStringToInt32(System.String)">
|
||||
<summary>
|
||||
将16进制的字符转换为int32。
|
||||
</summary>
|
||||
<param name="hexString"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Extension.String.StringExtensions.CombinePathOS(System.String,System.String[])">
|
||||
<summary>
|
||||
<inheritdoc cref="M:System.IO.Path.Combine(System.String[])"/>
|
||||
|
||||
@@ -31,11 +31,11 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
private DataFormat dataFormat;
|
||||
/// <inheritdoc/>
|
||||
[JsonIgnore]
|
||||
public Encoding Encoding { get; set; } = Encoding.UTF8;
|
||||
public virtual Encoding Encoding { get; set; } = Encoding.UTF8;
|
||||
/// <inheritdoc/>
|
||||
public BcdFormat? BcdFormat { get; set; }
|
||||
public virtual BcdFormat? BcdFormat { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public int StringLength { get; set; }
|
||||
public virtual int StringLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
@@ -55,7 +55,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataFormat DataFormat
|
||||
public virtual DataFormat DataFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -69,9 +69,9 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public EndianType EndianType => endianType;
|
||||
public virtual EndianType EndianType => endianType;
|
||||
/// <inheritdoc/>
|
||||
public bool IsStringReverseByteWord { get; set; }
|
||||
public virtual bool IsStringReverseByteWord { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual IThingsGatewayBitConverter CreateByDateFormat(DataFormat dataFormat)
|
||||
@@ -86,7 +86,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return byteConverter;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(bool value)
|
||||
public virtual byte[] GetBytes(bool value)
|
||||
{
|
||||
return GetBytes(new bool[1]
|
||||
{
|
||||
@@ -95,13 +95,13 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(bool[] values)
|
||||
public virtual byte[] GetBytes(bool[] values)
|
||||
{
|
||||
return values?.BoolArrayToByte();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(short value)
|
||||
public virtual byte[] GetBytes(short value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (!IsSameOfSet())
|
||||
@@ -111,7 +111,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return bytes;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(short[] value)
|
||||
public virtual byte[] GetBytes(short[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -123,7 +123,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ushort value)
|
||||
public virtual byte[] GetBytes(ushort value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (!IsSameOfSet())
|
||||
@@ -133,7 +133,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return bytes;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ushort[] value)
|
||||
public virtual byte[] GetBytes(ushort[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -144,12 +144,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(int value)
|
||||
public virtual byte[] GetBytes(int value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(int[] value)
|
||||
public virtual byte[] GetBytes(int[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -160,12 +160,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(uint value)
|
||||
public virtual byte[] GetBytes(uint value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(uint[] value)
|
||||
public virtual byte[] GetBytes(uint[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -176,12 +176,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(long value)
|
||||
public virtual byte[] GetBytes(long value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(long[] value)
|
||||
public virtual byte[] GetBytes(long[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -192,12 +192,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ulong value)
|
||||
public virtual byte[] GetBytes(ulong value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ulong[] value)
|
||||
public virtual byte[] GetBytes(ulong[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -208,12 +208,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(float value)
|
||||
public virtual byte[] GetBytes(float value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(float[] value)
|
||||
public virtual byte[] GetBytes(float[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -224,12 +224,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(double value)
|
||||
public virtual byte[] GetBytes(double value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(double[] value)
|
||||
public virtual byte[] GetBytes(double[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
@@ -240,7 +240,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(string value)
|
||||
public virtual byte[] GetBytes(string value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
@@ -280,7 +280,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsSameOfSet()
|
||||
public virtual bool IsSameOfSet()
|
||||
{
|
||||
return !(BitConverter.IsLittleEndian ^ (endianType == EndianType.Little));
|
||||
}
|
||||
@@ -288,7 +288,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ToBoolean(byte[] buffer, int offset)
|
||||
public virtual bool ToBoolean(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = new byte[buffer.Length];
|
||||
Array.Copy(buffer, 0, bytes, 0, buffer.Length);
|
||||
@@ -296,7 +296,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte ToByte(byte[] buffer, int offset)
|
||||
public virtual byte ToByte(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = new byte[1];
|
||||
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
|
||||
@@ -304,7 +304,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] ToByte(byte[] buffer, int offset, int length)
|
||||
public virtual byte[] ToByte(byte[] buffer, int offset, int length)
|
||||
{
|
||||
byte[] bytes = new byte[length];
|
||||
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
|
||||
@@ -317,7 +317,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public double ToDouble(byte[] buffer, int offset)
|
||||
public virtual double ToDouble(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat8(buffer, offset);
|
||||
|
||||
@@ -325,7 +325,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short ToInt16(byte[] buffer, int offset)
|
||||
public virtual short ToInt16(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = new byte[2];
|
||||
Array.Copy(buffer, offset, bytes, 0, bytes.Length);
|
||||
@@ -337,7 +337,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int ToInt32(byte[] buffer, int offset)
|
||||
public virtual int ToInt32(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat4(buffer, offset);
|
||||
|
||||
@@ -345,14 +345,14 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long ToInt64(byte[] buffer, int offset)
|
||||
public virtual long ToInt64(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat8(buffer, offset);
|
||||
return BitConverter.ToInt64(bytes, 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public float ToSingle(byte[] buffer, int offset)
|
||||
public virtual float ToSingle(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat4(buffer, offset);
|
||||
|
||||
@@ -360,13 +360,13 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ToString(byte[] buffer)
|
||||
public virtual string ToString(byte[] buffer)
|
||||
{
|
||||
return ToString(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ToString(byte[] buffer, int offset, int length)
|
||||
public virtual string ToString(byte[] buffer, int offset, int length)
|
||||
{
|
||||
byte[] numArray = buffer.SelectMiddle(offset, length);
|
||||
if (BcdFormat != null)
|
||||
@@ -385,7 +385,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ushort ToUInt16(byte[] buffer, int offset)
|
||||
public virtual ushort ToUInt16(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = new byte[2];
|
||||
Array.Copy(buffer, offset, bytes, 0, 2);
|
||||
@@ -397,7 +397,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint ToUInt32(byte[] buffer, int offset)
|
||||
public virtual uint ToUInt32(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat4(buffer, offset);
|
||||
|
||||
@@ -405,7 +405,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong ToUInt64(byte[] buffer, int offset)
|
||||
public virtual ulong ToUInt64(byte[] buffer, int offset)
|
||||
{
|
||||
byte[] bytes = ByteTransDataFormat8(buffer, offset);
|
||||
return BitConverter.ToUInt64(bytes, 0);
|
||||
@@ -508,7 +508,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool[] ToBoolean(byte[] buffer, int offset, int len)
|
||||
public virtual bool[] ToBoolean(byte[] buffer, int offset, int len)
|
||||
{
|
||||
bool[] flagArray = new bool[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -519,7 +519,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public double[] ToDouble(byte[] buffer, int offset, int len)
|
||||
public virtual double[] ToDouble(byte[] buffer, int offset, int len)
|
||||
{
|
||||
double[] numArray = new double[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -530,7 +530,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short[] ToInt16(byte[] buffer, int offset, int len)
|
||||
public virtual short[] ToInt16(byte[] buffer, int offset, int len)
|
||||
{
|
||||
short[] numArray = new short[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -541,7 +541,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int[] ToInt32(byte[] buffer, int offset, int len)
|
||||
public virtual int[] ToInt32(byte[] buffer, int offset, int len)
|
||||
{
|
||||
int[] numArray = new int[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -552,7 +552,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long[] ToInt64(byte[] buffer, int offset, int len)
|
||||
public virtual long[] ToInt64(byte[] buffer, int offset, int len)
|
||||
{
|
||||
long[] numArray = new long[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -562,7 +562,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public float[] ToSingle(byte[] buffer, int offset, int len)
|
||||
public virtual float[] ToSingle(byte[] buffer, int offset, int len)
|
||||
{
|
||||
float[] numArray = new float[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -573,7 +573,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ushort[] ToUInt16(byte[] buffer, int offset, int len)
|
||||
public virtual ushort[] ToUInt16(byte[] buffer, int offset, int len)
|
||||
{
|
||||
ushort[] numArray = new ushort[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -584,7 +584,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint[] ToUInt32(byte[] buffer, int offset, int len)
|
||||
public virtual uint[] ToUInt32(byte[] buffer, int offset, int len)
|
||||
{
|
||||
uint[] numArray = new uint[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
@@ -595,7 +595,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong[] ToUInt64(byte[] buffer, int offset, int len)
|
||||
public virtual ulong[] ToUInt64(byte[] buffer, int offset, int len)
|
||||
{
|
||||
ulong[] numArray = new ulong[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ThingsGateway.Foundation.Adapter.Modbus" Version="2.0.9" />
|
||||
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ModbusDemo</name>
|
||||
<name>DLT645Test</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
@@ -0,0 +1,112 @@
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Adapter.DLT645;
|
||||
using ThingsGateway.Foundation.Extension.Byte;
|
||||
using ThingsGateway.Foundation.Serial;
|
||||
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Sockets;
|
||||
|
||||
namespace DLT645Test
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
|
||||
await DLT645_2007ClientAsync();
|
||||
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
|
||||
private static async Task DLT645_2007ClientAsync()
|
||||
{
|
||||
//链路基础配置项
|
||||
var config = new TouchSocketConfig();
|
||||
config.SetRemoteIPHost(new IPHost("127.0.0.1:502"))//TCP/UDP链路才需要
|
||||
.SetSerialProperty(new SerialProperty() //串口链路才需要
|
||||
{
|
||||
PortName = "COM1"
|
||||
}).SetBufferLength(1024);
|
||||
|
||||
var serialClient = new SerialClient();//链路对象
|
||||
serialClient.Setup(config);
|
||||
|
||||
//创建协议对象,构造函数需要传入对应链路对象
|
||||
|
||||
DLT645_2007 dlt6452007 = new(serialClient)//传入链路
|
||||
{
|
||||
//协议配置
|
||||
DataFormat = DataFormat.ABCD,
|
||||
FrameTime = 0,
|
||||
CacheTimeout = 1000,
|
||||
ConnectTimeOut = 3000,
|
||||
TimeOut = 3000,
|
||||
EnableFEHead = true,
|
||||
};
|
||||
|
||||
#region 读写测试
|
||||
//测试读取写入
|
||||
Console.WriteLine("dlt6452007:" + dlt6452007.SerialClient.SerialProperty.ToJson());
|
||||
await TestAsync(dlt6452007);
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
private static async Task TestAsync(DLT645_2007 plc)
|
||||
{
|
||||
//下面的方法对应PLC读写协议对象都是通用的
|
||||
//注意下面的方法都带有CancellationToken传播,一般是在最后一个参数,默认为None
|
||||
|
||||
|
||||
//var bytes02010100Result = await plc.ReadAsync("03010100", 20);
|
||||
////返回带有是否成功等参数,实际数据在data.Content中
|
||||
//Console.WriteLine("bytes02010100Result:" + (bytes02010100Result.IsSuccess ? bytes02010100Result.Content.ToHexString() : bytes02010100Result.Message));
|
||||
//Console.WriteLine("bytes02010100Result:" + (bytes02010100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToDouble(bytes02010100Result.Content, 0) : bytes02010100Result.Message));
|
||||
|
||||
//var bytes02020100Result = await plc.ReadAsync("02020100", 20);
|
||||
////返回带有是否成功等参数,实际数据在data.Content中
|
||||
//Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
|
||||
//Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToDouble(bytes02020100Result.Content, 0) : bytes02020100Result.Message));
|
||||
|
||||
//var bytes02020100Result = await plc.ReadAsync("04000103", 1);
|
||||
////返回带有是否成功等参数,实际数据在data.Content中
|
||||
//Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
|
||||
//Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result.Content) : bytes02020100Result.Message));
|
||||
|
||||
|
||||
var test1 = await plc.ReadDeviceStationAsync();
|
||||
Console.WriteLine("bytes02020100Result:" + (test1.IsSuccess ? test1.Content : test1.Message));
|
||||
|
||||
var test2 = await plc.WriteDeviceStationAsync("311111111114");
|
||||
Console.WriteLine("bytes02020100Result:" + (test2.IsSuccess ? test2.Message : test2.Message));
|
||||
plc.BroadcastTime(DateTime.Now);
|
||||
plc.Station = "311111111114";
|
||||
|
||||
var test3 = await plc.WriteBaudRateAsync(19200);
|
||||
Console.WriteLine("bytes02020100Result:" + (test3.IsSuccess ? test3.Message : test3.Message));
|
||||
var test4 = await plc.FreezeAsync(DateTime.Now);
|
||||
Console.WriteLine("bytes02020100Result:" + (test4.IsSuccess ? test4.Message : test4.Message));
|
||||
|
||||
var test5 = await plc.WritePasswordAsync(1, "66666666", "11111111");
|
||||
Console.WriteLine("bytes02020100Result:" + (test5.IsSuccess ? test5.Message : test5.Message));
|
||||
plc.Password = "11111111";
|
||||
|
||||
|
||||
|
||||
var bytes02020100Result1 = await plc.ReadAsync("04000403", 1);
|
||||
//返回带有是否成功等参数,实际数据在data.Content中
|
||||
Console.WriteLine("bytes02020100Result:" + (bytes02020100Result1.IsSuccess ? bytes02020100Result1.Content.ToHexString() : bytes02020100Result1.Message));
|
||||
Console.WriteLine("bytes02020100Result:" + (bytes02020100Result1.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result1.Content) : bytes02020100Result1.Message));
|
||||
|
||||
var test = await plc.WriteAsync("04000403", "33");
|
||||
//返回带有是否成功等参数,实际数据在data.Content中
|
||||
Console.WriteLine("test:" + test.Message);
|
||||
var bytes02020100Result = await plc.ReadAsync("04000403", 1);
|
||||
//返回带有是否成功等参数,实际数据在data.Content中
|
||||
Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message));
|
||||
Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result.Content) : bytes02020100Result.Message));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>OPCUAClientDemo</name>
|
||||
<name>ModbusTest</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
@@ -7,8 +7,9 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCUA" Version="2.0.9" />
|
||||
<ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>OPCUAClientTest</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
||||
@@ -19,7 +19,10 @@ namespace ModbusDemo
|
||||
await oPCUAClient.ConnectAsync();
|
||||
|
||||
var testData1 = await oPCUAClient.ReadJTokenValueAsync(new[] { "ns=2;i=2897" });
|
||||
await oPCUAClient.WriteNodeAsync("ns=2;i=2897", testData1.FirstOrDefault().Item3);
|
||||
await oPCUAClient.WriteNodeAsync(new()
|
||||
{
|
||||
{"ns=2;i=2897", testData1.FirstOrDefault().Item3 }
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Version>2.0.9.2</Version>
|
||||
<Version>2.1.0.0</Version>
|
||||
<Authors>Diego</Authors>
|
||||
<Product>ThingsGateway</Product>
|
||||
<Copyright>© 2023-present Diego</Copyright>
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,8 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Byte;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
using ThingsGateway.Foundation.Serial;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
@@ -27,45 +29,58 @@ public class DLT645_2007 : ReadWriteDevicesSerialBase
|
||||
/// <param name="serialClient"></param>
|
||||
public DLT645_2007(SerialClient serialClient) : base(serialClient)
|
||||
{
|
||||
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
|
||||
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 组包缓存时间/ms
|
||||
/// </summary>
|
||||
[Description("组包缓存时间ms")]
|
||||
public int CacheTimeout { get; set; } = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// Crc校验
|
||||
/// 增加FE FE FE FE的报文头部
|
||||
/// </summary>
|
||||
[Description("Crc校验")]
|
||||
public bool Crc16CheckEnable { get; set; } = true;
|
||||
[Description("前导符报文头")]
|
||||
public bool EnableFEHead { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 帧前时间ms
|
||||
/// </summary>
|
||||
[Description("帧前时间ms")]
|
||||
public int FrameTime { get; set; }
|
||||
/// <summary>
|
||||
/// 站号
|
||||
/// 写入需操作员代码
|
||||
/// </summary>
|
||||
[Description("站号")]
|
||||
public byte Station { get; set; } = 1;
|
||||
[Description("操作员代码")]
|
||||
public string OperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入密码
|
||||
/// </summary>
|
||||
[Description("写入密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯地址BCD码,一般应该是12个字符
|
||||
/// </summary>
|
||||
[Description("通讯地址")]
|
||||
public string Station { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription();
|
||||
}
|
||||
public override string GetAddressDescription() => base.GetAddressDescription() + Environment.NewLine;
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, length, (byte)ControlCode.Read, Station);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
ResponsedData result = await SendThenReturnAsync(commandResult, token);
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
@@ -77,70 +92,368 @@ public class DLT645_2007 : ReadWriteDevicesSerialBase
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter()
|
||||
{
|
||||
ModbusRtuDataHandleAdapter dataHandleAdapter = new()
|
||||
var dataHandleAdapter = new DLT645_2007DataHandleAdapter
|
||||
{
|
||||
Crc16CheckEnable = Crc16CheckEnable,
|
||||
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
|
||||
EnableFEHead = EnableFEHead
|
||||
};
|
||||
SerialClient.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken token = default)
|
||||
public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken token = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station);
|
||||
Password ??= string.Empty;
|
||||
OperCode ??= string.Empty;
|
||||
if (Password.Length < 8)
|
||||
Password = Password.PadLeft(8, '0');
|
||||
if (OperCode.Length < 8)
|
||||
OperCode = OperCode.PadLeft(8, '0');
|
||||
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, 1, (byte)ControlCode.Write, Station, data, strArray);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
ResponsedData result = await SendThenReturnAsync(commandResult, token);
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<bool[]>(commandResult);
|
||||
return OperResult.CreateFailedResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<bool[]>(ex);
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken token = default)
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, double value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, float value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, long value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, ulong value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, ushort value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, short value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
||||
/// <summary>
|
||||
/// 广播校时
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public OperResult BroadcastTime(DateTime dateTime, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connect(token);
|
||||
string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}";
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
SerialClient.Send(commandResult.Content);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 冻结
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station);
|
||||
string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}";
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().Reverse().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
ResponsedData result = await SendThenReturnAsync(commandResult, token);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<bool[]>(commandResult);
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<bool[]>(ex);
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task<ResponsedData> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken token)
|
||||
/// <summary>
|
||||
/// 读取通信地址
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken token = default)
|
||||
{
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, token);
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, token);
|
||||
return result;
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33);
|
||||
return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 修改波特率
|
||||
/// </summary>
|
||||
/// <param name="baudRate"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
byte baudRateByte;
|
||||
switch (baudRate)
|
||||
{
|
||||
case 600: baudRateByte = 0x02; break;
|
||||
case 1200: baudRateByte = 0x04; break;
|
||||
case 2400: baudRateByte = 0x08; break;
|
||||
case 4800: baudRateByte = 0x10; break;
|
||||
case 9600: baudRateByte = 0x20; break;
|
||||
case 19200: baudRateByte = 0x40; break;
|
||||
default: return new OperResult<string>($"不支持此波特率:{baudRate}");
|
||||
}
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新通信地址
|
||||
/// </summary>
|
||||
/// <param name="station"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="oldPassword"></param>
|
||||
/// <param name="newPassword"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
string str = $"04000C{level:D2}";
|
||||
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
|
||||
str.ByHexStringToBytes().Reverse().ToArray()
|
||||
.SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
.SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 控制码
|
||||
/// </summary>
|
||||
public enum ControlCode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 读数据
|
||||
/// </summary>
|
||||
Read = 0x11,
|
||||
/// <summary>
|
||||
/// 读后续数据
|
||||
/// </summary>
|
||||
ReadSub = 0x12,
|
||||
/// <summary>
|
||||
/// 读站号
|
||||
/// </summary>
|
||||
ReadStation = 0x13,
|
||||
/// <summary>
|
||||
/// 写数据
|
||||
/// </summary>
|
||||
Write = 0x14,
|
||||
/// <summary>
|
||||
/// 写站号
|
||||
/// </summary>
|
||||
WriteStation = 0x15,
|
||||
/// <summary>
|
||||
/// 广播校时
|
||||
/// </summary>
|
||||
BroadcastTime = 0x08,
|
||||
/// <summary>
|
||||
/// 冻结
|
||||
/// </summary>
|
||||
Freeze = 0x16,
|
||||
/// <summary>
|
||||
/// 更新波特率
|
||||
/// </summary>
|
||||
WriteBaudRate = 0x17,
|
||||
/// <summary>
|
||||
/// 更新密码
|
||||
/// </summary>
|
||||
WritePassword = 0x18,
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Byte;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
|
||||
/// <summary>
|
||||
/// DLT645_2007Address
|
||||
/// </summary>
|
||||
public class DLT645_2007Address : DeviceAddressBase
|
||||
{
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public DLT645_2007Address()
|
||||
{
|
||||
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public DLT645_2007Address(string address, ushort len)
|
||||
{
|
||||
Parse(address, len);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DLT645_2007Address(string address, byte[] station)
|
||||
{
|
||||
Station = station;
|
||||
Parse(address, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据标识
|
||||
/// </summary>
|
||||
public byte[] DataId { get; set; } = new byte[0];
|
||||
/// <summary>
|
||||
/// 反转解析
|
||||
/// </summary>
|
||||
public bool Reverse { get; set; } = true;
|
||||
/// <summary>
|
||||
/// 站号信息
|
||||
/// </summary>
|
||||
public byte[] Station { get; set; } = new byte[0];
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Parse(string address, int length)
|
||||
{
|
||||
var result = ParseFrom(address, length);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
Length = result.Content.Length;
|
||||
AddressStart = result.Content.AddressStart;
|
||||
DataId = result.Content.DataId;
|
||||
Station = result.Content.Station;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(result.Message);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 解析地址
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static OperResult<DLT645_2007Address> ParseFrom(string address, int length)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
DLT645_2007Address dLT645_2007Address = new();
|
||||
byte[] array;
|
||||
array = new byte[0];
|
||||
dLT645_2007Address.Length = length;
|
||||
if (address.IndexOf(';') < 0)
|
||||
{
|
||||
array = address.ByHexStringToBytes().Reverse().ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
for (int index = 0; index < strArray.Length; ++index)
|
||||
{
|
||||
if (strArray[index].ToUpper().StartsWith("S="))
|
||||
{
|
||||
var station = strArray[index].Substring(2);
|
||||
if (station.IsNullOrEmpty()) return new OperResult<DLT645_2007Address>("通讯地址不能为空");
|
||||
if (station.Length < 12)
|
||||
station = station.PadLeft(12, '0');
|
||||
dLT645_2007Address.Station = station.ByHexStringToBytes().Reverse().ToArray();
|
||||
}
|
||||
else if (!strArray[index].Contains("r="))
|
||||
{
|
||||
dLT645_2007Address.Reverse = strArray[index].Substring(2).GetBoolValue();
|
||||
}
|
||||
else if (!strArray[index].Contains("="))
|
||||
{
|
||||
array = strArray[index].ByHexStringToBytes().Reverse().ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
dLT645_2007Address.DataId = array;
|
||||
return OperResult.CreateSuccessResult(dLT645_2007Address);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<DLT645_2007Address>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringGeter = new();
|
||||
if (Station.Length > 0)
|
||||
{
|
||||
stringGeter.Append("s=" + Station.Reverse().ToArray().ToHexString() + ";");
|
||||
}
|
||||
if (DataId.Length > 0)
|
||||
{
|
||||
stringGeter.Append(DataId.Reverse().ToArray().ToHexString() + ";");
|
||||
}
|
||||
if (!Reverse)
|
||||
{
|
||||
stringGeter.Append("s=" + Reverse.ToString() + ";");
|
||||
}
|
||||
return stringGeter.ToString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Byte;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public class DLT645_2007BitConverter : ThingsGatewayBitConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public DLT645_2007BitConverter(EndianType endianType) : base(endianType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DLT645协议转换double
|
||||
/// </summary>
|
||||
/// <param name="buffer">带数据项标识</param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public override double ToDouble(byte[] buffer, int offset)
|
||||
{
|
||||
return Convert.ToDouble(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString(byte[] buffer)
|
||||
{
|
||||
return this.ToString(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString(byte[] buffer, int offset, int length)
|
||||
{
|
||||
buffer = buffer.SelectMiddle(offset, length);
|
||||
buffer = buffer.BytesAdd(-0x33);
|
||||
var dataInfos = DLT645Helper.GetDataInfos(buffer);
|
||||
StringBuilder stringBuilder = new();
|
||||
foreach (var dataInfo in dataInfos)
|
||||
{
|
||||
//实际数据
|
||||
var content = buffer.SelectMiddle(4, dataInfo.ByteLength).Reverse().ToArray();
|
||||
if (dataInfo.IsSigned)//可能为负数
|
||||
{
|
||||
if (content[0] > 0x80)//最高位是表示正负
|
||||
{
|
||||
content[0] = (byte)(content[0] - 0x80);
|
||||
if (dataInfo.Digtal == 0)//无小数点
|
||||
{
|
||||
stringBuilder.AppendLine($"-{content.ToHexString()}");
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.AppendLine((-(Convert.ToDouble(content.ToHexString()) / Math.Pow(10.0, dataInfo.Digtal))).ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ToString(stringBuilder, dataInfo, content);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ToString(stringBuilder, dataInfo, content);
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
|
||||
static void ToString(StringBuilder stringBuilder, DataInfo dataInfo, byte[] content)
|
||||
{
|
||||
if (dataInfo.Digtal < 0)
|
||||
{
|
||||
stringBuilder.AppendLine($"{Encoding.ASCII.GetString(content)}");
|
||||
}
|
||||
else if (dataInfo.Digtal == 0)//无小数点
|
||||
{
|
||||
stringBuilder.AppendLine($"{content.ToHexString()}");
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.AppendLine(((Convert.ToDouble(content.ToHexString()) / Math.Pow(10.0, dataInfo.Digtal))).ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Adapter.Modbus;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
|
||||
/// <summary>
|
||||
/// DLT645_2007DataHandleAdapter
|
||||
/// </summary>
|
||||
public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<DLT645_2007Message>
|
||||
{
|
||||
/// <summary>
|
||||
/// 增加FE FE FE FE的报文头部
|
||||
/// </summary>
|
||||
[Description("前导符报文头")]
|
||||
public bool EnableFEHead { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override byte[] PackCommand(byte[] command)
|
||||
{
|
||||
//打包时加上4个FE字节
|
||||
if (EnableFEHead)
|
||||
{
|
||||
return DataTransUtil.SpliceArray(new byte[4] { 0xFE, 0xFE, 0xFE, 0xFE }, command);
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override DLT645_2007Message GetInstance()
|
||||
{
|
||||
return new DLT645_2007Message();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override FilterResult UnpackResponse(DLT645_2007Message request, byte[] send, byte[] body, byte[] response)
|
||||
{
|
||||
//因为设备可能带有FE前导符开头,这里找到0x68的位置
|
||||
int headCodeIndex = -1;
|
||||
if (response != null)
|
||||
{
|
||||
for (int index = 0; index < response.Length; index++)
|
||||
{
|
||||
if (response[index] == 0x68)
|
||||
{
|
||||
headCodeIndex = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//帧起始符 地址域 帧起始符 控制码 数据域长度共10个字节
|
||||
if (headCodeIndex < 0 || headCodeIndex + 10 > response.Length)
|
||||
return FilterResult.Cache;
|
||||
|
||||
|
||||
var len = 10 + response[headCodeIndex + 9] + 2;
|
||||
|
||||
if (response.Length - headCodeIndex < len)
|
||||
{
|
||||
return FilterResult.Cache;
|
||||
}
|
||||
if (response.Length - headCodeIndex >= len && response[len + headCodeIndex - 1] == 0x16)
|
||||
{
|
||||
|
||||
//检查校验码
|
||||
int sumCheck = 0;
|
||||
for (int i = headCodeIndex; i < len + headCodeIndex - 2; i++)
|
||||
sumCheck += response[i];
|
||||
if ((byte)sumCheck != response[len + headCodeIndex - 2])
|
||||
{
|
||||
//校验错误
|
||||
request.Message = "和校验错误";
|
||||
request.ResultCode = ResultCode.Fail;
|
||||
return FilterResult.Success;
|
||||
}
|
||||
if ((response[headCodeIndex + 8] & 0x40) == 0x40)//控制码bit6为1时,返回错误
|
||||
{
|
||||
byte byte1 = (byte)(response[headCodeIndex + 10] - 0x33);
|
||||
var error = DLT645Helper.Get2007ErrorMessage(byte1);
|
||||
request.Message = "异常控制码:" + $"0x{response[headCodeIndex + 8]:X2},错误信息:{error}";
|
||||
request.ResultCode = ResultCode.Fail;
|
||||
return FilterResult.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Content = response.RemoveBegin(headCodeIndex + 10).RemoveLast(response.Length + 2 - len - headCodeIndex);
|
||||
request.ResultCode = ResultCode.Success;
|
||||
return FilterResult.Success;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
request.ResultCode = ResultCode.Error;
|
||||
return FilterResult.Success;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusRtuMessage : MessageBase, IMessage
|
||||
public class DLT645_2007Message : MessageBase, IMessage
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override int HeadBytesLength => -1;
|
||||
@@ -0,0 +1,416 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Byte;
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.DLT645;
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// DLT645_2007
|
||||
/// </summary>
|
||||
/// <param name="tcpClient"></param>
|
||||
public DLT645_2007OverTcp(TcpClientEx tcpClient) : base(tcpClient)
|
||||
{
|
||||
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
|
||||
RegisterByteLength = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 组包缓存时间/ms
|
||||
/// </summary>
|
||||
[Description("组包缓存时间ms")]
|
||||
public int CacheTimeout { get; set; } = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// 增加FE FE FE FE的报文头部
|
||||
/// </summary>
|
||||
[Description("前导符报文头")]
|
||||
public bool EnableFEHead { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 帧前时间ms
|
||||
/// </summary>
|
||||
[Description("帧前时间ms")]
|
||||
public int FrameTime { get; set; }
|
||||
/// <summary>
|
||||
/// 写入需操作员代码
|
||||
/// </summary>
|
||||
[Description("操作员代码")]
|
||||
public string OperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 写入密码
|
||||
/// </summary>
|
||||
[Description("写入密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯地址BCD码,一般应该是12个字符
|
||||
/// </summary>
|
||||
[Description("通讯地址")]
|
||||
public string Station { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription() => base.GetAddressDescription() + Environment.NewLine;
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, length, (byte)ControlCode.Read, Station);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void SetDataAdapter()
|
||||
{
|
||||
var dataHandleAdapter = new DLT645_2007DataHandleAdapter
|
||||
{
|
||||
EnableFEHead = EnableFEHead
|
||||
};
|
||||
TcpClientEx.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken token = default)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
Password ??= string.Empty;
|
||||
OperCode ??= string.Empty;
|
||||
if (Password.Length < 8)
|
||||
Password = Password.PadLeft(8, '0');
|
||||
if (OperCode.Length < 8)
|
||||
OperCode = OperCode.PadLeft(8, '0');
|
||||
var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes());
|
||||
string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command(address, 1, (byte)ControlCode.Write, Station, data, strArray);
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<byte[]>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, byte value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, double value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, float value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, long value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, ulong value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, ushort value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, short value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, int value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token);
|
||||
|
||||
|
||||
#region 其他方法
|
||||
|
||||
/// <summary>
|
||||
/// 广播校时
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public OperResult BroadcastTime(DateTime dateTime, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connect(token);
|
||||
string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}";
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
TcpClientEx.Send(commandResult.Content);
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 冻结
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}";
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().Reverse().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取通信地址
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33);
|
||||
return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 修改波特率
|
||||
/// </summary>
|
||||
/// <param name="baudRate"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
byte baudRateByte;
|
||||
switch (baudRate)
|
||||
{
|
||||
case 600: baudRateByte = 0x02; break;
|
||||
case 1200: baudRateByte = 0x04; break;
|
||||
case 2400: baudRateByte = 0x08; break;
|
||||
case 4800: baudRateByte = 0x10; break;
|
||||
case 9600: baudRateByte = 0x20; break;
|
||||
case 19200: baudRateByte = 0x40; break;
|
||||
default: return new OperResult<string>($"不支持此波特率:{baudRate}");
|
||||
}
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新通信地址
|
||||
/// </summary>
|
||||
/// <param name="station"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="oldPassword"></param>
|
||||
/// <param name="newPassword"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConnectAsync(token);
|
||||
|
||||
if (Station.IsNullOrEmpty()) Station = string.Empty;
|
||||
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
|
||||
string str = $"04000C{level:D2}";
|
||||
|
||||
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
|
||||
str.ByHexStringToBytes().Reverse().ToArray()
|
||||
.SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
.SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray())
|
||||
, Station.ByHexStringToBytes().Reverse().ToArray());
|
||||
if (commandResult.IsSuccess)
|
||||
{
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token);
|
||||
var result1 = ((MessageBase)result.RequestInfo);
|
||||
if (result1.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(result1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateFailedResult<string>(commandResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<string>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Foundation.Adapter.Modbus;
|
||||
|
||||
/// <summary>
|
||||
/// Rtu适配器
|
||||
/// </summary>
|
||||
public class ModbusRtuDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusRtuMessage>
|
||||
{
|
||||
/// <summary>
|
||||
/// 检测CRC
|
||||
/// </summary>
|
||||
public bool Crc16CheckEnable { get; set; } = true;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <returns></returns>
|
||||
public override byte[] PackCommand(byte[] command)
|
||||
{
|
||||
return ModbusHelper.AddCrc(command);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override ModbusRtuMessage GetInstance()
|
||||
{
|
||||
return new ModbusRtuMessage();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override FilterResult UnpackResponse(ModbusRtuMessage request, byte[] send, byte[] body, byte[] response)
|
||||
{
|
||||
//理想状态检测
|
||||
var result = ModbusHelper.GetModbusRtuData(send, response, Crc16CheckEnable);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
request.ResultCode = result.ResultCode;
|
||||
request.Message = result.Message;
|
||||
request.Content = result.Content1;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.ResultCode = result.ResultCode;
|
||||
request.Message = result.Message;
|
||||
}
|
||||
return result.Content2;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,462 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ThingsGateway.Foundation.Adapter.DLT645</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DataInfo">
|
||||
<summary>
|
||||
解析参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.ByteLength">
|
||||
<summary>
|
||||
解析长度
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.Digtal">
|
||||
<summary>
|
||||
小数位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.IsSigned">
|
||||
<summary>
|
||||
有符号解析
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645Helper.GetDataInfos(System.Byte[])">
|
||||
<summary>
|
||||
获取返回的解析信息
|
||||
</summary>
|
||||
<param name="buffer"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645Helper.GetDLT645_2007Command(System.String,System.Int32,System.Byte,System.String,System.Byte[],System.String[])">
|
||||
<summary>
|
||||
获取DLT645报文
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.#ctor(ThingsGateway.Foundation.Serial.SerialClient)">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
<param name="serialClient"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.CacheTimeout">
|
||||
<summary>
|
||||
组包缓存时间/ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.EnableFEHead">
|
||||
<summary>
|
||||
增加FE FE FE FE的报文头部
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.FrameTime">
|
||||
<summary>
|
||||
帧前时间ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.OperCode">
|
||||
<summary>
|
||||
写入需操作员代码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.Password">
|
||||
<summary>
|
||||
写入密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.Station">
|
||||
<summary>
|
||||
通讯地址BCD码,一般应该是12个字符
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.GetAddressDescription">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.SetDataAdapter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.String,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Byte,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Double,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Single,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int64,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt64,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt16,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int16,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.BroadcastTime(System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
广播校时
|
||||
</summary>
|
||||
<param name="dateTime"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.FreezeAsync(System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
冻结
|
||||
</summary>
|
||||
<param name="dateTime"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.ReadDeviceStationAsync(System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取通信地址
|
||||
</summary>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteBaudRateAsync(System.Int32,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
修改波特率
|
||||
</summary>
|
||||
<param name="baudRate"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteDeviceStationAsync(System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
更新通信地址
|
||||
</summary>
|
||||
<param name="station"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WritePasswordAsync(System.Byte,System.String,System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
修改密码
|
||||
</summary>
|
||||
<param name="level"></param>
|
||||
<param name="oldPassword"></param>
|
||||
<param name="newPassword"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.ControlCode">
|
||||
<summary>
|
||||
控制码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Read">
|
||||
<summary>
|
||||
读数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.ReadSub">
|
||||
<summary>
|
||||
读后续数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.ReadStation">
|
||||
<summary>
|
||||
读站号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Write">
|
||||
<summary>
|
||||
写数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WriteStation">
|
||||
<summary>
|
||||
写站号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.BroadcastTime">
|
||||
<summary>
|
||||
广播校时
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Freeze">
|
||||
<summary>
|
||||
冻结
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WriteBaudRate">
|
||||
<summary>
|
||||
更新波特率
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WritePassword">
|
||||
<summary>
|
||||
更新密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address">
|
||||
<summary>
|
||||
DLT645_2007Address
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor(System.String,System.UInt16)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor(System.String,System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.DataId">
|
||||
<summary>
|
||||
数据标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Reverse">
|
||||
<summary>
|
||||
反转解析
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Station">
|
||||
<summary>
|
||||
站号信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Parse(System.String,System.Int32)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.ParseFrom(System.String,System.Int32)">
|
||||
<summary>
|
||||
解析地址
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<param name="length"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.ToString">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.#ctor(TouchSocket.Core.EndianType)">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToDouble(System.Byte[],System.Int32)">
|
||||
<summary>
|
||||
DLT645协议转换double
|
||||
</summary>
|
||||
<param name="buffer">带数据项标识</param>
|
||||
<param name="offset"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToString(System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToString(System.Byte[],System.Int32,System.Int32)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter">
|
||||
<summary>
|
||||
DLT645_2007DataHandleAdapter
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.EnableFEHead">
|
||||
<summary>
|
||||
增加FE FE FE FE的报文头部
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.PackCommand(System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.GetInstance">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message,System.Byte[],System.Byte[],System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.#ctor(ThingsGateway.Foundation.TcpClientEx)">
|
||||
<summary>
|
||||
DLT645_2007
|
||||
</summary>
|
||||
<param name="tcpClient"></param>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.CacheTimeout">
|
||||
<summary>
|
||||
组包缓存时间/ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.EnableFEHead">
|
||||
<summary>
|
||||
增加FE FE FE FE的报文头部
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.FrameTime">
|
||||
<summary>
|
||||
帧前时间ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.OperCode">
|
||||
<summary>
|
||||
写入需操作员代码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.Password">
|
||||
<summary>
|
||||
写入密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.Station">
|
||||
<summary>
|
||||
通讯地址BCD码,一般应该是12个字符
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.GetAddressDescription">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.SetDataAdapter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.String,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Byte,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Double,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Single,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int64,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt64,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt16,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int16,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.BroadcastTime(System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
广播校时
|
||||
</summary>
|
||||
<param name="dateTime"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.FreezeAsync(System.DateTime,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
冻结
|
||||
</summary>
|
||||
<param name="dateTime"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.ReadDeviceStationAsync(System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
读取通信地址
|
||||
</summary>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteBaudRateAsync(System.Int32,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
修改波特率
|
||||
</summary>
|
||||
<param name="baudRate"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteDeviceStationAsync(System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
更新通信地址
|
||||
</summary>
|
||||
<param name="station"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WritePasswordAsync(System.Byte,System.String,System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
修改密码
|
||||
</summary>
|
||||
<param name="level"></param>
|
||||
<param name="oldPassword"></param>
|
||||
<param name="newPassword"></param>
|
||||
<param name="token"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.HeadBytesLength">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.CheckHeadBytes(System.Byte[])">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.SendBytesThen">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
@@ -60,45 +60,94 @@ public class ModbusAddress : DeviceAddressBase
|
||||
/// <inheritdoc/>
|
||||
public override void Parse(string address, int length)
|
||||
{
|
||||
Length = length;
|
||||
if (address.IndexOf(';') < 0)
|
||||
var result = ParseFrom(address, length);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
Address(address);
|
||||
|
||||
Length = result.Content.Length;
|
||||
AddressStart = result.Content.AddressStart;
|
||||
ReadFunction = result.Content.ReadFunction;
|
||||
if (result.Content.Station > 0)
|
||||
Station = result.Content.Station;
|
||||
WriteFunction = result.Content.WriteFunction;
|
||||
}
|
||||
else
|
||||
}
|
||||
/// <summary>
|
||||
/// 解析地址
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static OperResult<ModbusAddress> ParseFrom(string address, int length)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int index = 0; index < strArray.Length; ++index)
|
||||
ModbusAddress modbusAddress = new()
|
||||
{
|
||||
if (strArray[index].ToUpper().StartsWith("S="))
|
||||
Length = length
|
||||
};
|
||||
if (address.IndexOf(';') < 0)
|
||||
{
|
||||
Address(address);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int index = 0; index < strArray.Length; ++index)
|
||||
{
|
||||
if (Convert.ToInt16(strArray[index].Substring(2)) > 0)
|
||||
Station = byte.Parse(strArray[index].Substring(2));
|
||||
}
|
||||
else if (strArray[index].ToUpper().StartsWith("W="))
|
||||
{
|
||||
if (Convert.ToInt16(strArray[index].Substring(2)) > 0)
|
||||
this.WriteFunction = byte.Parse(strArray[index].Substring(2));
|
||||
}
|
||||
else if (!strArray[index].Contains("="))
|
||||
{
|
||||
Address(strArray[index]);
|
||||
if (strArray[index].ToUpper().StartsWith("S="))
|
||||
{
|
||||
if (Convert.ToInt16(strArray[index].Substring(2)) > 0)
|
||||
modbusAddress.Station = byte.Parse(strArray[index].Substring(2));
|
||||
}
|
||||
else if (strArray[index].ToUpper().StartsWith("W="))
|
||||
{
|
||||
if (Convert.ToInt16(strArray[index].Substring(2)) > 0)
|
||||
modbusAddress.WriteFunction = byte.Parse(strArray[index].Substring(2));
|
||||
}
|
||||
else if (!strArray[index].Contains("="))
|
||||
{
|
||||
Address(strArray[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Address(string address)
|
||||
return OperResult.CreateSuccessResult(modbusAddress);
|
||||
|
||||
void Address(string address)
|
||||
{
|
||||
var readF = ushort.Parse(address.Substring(0, 1));
|
||||
if (readF > 4)
|
||||
throw new("功能码错误");
|
||||
switch (readF)
|
||||
{
|
||||
case 0:
|
||||
modbusAddress.ReadFunction = 1;
|
||||
break;
|
||||
case 1:
|
||||
modbusAddress.ReadFunction = 2;
|
||||
break;
|
||||
case 3:
|
||||
modbusAddress.ReadFunction = 4;
|
||||
break;
|
||||
case 4:
|
||||
modbusAddress.ReadFunction = 3;
|
||||
break;
|
||||
}
|
||||
modbusAddress.AddressStart = int.Parse(address.Substring(1)) - 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var readF = ushort.Parse(address.Substring(0, 1));
|
||||
if (readF > 4)
|
||||
throw new("功能码错误");
|
||||
GetFunction(readF);
|
||||
AddressStart = int.Parse(address.Substring(1)) - 1;
|
||||
return new OperResult<ModbusAddress>(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
@@ -115,24 +164,6 @@ public class ModbusAddress : DeviceAddressBase
|
||||
return stringGeter.ToString();
|
||||
}
|
||||
|
||||
private void GetFunction(ushort readF)
|
||||
{
|
||||
switch (readF)
|
||||
{
|
||||
case 0:
|
||||
ReadFunction = 1;
|
||||
break;
|
||||
case 1:
|
||||
ReadFunction = 2;
|
||||
break;
|
||||
case 3:
|
||||
ReadFunction = 4;
|
||||
break;
|
||||
case 4:
|
||||
ReadFunction = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
private string GetFunctionString(int readF)
|
||||
{
|
||||
return readF switch
|
||||
|
||||
@@ -124,10 +124,10 @@ internal class ModbusHelper
|
||||
{
|
||||
if (response.Length < 3)
|
||||
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
|
||||
|
||||
if (crcCheck && !EasyCRC16.CheckCRC16(response))
|
||||
return new OperResult<byte[], FilterResult>("Crc校验失败" + DataTransUtil.ByteToHexString(response, ' ')) { Content2 = FilterResult.Success };
|
||||
return GetModbusData(send, response.RemoveLast(2));
|
||||
var data = response.SelectMiddle(0, response[2] + 5);
|
||||
if (crcCheck && !EasyCRC16.CheckCRC16(data))
|
||||
return new OperResult<byte[], FilterResult>("Crc校验失败" + DataTransUtil.ByteToHexString(data, ' ')) { Content2 = FilterResult.Success };
|
||||
return GetModbusData(send, data.RemoveLast(2));
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取读取报文
|
||||
|
||||
@@ -38,6 +38,14 @@
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusAddress.Parse(System.String,System.Int32)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusAddress.ParseFrom(System.String,System.Int32)">
|
||||
<summary>
|
||||
解析地址
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<param name="length"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusAddress.ToString">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
|
||||
@@ -301,50 +301,94 @@ public class OPCDAClient : DisposableObject
|
||||
return OPCNode?.ToString();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 写入值
|
||||
/// 批量写入值
|
||||
/// </summary>
|
||||
/// <param name="valueName">写入</param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public OperResult WriteItem(string valueName, JToken value)
|
||||
public Dictionary<string, OperResult> WriteItem(Dictionary<string, JToken> writeInfos)
|
||||
{
|
||||
Dictionary<string, OperResult> results = new();
|
||||
if (PrivateConnect())
|
||||
{
|
||||
try
|
||||
{
|
||||
var group = Groups.FirstOrDefault(it => it.OpcItems.Any(a => a.ItemID == valueName));
|
||||
if (group == null)
|
||||
return new OperResult("不存在该变量" + valueName);
|
||||
var item = group.OpcItems.Where(it => it.ItemID == valueName).FirstOrDefault();
|
||||
int[] serverHandle = new int[1] { item.ServerHandle };
|
||||
int[] PErrors = new int[1];
|
||||
var jtoken = value;
|
||||
var rank = jtoken.CalculateActualValueRank();
|
||||
object rawWriteValue;
|
||||
switch (rank)
|
||||
var valueGroup = writeInfos.GroupBy(itemId =>
|
||||
{
|
||||
var group = Groups.FirstOrDefault(it => it.OpcItems.Any(a => a.ItemID == itemId.Key));
|
||||
return group;
|
||||
}).ToList();
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var item1 in valueGroup)
|
||||
{
|
||||
case -1:
|
||||
rawWriteValue = ((JValue)jtoken).Value;
|
||||
break;
|
||||
default:
|
||||
var jarray = ((JArray)jtoken);
|
||||
rawWriteValue = jarray.Select(j => (object)j).ToArray();
|
||||
break;
|
||||
if (item1.Key == null)
|
||||
{
|
||||
foreach (var item2 in item1)
|
||||
{
|
||||
results.Add(item2.Key, new OperResult("不存在该变量" + item2.Key));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<int> ServerHandles = new();
|
||||
List<object> Values = new();
|
||||
foreach (var item2 in item1)
|
||||
{
|
||||
var opcItem = item1.Key.OpcItems.Where(it => it.ItemID == item2.Key).FirstOrDefault();
|
||||
ServerHandles.Add(opcItem.ServerHandle);
|
||||
var jtoken = item2.Value;
|
||||
var rank = jtoken.CalculateActualValueRank();
|
||||
object rawWriteValue;
|
||||
switch (rank)
|
||||
{
|
||||
case -1:
|
||||
rawWriteValue = ((JValue)jtoken).Value;
|
||||
break;
|
||||
default:
|
||||
var jarray = ((JArray)jtoken);
|
||||
rawWriteValue = jarray.Select(j => (object)j).ToArray();
|
||||
break;
|
||||
}
|
||||
|
||||
Values.Add(rawWriteValue);
|
||||
|
||||
}
|
||||
|
||||
var result = item1.Key.Write(Values.ToArray(), ServerHandles.ToArray(), out var PErrors);
|
||||
var data = item1.ToList();
|
||||
for (int i = 0; i < data.Count; i++)
|
||||
{
|
||||
results.Add(data[i].Key, PErrors[i] == 0 ? OperResult.CreateSuccessResult() : new OperResult("错误代码:" + PErrors[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object[] Value = new object[1] { rawWriteValue };
|
||||
var result = group.Write(Value, serverHandle, out PErrors);
|
||||
return result;
|
||||
return results;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex.Message);
|
||||
var keys = writeInfos.Keys.ToList();
|
||||
foreach (var item in keys)
|
||||
{
|
||||
results.AddOrUpdate(item, new(ex));
|
||||
}
|
||||
return results;
|
||||
|
||||
}
|
||||
}
|
||||
return new OperResult();
|
||||
else
|
||||
{
|
||||
var keys = writeInfos.Keys.ToList();
|
||||
foreach (var item in keys)
|
||||
{
|
||||
results.AddOrUpdate(item, new("未初始化连接"));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
|
||||
@@ -520,12 +520,10 @@
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ToString">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.WriteItem(System.String,Newtonsoft.Json.Linq.JToken)">
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.WriteItem(System.Collections.Generic.Dictionary{System.String,Newtonsoft.Json.Linq.JToken})">
|
||||
<summary>
|
||||
写入值
|
||||
批量写入值
|
||||
</summary>
|
||||
<param name="valueName">写入</param>
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Dispose(System.Boolean)">
|
||||
|
||||
@@ -69,7 +69,10 @@ public class OPCUAClient : DisposableObject
|
||||
private readonly ApplicationInstance m_application = new();
|
||||
|
||||
private readonly ApplicationConfiguration m_configuration;
|
||||
|
||||
/// <summary>
|
||||
/// SessionReconnectHandler
|
||||
/// </summary>
|
||||
public SessionReconnectHandler ReConnectHandler => m_reConnectHandler;
|
||||
private SessionReconnectHandler m_reConnectHandler;
|
||||
private ISession m_session;
|
||||
/// <summary>
|
||||
@@ -521,29 +524,33 @@ public class OPCUAClient : DisposableObject
|
||||
/// <summary>
|
||||
/// 异步写opc标签
|
||||
/// </summary>
|
||||
public async Task<OperResult> WriteNodeAsync(string tag, JToken value, CancellationToken token = default)
|
||||
public async Task<Dictionary<string, OperResult>> WriteNodeAsync(Dictionary<string, JToken> writeInfoLists, CancellationToken token = default)
|
||||
{
|
||||
Dictionary<string, OperResult> results = new();
|
||||
try
|
||||
{
|
||||
WriteValue valueToWrite = new()
|
||||
WriteValueCollection valuesToWrite = new();
|
||||
foreach (var item in writeInfoLists)
|
||||
{
|
||||
NodeId = new NodeId(tag),
|
||||
AttributeId = Attributes.Value,
|
||||
};
|
||||
var variableNode = (VariableNode)ReadNode(tag.ToString(), false);
|
||||
await typeSystem.LoadType(variableNode.DataType, true, true);
|
||||
var dataValue = JsonUtils.Decode(
|
||||
m_session.MessageContext,
|
||||
variableNode.DataType,
|
||||
TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable),
|
||||
value.CalculateActualValueRank(),
|
||||
value
|
||||
);
|
||||
valueToWrite.Value = dataValue;
|
||||
WriteValueCollection valuesToWrite = new()
|
||||
{
|
||||
valueToWrite
|
||||
};
|
||||
WriteValue valueToWrite = new()
|
||||
{
|
||||
NodeId = new NodeId(item.Key),
|
||||
AttributeId = Attributes.Value,
|
||||
};
|
||||
var variableNode = (VariableNode)ReadNode(item.Key, false);
|
||||
await typeSystem.LoadType(variableNode.DataType, true, true);
|
||||
var dataValue = JsonUtils.Decode(
|
||||
m_session.MessageContext,
|
||||
variableNode.DataType,
|
||||
TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable),
|
||||
item.Value.CalculateActualValueRank(),
|
||||
item.Value
|
||||
);
|
||||
valueToWrite.Value = dataValue;
|
||||
|
||||
valuesToWrite.Add(valueToWrite);
|
||||
}
|
||||
|
||||
|
||||
var result = await m_session.WriteAsync(
|
||||
requestHeader: null,
|
||||
@@ -551,15 +558,29 @@ public class OPCUAClient : DisposableObject
|
||||
|
||||
ClientBase.ValidateResponse(result.Results, valuesToWrite);
|
||||
ClientBase.ValidateDiagnosticInfos(result.DiagnosticInfos, valuesToWrite);
|
||||
if (!StatusCode.IsGood(result.Results[0]))
|
||||
|
||||
|
||||
var keys = writeInfoLists.Keys.ToList();
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
return new OperResult(result.Results[0].ToString());
|
||||
if (!StatusCode.IsGood(result.Results[i]))
|
||||
results.Add(keys[i], new(result.Results[i].ToString()));
|
||||
else
|
||||
{
|
||||
results.Add(keys[i], OperResult.CreateSuccessResult());
|
||||
}
|
||||
}
|
||||
return OperResult.CreateSuccessResult();
|
||||
|
||||
return results;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
var keys = writeInfoLists.Keys.ToList();
|
||||
foreach (var item in keys)
|
||||
{
|
||||
results.Add(item, new(ex));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -286,6 +286,11 @@
|
||||
当前的订阅组,组名称/组
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReConnectHandler">
|
||||
<summary>
|
||||
SessionReconnectHandler
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.#ctor(TouchSocket.Core.ILog)">
|
||||
<summary>
|
||||
默认的构造函数,实例化一个新的OPC UA类
|
||||
@@ -375,7 +380,7 @@
|
||||
从服务器读取值
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.WriteNodeAsync(System.String,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.WriteNodeAsync(System.Collections.Generic.Dictionary{System.String,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
异步写opc标签
|
||||
</summary>
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Serial;
|
||||
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Sockets;
|
||||
|
||||
namespace ThingsGateway.DLT645;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public class DLT645_2007 : CollectBase
|
||||
{
|
||||
private readonly DLT645_2007Property driverPropertys = new();
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => _plc;
|
||||
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007 _plc;
|
||||
/// <inheritdoc/>
|
||||
public override Type DriverDebugUIType => typeof(DLT645_2007DebugDriverPage);
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override CollectDriverPropertyBase DriverPropertys => driverPropertys;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public override bool IsSupportRequest => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IThingsGatewayBitConverter ThingsGatewayBitConverter { get => _plc?.ThingsGatewayBitConverter; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task AfterStopAsync()
|
||||
{
|
||||
_plc?.Disconnect();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task BeforStartAsync(CancellationToken token)
|
||||
{
|
||||
await _plc?.ConnectAsync(token);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_plc?.Disconnect();
|
||||
_plc?.SafeDispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void InitDataAdapter()
|
||||
{
|
||||
_plc.SetDataAdapter();
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override bool IsConnected()
|
||||
{
|
||||
return _plc?.SerialClient?.CanSend == true;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override List<DeviceVariableSourceRead> LoadSourceRead(List<DeviceVariableRunTime> deviceVariables)
|
||||
{
|
||||
return deviceVariables.LoadSourceRead(_plc);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(CollectDeviceRunTime device, object client = null)
|
||||
{
|
||||
if (client == null)
|
||||
{
|
||||
FoundataionConfig.SetSerialProperty(new()
|
||||
{
|
||||
PortName = driverPropertys.PortName,
|
||||
BaudRate = driverPropertys.BaudRate,
|
||||
DataBits = driverPropertys.DataBits,
|
||||
Parity = driverPropertys.Parity,
|
||||
StopBits = driverPropertys.StopBits,
|
||||
})
|
||||
.SetBufferLength(1024);
|
||||
client = new SerialClient();
|
||||
((SerialClient)client).Setup(FoundataionConfig);
|
||||
}
|
||||
//载入配置
|
||||
_plc = new((SerialClient)client)
|
||||
{
|
||||
FrameTime = driverPropertys.FrameTime,
|
||||
CacheTimeout = driverPropertys.CacheTimeout,
|
||||
DataFormat = driverPropertys.DataFormat,
|
||||
EnableFEHead = driverPropertys.EnableFEHead,
|
||||
OperCode = driverPropertys.OperCode,
|
||||
Password = driverPropertys.Password,
|
||||
Station = driverPropertys.Station,
|
||||
TimeOut = driverPropertys.TimeOut
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken token)
|
||||
{
|
||||
return await _plc.ReadAsync(address, length, token);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
@*
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
*@
|
||||
|
||||
@using BlazorComponent;
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using Microsoft.JSInterop;
|
||||
@using ThingsGateway.Admin.Core;
|
||||
@using ThingsGateway.Foundation.Adapter.DLT645;
|
||||
@using ThingsGateway.Foundation;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using ThingsGateway.Blazor;
|
||||
@namespace ThingsGateway.DLT645
|
||||
@using Masa.Blazor
|
||||
@using ThingsGateway.Application;
|
||||
|
||||
<DefalutDebugDriverPage Channel="ChannelEnum.SerialPort" @ref=defalutDebugDriverPage>
|
||||
<MCard Flat Elevation="0">
|
||||
<MRow Class="my-1" NoGutters Justify="JustifyTypes.SpaceBetween" Align="AlignTypes.Center">
|
||||
<MCheckbox Class="ma-1" Label=@(_plc.Description(x => x.EnableFEHead)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.EnableFEHead></MCheckbox>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.FrameTime)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.CacheTimeout)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.Station)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.OperCode)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.OperCode></MTextField>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.Password)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.Password></MTextField>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.TimeOut)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MSelect Class="ma-1" Style="max-width:200px" @bind-Value="_plc.DataFormat" Outlined Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.des)
|
||||
ItemValue=@(u =>(DataFormat)u.value)
|
||||
HideDetails=@("auto") Height="30"
|
||||
Dense>
|
||||
</MSelect>
|
||||
</MRow>
|
||||
</MCard>
|
||||
</DefalutDebugDriverPage>
|
||||
|
||||
@code
|
||||
{
|
||||
private DefalutDebugDriverPage defalutDebugDriverPage;
|
||||
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007 _plc;
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
//载入配置
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007((SerialClient)defalutDebugDriverPage.SerialClientPage.GetSerialClient());
|
||||
defalutDebugDriverPage.Plc = _plc;
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return nameof(DLT645_2007);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.IO.Ports;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
namespace ThingsGateway.DLT645;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class DLT645_2007Property : CollectDriverPropertyBase
|
||||
{
|
||||
/// <summary>
|
||||
/// COM口
|
||||
/// </summary>
|
||||
[DeviceProperty("COM口", "示例:COM1")]
|
||||
public override string PortName { get; set; } = "COM1";
|
||||
/// <summary>
|
||||
/// 波特率
|
||||
/// </summary>
|
||||
[DeviceProperty("波特率", "通常为:38400/19200/9600/4800")]
|
||||
public override int BaudRate { get; set; } = 9600;
|
||||
/// <summary>
|
||||
/// 数据位
|
||||
/// </summary>
|
||||
[DeviceProperty("数据位", "通常为:8/7/6")]
|
||||
public override byte DataBits { get; set; } = 8;
|
||||
|
||||
/// <summary>
|
||||
/// 停止位
|
||||
/// </summary>
|
||||
[DeviceProperty("停止位", "示例:None/One/Two/OnePointFive")]
|
||||
public override StopBits StopBits { get; set; } = StopBits.One;
|
||||
|
||||
/// <summary>
|
||||
/// 校验位
|
||||
/// </summary>
|
||||
[DeviceProperty("校验位", "示例:None/Odd/Even/Mark/Space")]
|
||||
public override Parity Parity { get; set; } = Parity.None;
|
||||
|
||||
/// <summary>
|
||||
/// 读写超时时间
|
||||
/// </summary>
|
||||
[DeviceProperty("读写超时时间", "")]
|
||||
public ushort TimeOut { get; set; } = 3000;
|
||||
/// <summary>
|
||||
/// 默认地址
|
||||
/// </summary>
|
||||
[DeviceProperty("默认地址", "")]
|
||||
public string Station { get; set; }
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
[DeviceProperty("密码", "")]
|
||||
public string Password { get; set; }
|
||||
/// <summary>
|
||||
/// 操作员代码
|
||||
/// </summary>
|
||||
[DeviceProperty("操作员代码", "")]
|
||||
public string OperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 前导符报文头
|
||||
/// </summary>
|
||||
[DeviceProperty("前导符报文头", "")]
|
||||
public bool EnableFEHead { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 默认解析顺序
|
||||
/// </summary>
|
||||
[DeviceProperty("默认解析顺序", "")]
|
||||
public DataFormat DataFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 帧前时间ms
|
||||
/// </summary>
|
||||
[DeviceProperty("帧前时间", "某些设备性能较弱,报文间需要间隔较长时间")]
|
||||
public int FrameTime { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 组包缓存超时ms
|
||||
/// </summary>
|
||||
[DeviceProperty("组包缓存超时ms", "某些设备性能较弱,报文间需要间隔较长时间,可以设置更长的组包缓存,默认1s")]
|
||||
public int CacheTimeout { get; set; } = 1000;
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 共享链路
|
||||
/// </summary>
|
||||
[DeviceProperty("共享链路", "")]
|
||||
public override bool IsShareChannel { get; set; } = false;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public override ShareChannelEnum ShareChannel => ShareChannelEnum.SerialPort;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
namespace ThingsGateway.DLT645;
|
||||
|
||||
internal static class DLT645_2007Helper
|
||||
{
|
||||
internal static List<DeviceVariableSourceRead> LoadSourceRead(this List<DeviceVariableRunTime> deviceVariables, IReadWriteDevice device)
|
||||
{
|
||||
var byteConverter = device.ThingsGatewayBitConverter;
|
||||
var result = new List<DeviceVariableSourceRead>();
|
||||
//需要先剔除额外信息,比如dataformat等
|
||||
foreach (var item in deviceVariables)
|
||||
{
|
||||
var address = item.VariableAddress;
|
||||
|
||||
IThingsGatewayBitConverter transformParameter = ByteTransformUtil.GetTransByAddress(ref address, byteConverter);
|
||||
item.ThingsGatewayBitConverter = transformParameter;
|
||||
item.VariableAddress = address;
|
||||
item.Index = device.GetBitOffset(item.VariableAddress);
|
||||
|
||||
result.Add(new()
|
||||
{
|
||||
DeviceVariables = new() { item },
|
||||
Address = address,
|
||||
Length = 1,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
using TouchSocket.Sockets;
|
||||
|
||||
namespace ThingsGateway.DLT645;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public class DLT645_2007OverTcp : CollectBase
|
||||
{
|
||||
|
||||
private readonly ModbusRtuOverTcpProperty driverPropertys = new();
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => _plc;
|
||||
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp _plc;
|
||||
/// <inheritdoc/>
|
||||
public override Type DriverDebugUIType => typeof(ModbusRtuOverTcpDebugDriverPage);
|
||||
/// <inheritdoc/>
|
||||
public override CollectDriverPropertyBase DriverPropertys => driverPropertys;
|
||||
/// <inheritdoc/>
|
||||
public override bool IsSupportRequest => true;
|
||||
/// <inheritdoc/>
|
||||
public override IThingsGatewayBitConverter ThingsGatewayBitConverter { get => _plc?.ThingsGatewayBitConverter; }
|
||||
/// <inheritdoc/>
|
||||
public override Task AfterStopAsync()
|
||||
{
|
||||
_plc?.Disconnect();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task BeforStartAsync(CancellationToken token)
|
||||
{
|
||||
await _plc?.ConnectAsync(token);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override void InitDataAdapter()
|
||||
{
|
||||
_plc.SetDataAdapter();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool IsConnected()
|
||||
{
|
||||
return _plc?.TcpClientEx?.CanSend == true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<DeviceVariableSourceRead> LoadSourceRead(List<DeviceVariableRunTime> deviceVariables)
|
||||
{
|
||||
return deviceVariables.LoadSourceRead(_plc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_plc?.Disconnect();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(CollectDeviceRunTime device, object client = null)
|
||||
{
|
||||
if (client == null)
|
||||
{
|
||||
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
|
||||
.SetBufferLength(1024);
|
||||
client = new TcpClientEx();
|
||||
((TcpClientEx)client).Setup(FoundataionConfig);
|
||||
}
|
||||
//载入配置
|
||||
_plc = new((TcpClientEx)client)
|
||||
{
|
||||
FrameTime = driverPropertys.FrameTime,
|
||||
CacheTimeout = driverPropertys.CacheTimeout,
|
||||
DataFormat = driverPropertys.DataFormat,
|
||||
EnableFEHead = driverPropertys.EnableFEHead,
|
||||
OperCode = driverPropertys.OperCode,
|
||||
Password = driverPropertys.Password,
|
||||
Station = driverPropertys.Station,
|
||||
TimeOut = driverPropertys.TimeOut
|
||||
};
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken token)
|
||||
{
|
||||
return await _plc.ReadAsync(address, length, token);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
@*
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
*@
|
||||
|
||||
@using BlazorComponent;
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using Microsoft.JSInterop;
|
||||
@using ThingsGateway.Admin.Core;
|
||||
@using ThingsGateway.Foundation.Adapter.Modbus;
|
||||
@using ThingsGateway.Foundation;
|
||||
@using ThingsGateway.Foundation.Extension;
|
||||
@using ThingsGateway.Foundation.Serial;
|
||||
@using ThingsGateway.Application;
|
||||
@using Masa.Blazor
|
||||
@using ThingsGateway.Blazor;
|
||||
@namespace ThingsGateway.DLT645
|
||||
<DefalutDebugDriverPage Channel="ChannelEnum.TcpClientEx" @ref=defalutDebugDriverPage>
|
||||
<MCard Flat Elevation="0">
|
||||
<MRow Class="my-1" NoGutters Justify="JustifyTypes.SpaceBetween" Align="AlignTypes.Center">
|
||||
<MCheckbox Class="ma-1" Label=@(_plc.Description(x => x.EnableFEHead)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.EnableFEHead></MCheckbox>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.FrameTime)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.FrameTime></MTextField>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.CacheTimeout)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.CacheTimeout></MTextField>
|
||||
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.Station)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.OperCode)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.OperCode></MTextField>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.Password)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.Password></MTextField>
|
||||
<MTextField Class="ma-1" Label=@(_plc.Description(x => x.TimeOut)) Dense Outlined HideDetails="@("auto")" @bind-Value=@_plc.TimeOut></MTextField>
|
||||
<MSelect Class="ma-1" Style="max-width:200px" @bind-Value="_plc.DataFormat" Outlined Label="@(_plc.Description(x => x.DataFormat))"
|
||||
Items=@(typeof(DataFormat).GetEnumList())
|
||||
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
|
||||
ItemText=@((u) =>u.des)
|
||||
ItemValue=@(u =>(DataFormat)u.value)
|
||||
HideDetails=@("auto") Height="30"
|
||||
Dense>
|
||||
</MSelect>
|
||||
</MRow>
|
||||
</MCard>
|
||||
</DefalutDebugDriverPage>
|
||||
|
||||
|
||||
@code
|
||||
{
|
||||
private DefalutDebugDriverPage defalutDebugDriverPage;
|
||||
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp _plc;
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
//载入配置
|
||||
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp((TcpClientEx)defalutDebugDriverPage.TcpClientPage.GetTcpClient());
|
||||
defalutDebugDriverPage.Plc = _plc;
|
||||
}
|
||||
base.OnAfterRender(firstRender);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return nameof(DLT645_2007OverTcp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
namespace ThingsGateway.DLT645;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class ModbusRtuOverTcpProperty : CollectDriverPropertyBase
|
||||
{
|
||||
/// <summary>
|
||||
/// IP
|
||||
/// </summary>
|
||||
[DeviceProperty("IP", "")]
|
||||
public override string IP { get; set; } = "127.0.0.1";
|
||||
/// <summary>
|
||||
/// 端口
|
||||
/// </summary>
|
||||
[DeviceProperty("端口", "")]
|
||||
public override int Port { get; set; } = 502;
|
||||
/// <summary>
|
||||
/// 默认解析顺序
|
||||
/// </summary>
|
||||
[DeviceProperty("默认解析顺序", "")]
|
||||
public DataFormat DataFormat { get; set; }
|
||||
/// <summary>
|
||||
/// 连接超时时间
|
||||
/// </summary>
|
||||
[DeviceProperty("连接超时时间", "")]
|
||||
public ushort ConnectTimeOut { get; set; } = 3000;
|
||||
/// <summary>
|
||||
/// 默认地址
|
||||
/// </summary>
|
||||
[DeviceProperty("默认地址", "")]
|
||||
public string Station { get; set; }
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
[DeviceProperty("密码", "")]
|
||||
public string Password { get; set; }
|
||||
/// <summary>
|
||||
/// 操作员代码
|
||||
/// </summary>
|
||||
[DeviceProperty("操作员代码", "")]
|
||||
public string OperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 前导符报文头
|
||||
/// </summary>
|
||||
[DeviceProperty("前导符报文头", "")]
|
||||
public bool EnableFEHead { get; set; } = true;
|
||||
/// <summary>
|
||||
/// 读写超时时间
|
||||
/// </summary>
|
||||
[DeviceProperty("读写超时时间", "")]
|
||||
public ushort TimeOut { get; set; } = 3000;
|
||||
/// <summary>
|
||||
/// 帧前时间ms
|
||||
/// </summary>
|
||||
[DeviceProperty("帧前时间ms", "某些设备性能较弱,报文间需要间隔较长时间")]
|
||||
public int FrameTime { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 组包缓存超时ms
|
||||
/// </summary>
|
||||
[DeviceProperty("组包缓存超时", "某些设备性能较弱,报文间需要间隔较长时间,可以设置更长的组包缓存,默认1s")]
|
||||
public int CacheTimeout { get; set; } = 1;
|
||||
/// <summary>
|
||||
/// 共享链路
|
||||
/// </summary>
|
||||
[DeviceProperty("共享链路", "")]
|
||||
public override bool IsShareChannel { get; set; } = false;
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public override ShareChannelEnum ShareChannel => ShareChannelEnum.TcpClientEx;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
global using System;
|
||||
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<!--<GenerateDocumentationFile>True</GenerateDocumentationFile>-->
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
|
||||
<Exec Command=" set dir="$(SolutionDir)ThingsGateway.Web.Entry\bin\$(Configuration)\$(TargetFramework)\Plugins\$(AssemblyName)"
 if not exist %25dir%25 md %25dir%25 
copy "$(TargetDir)*DLT645*.dll" %25dir%25


" />
|
||||
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ThingsGateway.Blazor\ThingsGateway.Blazor.csproj">
|
||||
<IncludeAssets>Compile</IncludeAssets>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Foundataion\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,244 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ThingsGateway.DLT645</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:ThingsGateway.DLT645.DLT645_2007OverTcp">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007OverTcp.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007OverTcp.DriverDebugUIType">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007OverTcp.DriverPropertys">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007OverTcp.IsSupportRequest">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007OverTcp.ThingsGatewayBitConverter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007OverTcp.AfterStopAsync">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007OverTcp.BeforStartAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007OverTcp.InitDataAdapter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007OverTcp.IsConnected">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007OverTcp.LoadSourceRead(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariableRunTime})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007OverTcp.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007OverTcp.Init(ThingsGateway.Application.CollectDeviceRunTime,System.Object)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007OverTcp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.DLT645.ModbusRtuOverTcpProperty">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.IP">
|
||||
<summary>
|
||||
IP
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.Port">
|
||||
<summary>
|
||||
端口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.DataFormat">
|
||||
<summary>
|
||||
默认解析顺序
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.ConnectTimeOut">
|
||||
<summary>
|
||||
连接超时时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.Station">
|
||||
<summary>
|
||||
默认地址
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.Password">
|
||||
<summary>
|
||||
密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.OperCode">
|
||||
<summary>
|
||||
操作员代码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.EnableFEHead">
|
||||
<summary>
|
||||
前导符报文头
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.TimeOut">
|
||||
<summary>
|
||||
读写超时时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.FrameTime">
|
||||
<summary>
|
||||
帧前时间ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.CacheTimeout">
|
||||
<summary>
|
||||
组包缓存超时ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.IsShareChannel">
|
||||
<summary>
|
||||
共享链路
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.ModbusRtuOverTcpProperty.ShareChannel">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.DLT645.DLT645_2007">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007.DriverDebugUIType">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007.DriverPropertys">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007.IsSupportRequest">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007.ThingsGatewayBitConverter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007.AfterStopAsync">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007.BeforStartAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007.InitDataAdapter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007.IsConnected">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007.LoadSourceRead(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariableRunTime})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007.Init(ThingsGateway.Application.CollectDeviceRunTime,System.Object)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.DLT645.DLT645_2007.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.DLT645.DLT645_2007Property">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.PortName">
|
||||
<summary>
|
||||
COM口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.BaudRate">
|
||||
<summary>
|
||||
波特率
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.DataBits">
|
||||
<summary>
|
||||
数据位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.StopBits">
|
||||
<summary>
|
||||
停止位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.Parity">
|
||||
<summary>
|
||||
校验位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.TimeOut">
|
||||
<summary>
|
||||
读写超时时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.Station">
|
||||
<summary>
|
||||
默认地址
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.Password">
|
||||
<summary>
|
||||
密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.OperCode">
|
||||
<summary>
|
||||
操作员代码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.EnableFEHead">
|
||||
<summary>
|
||||
前导符报文头
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.DataFormat">
|
||||
<summary>
|
||||
默认解析顺序
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.FrameTime">
|
||||
<summary>
|
||||
帧前时间ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.CacheTimeout">
|
||||
<summary>
|
||||
组包缓存超时ms
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.IsShareChannel">
|
||||
<summary>
|
||||
共享链路
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.DLT645.DLT645_2007Property.ShareChannel">
|
||||
<summary>
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Serial;
|
||||
@@ -22,6 +20,8 @@ namespace ThingsGateway.Modbus;
|
||||
public class ModbusRtu : CollectBase
|
||||
{
|
||||
private readonly ModbusRtuProperty driverPropertys = new();
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => _plc;
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu _plc;
|
||||
/// <inheritdoc/>
|
||||
public override Type DriverDebugUIType => typeof(ModbusRtuDebugDriverPage);
|
||||
@@ -74,12 +74,6 @@ public class ModbusRtu : CollectBase
|
||||
return deviceVariables.LoadSourceRead(_plc, driverPropertys.MaxPack);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
{
|
||||
return await _plc.WriteAsync(deviceVariable.VariableAddress, deviceVariable.DataType, value.ToString(), token);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(CollectDeviceRunTime device, object client = null)
|
||||
{
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
@@ -22,6 +20,8 @@ public class ModbusRtuOverTcp : CollectBase
|
||||
{
|
||||
|
||||
private readonly ModbusRtuOverTcpProperty driverPropertys = new();
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => _plc;
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp _plc;
|
||||
/// <inheritdoc/>
|
||||
public override Type DriverDebugUIType => typeof(ModbusRtuOverTcpDebugDriverPage);
|
||||
@@ -61,11 +61,7 @@ public class ModbusRtuOverTcp : CollectBase
|
||||
return deviceVariables.LoadSourceRead(_plc, driverPropertys.MaxPack);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
{
|
||||
return await _plc.WriteAsync(deviceVariable.VariableAddress, deviceVariable.DataType, value.ToString(), token);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
@@ -22,6 +20,8 @@ namespace ThingsGateway.Modbus;
|
||||
public class ModbusRtuOverUdp : CollectBase
|
||||
{
|
||||
private readonly ModbusRtuOverUdpProperty driverPropertys = new();
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => _plc;
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp _plc;
|
||||
/// <inheritdoc/>
|
||||
public override Type DriverDebugUIType => typeof(ModbusRtuOverUdpDebugDriverPage);
|
||||
@@ -65,11 +65,7 @@ public class ModbusRtuOverUdp : CollectBase
|
||||
return deviceVariables.LoadSourceRead(_plc, driverPropertys.MaxPack);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
{
|
||||
return await _plc.WriteAsync(deviceVariable.VariableAddress, deviceVariable.DataType, value.ToString(), token);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
|
||||
@@ -201,16 +201,25 @@ public class ModbusServer : UpLoadBase
|
||||
if (Enum.TryParse<DataTypeEnum>(type, out DataTypeEnum result))
|
||||
{
|
||||
var resultTask1 = RpcCore.InvokeDeviceMethodAsync($"{nameof(ModbusServer)}-{CurDevice.Name}-{client.IP + ":" + client.Port}",
|
||||
new(tag.Value.Name, thingsGatewayBitConverter.GetDynamicDataFormBytes(addressStr ?? string.Empty, result.GetSystemType(), bytes).ToString()));
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{tag.Value.Name, thingsGatewayBitConverter.GetDynamicDataFormBytes(addressStr ?? string.Empty, result.GetSystemType(), bytes).ToString()},
|
||||
}
|
||||
|
||||
);
|
||||
var result1 = resultTask1.ConfigureAwait(true).GetAwaiter().GetResult();
|
||||
return result1;
|
||||
return result1.FirstOrDefault().Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var resultTask1 = RpcCore.InvokeDeviceMethodAsync($"{nameof(ModbusServer)}-{CurDevice.Name}-{client.IP + ":" + client.Port}",
|
||||
new(tag.Value.Name, thingsGatewayBitConverter.GetDynamicDataFormBytes(addressStr ?? string.Empty, tag.Value.DataType, bytes).ToString()));
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{tag.Value.Name, thingsGatewayBitConverter.GetDynamicDataFormBytes(addressStr ?? string.Empty, result.GetSystemType(), bytes).ToString()},
|
||||
}
|
||||
);
|
||||
var result1 = resultTask1.ConfigureAwait(true).GetAwaiter().GetResult();
|
||||
return result1;
|
||||
return result1.FirstOrDefault().Value;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
@@ -22,6 +20,8 @@ namespace ThingsGateway.Modbus;
|
||||
/// </summary>
|
||||
public class ModbusTcp : CollectBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => _plc;
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp _plc;
|
||||
|
||||
private readonly ModbusTcpProperty driverPropertys = new();
|
||||
@@ -67,11 +67,7 @@ public class ModbusTcp : CollectBase
|
||||
return deviceVariables.LoadSourceRead(_plc, driverPropertys.MaxPack);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
{
|
||||
return await _plc.WriteAsync(deviceVariable.VariableAddress, deviceVariable.DataType, value.ToString(), token);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
@@ -21,6 +19,8 @@ namespace ThingsGateway.Modbus;
|
||||
/// <inheritdoc/>
|
||||
public class ModbusUdp : CollectBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => _plc;
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp _plc;
|
||||
|
||||
private readonly ModbusUdpProperty driverPropertys = new();
|
||||
@@ -66,11 +66,7 @@ public class ModbusUdp : CollectBase
|
||||
return deviceVariables.LoadSourceRead(_plc, driverPropertys.MaxPack);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
{
|
||||
return await _plc.WriteAsync(deviceVariable.VariableAddress, deviceVariable.DataType, value.ToString(), token);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
<member name="T:ThingsGateway.Modbus.ModbusRtuOverTcp">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusRtuOverTcp.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusRtuOverTcp.DriverDebugUIType">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -34,9 +37,6 @@
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtuOverTcp.LoadSourceRead(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariableRunTime})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtuOverTcp.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtuOverTcp.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -116,6 +116,9 @@
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusRtuOverUdp.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusRtuOverUdp.DriverDebugUIType">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -143,9 +146,6 @@
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtuOverUdp.LoadSourceRead(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariableRunTime})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtuOverUdp.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtuOverUdp.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -168,6 +168,9 @@
|
||||
<member name="T:ThingsGateway.Modbus.ModbusRtu">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusRtu.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusRtu.DriverDebugUIType">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -200,9 +203,6 @@
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtu.LoadSourceRead(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariableRunTime})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtu.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusRtu.Init(ThingsGateway.Application.CollectDeviceRunTime,System.Object)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -400,6 +400,9 @@
|
||||
<inheritdoc/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusTcp.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusTcp.DriverDebugUIType">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -427,9 +430,6 @@
|
||||
<member name="M:ThingsGateway.Modbus.ModbusTcp.LoadSourceRead(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariableRunTime})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusTcp.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusTcp.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -507,6 +507,9 @@
|
||||
<member name="T:ThingsGateway.Modbus.ModbusUdp">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusUdp.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Modbus.ModbusUdp.DriverDebugUIType">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -534,9 +537,6 @@
|
||||
<member name="M:ThingsGateway.Modbus.ModbusUdp.LoadSourceRead(System.Collections.Generic.List{ThingsGateway.Application.DeviceVariableRunTime})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusUdp.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Modbus.ModbusUdp.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
|
||||
@@ -340,9 +340,7 @@ GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean()
|
||||
&& driverPropertys.DeviceRpcEnable;
|
||||
if (rpcEnable == true)
|
||||
{
|
||||
var result = await _rpcCore.InvokeDeviceMethodAsync(ToString() + "-" + rpcrequestid, item);
|
||||
|
||||
results.Add(item.Key, result);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -356,6 +354,12 @@ GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean()
|
||||
results.Add(item.Key, new("不存在该变量"));
|
||||
}
|
||||
}
|
||||
|
||||
var result = await _rpcCore.InvokeDeviceMethodAsync(ToString() + "-" + rpcrequestid, nameValue
|
||||
.Where(a => !results.Any(b => b.Key == a.Key))
|
||||
.ToDictionary(a => a.Key, a => a.Value));
|
||||
|
||||
results.AddRange(result);
|
||||
rpcResponse = new()
|
||||
{
|
||||
DeviceId = rpcdevicename,
|
||||
|
||||
@@ -317,6 +317,7 @@ public class MqttClient : UpLoadBase
|
||||
.WithTcpServer(driverPropertys.IP, driverPropertys.Port)//服务器
|
||||
.WithCleanSession(true)
|
||||
.WithKeepAlivePeriod(TimeSpan.FromSeconds(120.0))
|
||||
.WithoutThrowOnNonSuccessfulConnectResponse()
|
||||
.Build();
|
||||
_mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
|
||||
.WithTopicFilter(
|
||||
@@ -405,40 +406,48 @@ public class MqttClient : UpLoadBase
|
||||
return;
|
||||
if (arg.ApplicationMessage.Topic != driverPropertys.RpcWriteTopic)
|
||||
return;
|
||||
var rpcData = Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment).FromJson<MqttRpcNameVaueWithId>();
|
||||
if (rpcData == null)
|
||||
var rpcDatas = Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment).FromJson<MqttRpcNameVaueWithId>();
|
||||
if (rpcDatas == null)
|
||||
return;
|
||||
|
||||
MqttRpcResult mqttRpcResult = new();
|
||||
MqttRpcResult mqttRpcResult = new() { RpcId = rpcDatas.RpcId, Success = true };
|
||||
try
|
||||
{
|
||||
var nv = rpcData.Adapt<KeyValuePair<string, string>>();
|
||||
var tag = _uploadVariables.FirstOrDefault(a => a.Name == nv.Key);
|
||||
if (tag != null)
|
||||
foreach (var rpcData in rpcDatas.WriteInfos)
|
||||
{
|
||||
var rpcEnable = GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean();
|
||||
if (rpcEnable == true)
|
||||
|
||||
var tag = _uploadVariables.FirstOrDefault(a => a.Name == rpcData.Key);
|
||||
if (tag != null)
|
||||
{
|
||||
var result = await _rpcCore.InvokeDeviceMethodAsync(ToString() + "-" + arg.ClientId, nv);
|
||||
|
||||
mqttRpcResult = new() { Message = result.Message, RpcId = rpcData.RpcId, Success = result.IsSuccess };
|
||||
var rpcEnable = GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean();
|
||||
if (rpcEnable == true)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
mqttRpcResult.Success = false;
|
||||
mqttRpcResult.Message.Add(rpcData.Key, new("权限不足,变量不支持写入"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mqttRpcResult = new() { Message = "权限不足,变量不支持写入", RpcId = rpcData.RpcId, Success = false };
|
||||
mqttRpcResult.Success = false;
|
||||
mqttRpcResult.Message.Add(rpcData.Key, new("不存在该变量"));
|
||||
}
|
||||
}
|
||||
|
||||
var result = await _rpcCore.InvokeDeviceMethodAsync(ToString() + "-" + arg.ClientId,
|
||||
rpcDatas.WriteInfos.Where(
|
||||
a => !mqttRpcResult.Message.Any(b => b.Key == a.Key)).ToDictionary(a => a.Key, a => a.Value));
|
||||
|
||||
mqttRpcResult.Message.AddRange(result);
|
||||
mqttRpcResult.Success = !mqttRpcResult.Message.Any(a => !a.Value.IsSuccess);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
mqttRpcResult = new() { Message = "不存在该变量", RpcId = rpcData.RpcId, Success = false };
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage?.LogWarning(ex, ToString());
|
||||
mqttRpcResult = new() { Message = "Failed", RpcId = rpcData.RpcId, Success = false };
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
namespace ThingsGateway.Mqtt;
|
||||
|
||||
/// <summary>
|
||||
@@ -22,13 +26,9 @@ public class MqttRpcNameVaueWithId
|
||||
/// </summary>
|
||||
public string RpcId { get; set; }
|
||||
/// <summary>
|
||||
/// 通常是变量名称
|
||||
/// "WriteInfos":{"test":"1"}
|
||||
/// </summary>
|
||||
public string Key { get; set; }
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
public Dictionary<string, string> WriteInfos { get; set; } = new();
|
||||
}
|
||||
/// <summary>
|
||||
/// MqttRpc输出
|
||||
@@ -42,7 +42,7 @@ public class MqttRpcResult
|
||||
/// <summary>
|
||||
/// 消息
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
public Dictionary<string, OperResult> Message { get; set; } = new();
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
|
||||
@@ -260,41 +260,46 @@ public class MqttServer : UpLoadBase
|
||||
return;
|
||||
if (arg.ApplicationMessage.Topic != driverPropertys.RpcWriteTopic)
|
||||
return;
|
||||
var rpcData = Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment).FromJson<MqttRpcNameVaueWithId>();
|
||||
if (rpcData == null)
|
||||
var rpcDatas = Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment).FromJson<MqttRpcNameVaueWithId>();
|
||||
if (rpcDatas == null)
|
||||
return;
|
||||
MqttRpcResult mqttRpcResult = new();
|
||||
MqttRpcResult mqttRpcResult = new() { RpcId = rpcDatas.RpcId, Success = true };
|
||||
try
|
||||
{
|
||||
var nv = rpcData.Adapt<KeyValuePair<string, string>>();
|
||||
var tag = _uploadVariables.FirstOrDefault(a => a.Name == nv.Key);
|
||||
if (tag != null)
|
||||
foreach (var rpcData in rpcDatas.WriteInfos)
|
||||
{
|
||||
var rpcEnable = GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean();
|
||||
if (rpcEnable == true)
|
||||
|
||||
var tag = _uploadVariables.FirstOrDefault(a => a.Name == rpcData.Key);
|
||||
if (tag != null)
|
||||
{
|
||||
var result = await _rpcCore.InvokeDeviceMethodAsync(ToString() + "-" + IdWithName[arg.ClientId], nv);
|
||||
|
||||
mqttRpcResult = new() { Message = result.Message, RpcId = rpcData.RpcId, Success = result.IsSuccess };
|
||||
var rpcEnable = GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean();
|
||||
if (rpcEnable == true)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
mqttRpcResult.Success = false;
|
||||
mqttRpcResult.Message.Add(rpcData.Key, new("权限不足,变量不支持写入"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mqttRpcResult = new() { Message = "权限不足,变量不支持写入", RpcId = rpcData.RpcId, Success = false };
|
||||
mqttRpcResult.Success = false;
|
||||
mqttRpcResult.Message.Add(rpcData.Key, new("不存在该变量"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
mqttRpcResult = new() { Message = "不存在该变量", RpcId = rpcData.RpcId, Success = false };
|
||||
}
|
||||
var result = await _rpcCore.InvokeDeviceMethodAsync(ToString() + "-" + arg.ClientId,
|
||||
rpcDatas.WriteInfos.Where(
|
||||
a => !mqttRpcResult.Message.Any(b => b.Key == a.Key)).ToDictionary(a => a.Key, a => a.Value));
|
||||
|
||||
mqttRpcResult.Message.AddRange(result);
|
||||
mqttRpcResult.Success = !mqttRpcResult.Message.Any(a => !a.Value.IsSuccess);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage?.LogWarning(ex, ToString());
|
||||
mqttRpcResult = new() { Message = "Failed", RpcId = rpcData.RpcId, Success = false };
|
||||
|
||||
}
|
||||
try
|
||||
{
|
||||
@@ -302,7 +307,7 @@ public class MqttServer : UpLoadBase
|
||||
.WithTopic($"{driverPropertys.RpcSubTopic}")
|
||||
.WithPayload(mqttRpcResult.ToJson()).Build();
|
||||
await _mqttServer.InjectApplicationMessage(
|
||||
new InjectedMqttApplicationMessage(variableMessage));
|
||||
new InjectedMqttApplicationMessage(variableMessage));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -294,14 +294,9 @@
|
||||
标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Mqtt.MqttRpcNameVaueWithId.Key">
|
||||
<member name="P:ThingsGateway.Mqtt.MqttRpcNameVaueWithId.WriteInfos">
|
||||
<summary>
|
||||
通常是变量名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Mqtt.MqttRpcNameVaueWithId.Value">
|
||||
<summary>
|
||||
值
|
||||
"WriteInfos":{"test":"1"}
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ThingsGateway.Mqtt.MqttRpcResult">
|
||||
|
||||
@@ -35,7 +35,7 @@ public class OPCDAClient : CollectBase
|
||||
{
|
||||
internal CollectDeviceRunTime Device;
|
||||
|
||||
internal ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient PLC = null;
|
||||
internal ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient _plc = null;
|
||||
|
||||
private readonly OPCDAClientProperty driverPropertys = new();
|
||||
private ConcurrentList<DeviceVariableRunTime> _deviceVariables = new();
|
||||
@@ -50,17 +50,20 @@ public class OPCDAClient : CollectBase
|
||||
/// <inheritdoc/>
|
||||
public override ThingsGatewayBitConverter ThingsGatewayBitConverter { get; } = new(EndianType.Little);
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => null;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task AfterStopAsync()
|
||||
{
|
||||
PLC?.Disconnect();
|
||||
_plc?.Disconnect();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task BeforStartAsync(CancellationToken token)
|
||||
{
|
||||
PLC.Connect();
|
||||
_plc.Connect();
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -69,14 +72,19 @@ public class OPCDAClient : CollectBase
|
||||
{
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public override bool IsConnected() => PLC?.IsConnected == true;
|
||||
public override bool IsConnected()
|
||||
{
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime);
|
||||
return _plc?.IsConnected == true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<DeviceVariableSourceRead> LoadSourceRead(List<DeviceVariableRunTime> deviceVariables)
|
||||
{
|
||||
_deviceVariables = new(deviceVariables);
|
||||
if (deviceVariables.Count > 0)
|
||||
{
|
||||
var result = PLC.AddItemsWithSave(deviceVariables.Select(a => a.VariableAddress).ToList());
|
||||
var result = _plc.AddItemsWithSave(deviceVariables.Select(a => a.VariableAddress).ToList());
|
||||
var sourVars = result?.Select(
|
||||
it =>
|
||||
{
|
||||
@@ -98,26 +106,31 @@ public class OPCDAClient : CollectBase
|
||||
public override async Task<OperResult<byte[]>> ReadSourceAsync(DeviceVariableSourceRead deviceVariableSourceRead, CancellationToken token)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
var result = PLC.ReadItemsWithGroup(deviceVariableSourceRead.Address);
|
||||
var result = _plc.ReadItemsWithGroup(deviceVariableSourceRead.Address);
|
||||
return result.Copy<byte[]>();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
public override Task<Dictionary<string, OperResult>> WriteValuesAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token)
|
||||
{
|
||||
var result = PLC.WriteItem(deviceVariable.VariableAddress, value);
|
||||
return Task.FromResult(result);
|
||||
var result = _plc.WriteItem(writeInfoLists.ToDictionary(a => a.Key.VariableAddress, a => a.Value));
|
||||
return Task.FromResult(result.ToDictionary(a =>
|
||||
{
|
||||
return writeInfoLists.Keys.FirstOrDefault(b => b.VariableAddress == a.Key).Name;
|
||||
}, a => a.Value));
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (PLC != null)
|
||||
PLC.DataChangedHandler -= DataChangedHandler;
|
||||
PLC?.Disconnect();
|
||||
PLC?.SafeDispose();
|
||||
PLC = null;
|
||||
if (_plc != null)
|
||||
_plc.DataChangedHandler -= DataChangedHandler;
|
||||
_plc?.Disconnect();
|
||||
_plc?.SafeDispose();
|
||||
_plc = null;
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
@@ -134,12 +147,12 @@ public class OPCDAClient : CollectBase
|
||||
ActiveSubscribe = driverPropertys.ActiveSubscribe,
|
||||
CheckRate = driverPropertys.CheckRate
|
||||
};
|
||||
if (PLC == null)
|
||||
if (_plc == null)
|
||||
{
|
||||
PLC = new(LogMessage);
|
||||
PLC.DataChangedHandler += DataChangedHandler;
|
||||
_plc = new(LogMessage);
|
||||
_plc.DataChangedHandler += DataChangedHandler;
|
||||
}
|
||||
PLC.Init(opcNode);
|
||||
_plc.Init(opcNode);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Components;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ThingsGateway.Admin.Blazor.Core;
|
||||
@@ -147,14 +148,19 @@ public partial class OPCDAClientDebugDriverPage : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = _plc.WriteItem(defalutDebugDriverPage.Address, defalutDebugDriverPage.WriteValue);
|
||||
if (data.IsSuccess)
|
||||
var data = _plc.WriteItem(
|
||||
new()
|
||||
{
|
||||
{defalutDebugDriverPage.Address, defalutDebugDriverPage.WriteValue }
|
||||
}
|
||||
);
|
||||
if (data.Values.FirstOrDefault().IsSuccess)
|
||||
{
|
||||
defalutDebugDriverPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - 写入" + data.Message));
|
||||
defalutDebugDriverPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - 写入" + data.Values.FirstOrDefault().Message));
|
||||
}
|
||||
else
|
||||
{
|
||||
defalutDebugDriverPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + data.Message));
|
||||
defalutDebugDriverPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + data.Values.FirstOrDefault().Message));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
<member name="P:ThingsGateway.OPCDA.OPCDAClient.ThingsGatewayBitConverter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.OPCDA.OPCDAClient.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.OPCDA.OPCDAClient.AfterStopAsync">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -58,7 +61,7 @@
|
||||
<member name="M:ThingsGateway.OPCDA.OPCDAClient.ReadSourceAsync(ThingsGateway.Application.DeviceVariableSourceRead,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.OPCDA.OPCDAClient.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.OPCDA.OPCDAClient.WriteValuesAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.OPCDA.OPCDAClient.Dispose(System.Boolean)">
|
||||
|
||||
@@ -22,6 +22,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ThingsGateway.Admin.Core;
|
||||
using ThingsGateway.Application;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Adapter.OPCUA;
|
||||
@@ -36,41 +37,12 @@ namespace ThingsGateway.OPCUA;
|
||||
/// </summary>
|
||||
public class OPCUAClient : CollectBase
|
||||
{
|
||||
readonly PeriodicTimer _periodicTimer = new(TimeSpan.FromSeconds(60));
|
||||
/// <summary>
|
||||
/// OPCUA客户端
|
||||
/// </summary>
|
||||
public OPCUAClient()
|
||||
{
|
||||
_ = RunTimerAsync();
|
||||
}
|
||||
|
||||
private async Task RunTimerAsync()
|
||||
{
|
||||
while (await _periodicTimer.WaitForNextTickAsync())
|
||||
{
|
||||
if (PLC != null && PLC.Session == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await PLC.ConnectAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage.Exception(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal Foundation.Adapter.OPCUA.OPCUAClient _plc = null;
|
||||
internal CollectDeviceRunTime Device;
|
||||
|
||||
internal Foundation.Adapter.OPCUA.OPCUAClient PLC = null;
|
||||
private readonly OPCUAClientProperty driverPropertys = new();
|
||||
|
||||
private List<DeviceVariableRunTime> _deviceVariables = new();
|
||||
|
||||
private readonly OPCUAClientProperty driverPropertys = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Type DriverDebugUIType => typeof(OPCUAClientDebugDriverPage);
|
||||
@@ -83,18 +55,23 @@ public class OPCUAClient : CollectBase
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override ThingsGatewayBitConverter ThingsGatewayBitConverter { get; } = new(EndianType.Little);
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => null;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task AfterStopAsync()
|
||||
{
|
||||
PLC?.Disconnect();
|
||||
_plc?.Disconnect();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task BeforStartAsync(CancellationToken token)
|
||||
{
|
||||
await PLC?.ConnectAsync();
|
||||
await _plc?.ConnectAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void InitDataAdapter()
|
||||
{
|
||||
@@ -103,15 +80,18 @@ public class OPCUAClient : CollectBase
|
||||
/// <inheritdoc/>
|
||||
public override bool IsConnected()
|
||||
{
|
||||
|
||||
return PLC.Connected;
|
||||
if (_plc.Session != null)
|
||||
{
|
||||
Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime);
|
||||
}
|
||||
return _plc?.Connected == true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override List<DeviceVariableSourceRead> LoadSourceRead(List<DeviceVariableRunTime> deviceVariables)
|
||||
{
|
||||
_deviceVariables = deviceVariables;
|
||||
PLC.Variables.AddRange(deviceVariables.Select(a => a.VariableAddress).ToList());
|
||||
_plc.Variables.AddRange(deviceVariables.Select(a => a.VariableAddress).ToList());
|
||||
var dataLists = deviceVariables.ChunkTrivialBetter(driverPropertys.GroupSize);
|
||||
var dataResult = new List<DeviceVariableSourceRead>();
|
||||
foreach (var variable in dataLists)
|
||||
@@ -131,7 +111,7 @@ public class OPCUAClient : CollectBase
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult<byte[]>> ReadSourceAsync(DeviceVariableSourceRead deviceVariableSourceRead, CancellationToken token)
|
||||
{
|
||||
var result = await PLC.ReadJTokenValueAsync(deviceVariableSourceRead.DeviceVariables.Select(a => a.VariableAddress).ToArray(), token);
|
||||
var result = await _plc.ReadJTokenValueAsync(deviceVariableSourceRead.DeviceVariables.Select(a => a.VariableAddress).ToArray(), token);
|
||||
foreach (var data in result)
|
||||
{
|
||||
if (!token.IsCancellationRequested)
|
||||
@@ -184,26 +164,32 @@ public class OPCUAClient : CollectBase
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
public override async Task<Dictionary<string, OperResult>> WriteValuesAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token)
|
||||
{
|
||||
var result = await PLC.WriteNodeAsync(deviceVariable.VariableAddress, value, token);
|
||||
return result;
|
||||
var result = await _plc.WriteNodeAsync(writeInfoLists.ToDictionary(a => a.Key.VariableAddress, a => a.Value), token);
|
||||
return result.ToDictionary(a =>
|
||||
{
|
||||
return writeInfoLists.Keys.FirstOrDefault(b => b.VariableAddress == a.Key)?.Name;
|
||||
}
|
||||
, a => a.Value);
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_periodicTimer?.Dispose();
|
||||
if (PLC != null)
|
||||
if (_plc != null)
|
||||
{
|
||||
PLC.DataChangedHandler -= DataChangedHandler;
|
||||
PLC.Disconnect();
|
||||
PLC.SafeDispose();
|
||||
PLC = null;
|
||||
_plc.DataChangedHandler -= DataChangedHandler;
|
||||
_plc.Disconnect();
|
||||
_plc.SafeDispose();
|
||||
_plc = null;
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(CollectDeviceRunTime device, object client = null)
|
||||
{
|
||||
@@ -220,13 +206,13 @@ public class OPCUAClient : CollectBase
|
||||
UserName = driverPropertys.UserName,
|
||||
Password = driverPropertys.Password
|
||||
};
|
||||
if (PLC == null)
|
||||
if (_plc == null)
|
||||
{
|
||||
PLC = new(LogMessage);
|
||||
PLC.DataChangedHandler += DataChangedHandler;
|
||||
_plc = new(LogMessage);
|
||||
_plc.DataChangedHandler += DataChangedHandler;
|
||||
}
|
||||
|
||||
PLC.OPCNode = opcNode;
|
||||
_plc.OPCNode = opcNode;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -252,7 +238,7 @@ public class OPCUAClient : CollectBase
|
||||
return;
|
||||
}
|
||||
//尝试固定点位的数据类型
|
||||
var type = TypeInfo.GetSystemType(TypeInfo.GetBuiltInType(data.variableNode.DataType, PLC.Session.SystemContext.TypeTable), data.variableNode.ValueRank);
|
||||
var type = TypeInfo.GetSystemType(TypeInfo.GetBuiltInType(data.variableNode.DataType, _plc.Session.SystemContext.TypeTable), data.variableNode.ValueRank);
|
||||
|
||||
var itemReads = _deviceVariables.Where(it => it.VariableAddress == data.variableNode.NodeId).ToList();
|
||||
|
||||
@@ -266,8 +252,11 @@ public class OPCUAClient : CollectBase
|
||||
value = data.jToken;
|
||||
}
|
||||
var quality = StatusCode.IsGood(data.dataValue.StatusCode);
|
||||
|
||||
var time = data.dataValue.SourceTimestamp.ToLocalTime();
|
||||
DateTime time = default;
|
||||
if (driverPropertys.SourceTimestampEnable)
|
||||
{
|
||||
time = data.dataValue.SourceTimestamp.ToLocalTime();
|
||||
}
|
||||
foreach (var item in itemReads)
|
||||
{
|
||||
if (item.DataTypeEnum == DataTypeEnum.Object)
|
||||
@@ -296,4 +285,5 @@ public class OPCUAClient : CollectBase
|
||||
LogMessage?.LogWarning(ex, ToString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ using Newtonsoft.Json.Linq;
|
||||
using Opc.Ua;
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ThingsGateway.Admin.Blazor.Core;
|
||||
@@ -157,14 +158,19 @@ public partial class OPCUAClientDebugDriverPage
|
||||
{
|
||||
if (_plc.Connected)
|
||||
{
|
||||
var data = await _plc.WriteNodeAsync(defalutDebugDriverPage.Address, JToken.Parse(defalutDebugDriverPage.WriteValue));
|
||||
if (data.IsSuccess)
|
||||
var data = await _plc.WriteNodeAsync(
|
||||
new()
|
||||
{
|
||||
{ defalutDebugDriverPage.Address, JToken.Parse(defalutDebugDriverPage.WriteValue)}
|
||||
}
|
||||
);
|
||||
if (data.Values.FirstOrDefault().IsSuccess)
|
||||
{
|
||||
defalutDebugDriverPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + " - 写入成功"));
|
||||
}
|
||||
else
|
||||
{
|
||||
defalutDebugDriverPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + " - 写入失败 " + data.Message));
|
||||
defalutDebugDriverPage.Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + " - 写入失败 " + data.Values.FirstOrDefault().Message));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -43,6 +43,11 @@ public class OPCUAClientProperty : CollectDriverPropertyBase
|
||||
[DeviceProperty("安全策略", "True为使用安全策略,False为无")]
|
||||
public bool IsUseSecurity { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用SourceTime
|
||||
/// </summary>
|
||||
[DeviceProperty("使用SourceTime", "")]
|
||||
public bool SourceTimestampEnable { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 激活订阅
|
||||
|
||||
@@ -490,16 +490,22 @@ src.IsOnline ? StatusCodes.Good : StatusCodes.Bad);
|
||||
//仅当指定了值时才将值写入
|
||||
if (variable.Value != null)
|
||||
{
|
||||
var nv = new KeyValuePair<string, string>(variable.SymbolicName, value?.ToString());
|
||||
|
||||
var result = _rpcCore.InvokeDeviceMethodAsync("OPCUASERVER-" + context1?.OperationContext?.Session?.Identity?.DisplayName, nv).ConfigureAwait(true).GetAwaiter().GetResult();
|
||||
if (result.IsSuccess)
|
||||
var result = _rpcCore.InvokeDeviceMethodAsync("OPCUASERVER-" + context1?.OperationContext?.Session?.Identity?.DisplayName,
|
||||
new()
|
||||
{
|
||||
{ variable.SymbolicName, value?.ToString() }
|
||||
}
|
||||
|
||||
|
||||
).ConfigureAwait(true).GetAwaiter().GetResult();
|
||||
if (result.Values.FirstOrDefault().IsSuccess)
|
||||
{
|
||||
return StatusCodes.Good;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new(StatusCodes.BadWaitingForResponse, result.Message);
|
||||
return new(StatusCodes.BadWaitingForResponse, result.Values.FirstOrDefault().Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,6 @@
|
||||
OPCUA客户端
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.OPCUA.OPCUAClient.#ctor">
|
||||
<summary>
|
||||
OPCUA客户端
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.OPCUA.OPCUAClient.DriverDebugUIType">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -50,6 +45,9 @@
|
||||
<member name="P:ThingsGateway.OPCUA.OPCUAClient.ThingsGatewayBitConverter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.OPCUA.OPCUAClient.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.OPCUA.OPCUAClient.AfterStopAsync">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -68,7 +66,7 @@
|
||||
<member name="M:ThingsGateway.OPCUA.OPCUAClient.ReadSourceAsync(ThingsGateway.Application.DeviceVariableSourceRead,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.OPCUA.OPCUAClient.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<member name="M:ThingsGateway.OPCUA.OPCUAClient.WriteValuesAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.OPCUA.OPCUAClient.Dispose(System.Boolean)">
|
||||
@@ -142,6 +140,11 @@
|
||||
安全策略
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.OPCUA.OPCUAClientProperty.SourceTimestampEnable">
|
||||
<summary>
|
||||
是否使用SourceTime
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.OPCUA.OPCUAClientProperty.ActiveSubscribe">
|
||||
<summary>
|
||||
激活订阅
|
||||
|
||||
@@ -56,11 +56,13 @@ public class RabbitMQClientProperty : UpDriverPropertyBase
|
||||
/// </summary>
|
||||
[DeviceProperty("虚拟Host", "")]
|
||||
public string VirtualHost { get; set; } = ConnectionFactory.DefaultVHost;
|
||||
/// <summary>
|
||||
/// RoutingKey
|
||||
/// </summary>
|
||||
[DeviceProperty("路由名称", "")]
|
||||
public string RoutingKey { get; set; } = "TG";
|
||||
|
||||
///// <summary>
|
||||
///// RoutingKey
|
||||
///// </summary>
|
||||
//[DeviceProperty("路由名称", "")]
|
||||
//public string RoutingKey { get; set; } = "TG";
|
||||
|
||||
/// <summary>
|
||||
/// 交换机名称
|
||||
/// </summary>
|
||||
|
||||
@@ -85,11 +85,6 @@
|
||||
VirtualHost
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.RabbitMQ.RabbitMQClientProperty.RoutingKey">
|
||||
<summary>
|
||||
RoutingKey
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.RabbitMQ.RabbitMQClientProperty.ExchangeName">
|
||||
<summary>
|
||||
交换机名称
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -31,6 +29,8 @@ public abstract class Siemens : CollectBase
|
||||
/// PLC
|
||||
/// </summary>
|
||||
protected SiemensS7PLC _plc;
|
||||
/// <inheritdoc/>
|
||||
protected override IReadWriteDevice PLC => _plc;
|
||||
/// <summary>
|
||||
/// SiemensProperty
|
||||
/// </summary>
|
||||
@@ -124,11 +124,7 @@ public abstract class Siemens : CollectBase
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token)
|
||||
{
|
||||
return await _plc.WriteAsync(deviceVariable.VariableAddress, deviceVariable.DataType, value.ToString(), token);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
|
||||
@@ -88,6 +88,9 @@
|
||||
PLC
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:ThingsGateway.Siemens.Siemens.PLC">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:ThingsGateway.Siemens.Siemens.driverPropertys">
|
||||
<summary>
|
||||
SiemensProperty
|
||||
@@ -138,9 +141,6 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Siemens.Siemens.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:ThingsGateway.Siemens.Siemens.Dispose(System.Boolean)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
|
||||
@@ -84,11 +84,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThingsGateway.OPCUA", "Thin
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThingsGateway.Foundation.Adapter.OPCUA", "ThingsGateway.Plugin\Foundataion\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj", "{E1C327FA-C442-45DD-9265-9EA26573B61E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Foundataion.Demo", "Foundataion.Demo", "{E733E483-4823-4BD6-BC29-669426386A96}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModbusTest", "ThingsGateway.Plugin\Foundataion.ConsoleTests\ModbusTest\ModbusTest.csproj", "{BA2AC34C-F640-466E-B2CC-933A8658A16E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModbusDemo", "ThingsGateway.Plugin\Foundataion.Demo\ModbusDemo\ModbusDemo.csproj", "{48D2CA26-E535-413D-8CA9-A4A2AAC6582D}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlt645", "Dlt645", "{27B13F0D-2D0D-40C6-AC42-5F4B3BDE4A02}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OPCUAClientDemo", "ThingsGateway.Plugin\Foundataion.Demo\OPCUAClientDemo\OPCUAClientDemo.csproj", "{3F83EF0F-002D-4D06-87A8-739399074DBA}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DLT645Test", "ThingsGateway.Plugin\Foundataion.ConsoleTests\DLT645Test\DLT645Test.csproj", "{B9707E29-84E7-474A-8229-B203BC0DC392}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThingsGateway.Foundation.Adapter.DLT645", "ThingsGateway.Plugin\Foundataion\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj", "{D0B6D912-027D-451C-A8C8-ADC461F4AD99}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThingsGateway.DLT645", "ThingsGateway.Plugin\ThingsGateway.DLT645\ThingsGateway.DLT645.csproj", "{30A7CA70-DDC2-4E5E-8F70-1F2BECE61093}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OPCUAClientTest", "ThingsGateway.Plugin\Foundataion.ConsoleTests\OPCUAClientTest\OPCUAClientTest.csproj", "{0ABC8437-8489-4DE5-A7C6-1C2705D23D53}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -184,14 +190,26 @@ Global
|
||||
{E1C327FA-C442-45DD-9265-9EA26573B61E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E1C327FA-C442-45DD-9265-9EA26573B61E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E1C327FA-C442-45DD-9265-9EA26573B61E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{48D2CA26-E535-413D-8CA9-A4A2AAC6582D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{48D2CA26-E535-413D-8CA9-A4A2AAC6582D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{48D2CA26-E535-413D-8CA9-A4A2AAC6582D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{48D2CA26-E535-413D-8CA9-A4A2AAC6582D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3F83EF0F-002D-4D06-87A8-739399074DBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3F83EF0F-002D-4D06-87A8-739399074DBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3F83EF0F-002D-4D06-87A8-739399074DBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3F83EF0F-002D-4D06-87A8-739399074DBA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BA2AC34C-F640-466E-B2CC-933A8658A16E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BA2AC34C-F640-466E-B2CC-933A8658A16E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BA2AC34C-F640-466E-B2CC-933A8658A16E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BA2AC34C-F640-466E-B2CC-933A8658A16E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B9707E29-84E7-474A-8229-B203BC0DC392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B9707E29-84E7-474A-8229-B203BC0DC392}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B9707E29-84E7-474A-8229-B203BC0DC392}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B9707E29-84E7-474A-8229-B203BC0DC392}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D0B6D912-027D-451C-A8C8-ADC461F4AD99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D0B6D912-027D-451C-A8C8-ADC461F4AD99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D0B6D912-027D-451C-A8C8-ADC461F4AD99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D0B6D912-027D-451C-A8C8-ADC461F4AD99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{30A7CA70-DDC2-4E5E-8F70-1F2BECE61093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{30A7CA70-DDC2-4E5E-8F70-1F2BECE61093}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{30A7CA70-DDC2-4E5E-8F70-1F2BECE61093}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{30A7CA70-DDC2-4E5E-8F70-1F2BECE61093}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0ABC8437-8489-4DE5-A7C6-1C2705D23D53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0ABC8437-8489-4DE5-A7C6-1C2705D23D53}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0ABC8437-8489-4DE5-A7C6-1C2705D23D53}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0ABC8437-8489-4DE5-A7C6-1C2705D23D53}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -224,9 +242,12 @@ Global
|
||||
{F2DF3BE7-D497-44B3-9CD6-CDDBC4FBD09C} = {86119A5F-5717-42FF-8888-F034B4136A1B}
|
||||
{8F21F851-6AAE-4A78-9F11-D0EED0D3E9BE} = {F2DF3BE7-D497-44B3-9CD6-CDDBC4FBD09C}
|
||||
{E1C327FA-C442-45DD-9265-9EA26573B61E} = {F2DF3BE7-D497-44B3-9CD6-CDDBC4FBD09C}
|
||||
{E733E483-4823-4BD6-BC29-669426386A96} = {86119A5F-5717-42FF-8888-F034B4136A1B}
|
||||
{48D2CA26-E535-413D-8CA9-A4A2AAC6582D} = {E733E483-4823-4BD6-BC29-669426386A96}
|
||||
{3F83EF0F-002D-4D06-87A8-739399074DBA} = {E733E483-4823-4BD6-BC29-669426386A96}
|
||||
{BA2AC34C-F640-466E-B2CC-933A8658A16E} = {57BB8507-47A8-471E-BD16-19B7C82712E0}
|
||||
{27B13F0D-2D0D-40C6-AC42-5F4B3BDE4A02} = {86119A5F-5717-42FF-8888-F034B4136A1B}
|
||||
{B9707E29-84E7-474A-8229-B203BC0DC392} = {27B13F0D-2D0D-40C6-AC42-5F4B3BDE4A02}
|
||||
{D0B6D912-027D-451C-A8C8-ADC461F4AD99} = {27B13F0D-2D0D-40C6-AC42-5F4B3BDE4A02}
|
||||
{30A7CA70-DDC2-4E5E-8F70-1F2BECE61093} = {27B13F0D-2D0D-40C6-AC42-5F4B3BDE4A02}
|
||||
{0ABC8437-8489-4DE5-A7C6-1C2705D23D53} = {F2DF3BE7-D497-44B3-9CD6-CDDBC4FBD09C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {38B292E0-B3E7-4608-9912-1B057C2A508F}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import lunr from "E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\lunr\\lunr.js";
|
||||
require("E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\lunr-languages\\lunr.stemmer.support.js")(lunr);
|
||||
import lunr from "E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\lunr\\lunr.js";
|
||||
require("E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\lunr-languages\\lunr.stemmer.support.js")(lunr);
|
||||
require("@easyops-cn/docusaurus-search-local/dist/client/shared/lunrLanguageZh").lunrLanguageZh(lunr);
|
||||
require("E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\lunr-languages\\lunr.multi.js")(lunr);
|
||||
require("E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\lunr-languages\\lunr.multi.js")(lunr);
|
||||
export const language = ["en","zh"];
|
||||
export const removeDefaultStopWordFilter = false;
|
||||
export const removeDefaultStemmer = false;
|
||||
export { default as Mark } from "E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\mark.js\\dist\\mark.js"
|
||||
export const searchIndexUrl = "search-index{dir}.json?_=9bed4e05";
|
||||
export { default as Mark } from "E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\mark.js\\dist\\mark.js"
|
||||
export const searchIndexUrl = "search-index{dir}.json?_=04f8b93d";
|
||||
export const searchResultLimits = 8;
|
||||
export const searchResultContextMaxLength = 50;
|
||||
export const explicitSearchResultPath = true;
|
||||
|
||||
@@ -49,9 +49,6 @@
|
||||
532,
|
||||
4972
|
||||
],
|
||||
"25b34da0": [
|
||||
9974
|
||||
],
|
||||
"28e31f38": [
|
||||
2419
|
||||
],
|
||||
@@ -61,12 +58,18 @@
|
||||
"3546ab43": [
|
||||
9223
|
||||
],
|
||||
"39f79d48": [
|
||||
229
|
||||
],
|
||||
"40146f88": [
|
||||
7128
|
||||
],
|
||||
"43dc5fb8": [
|
||||
445
|
||||
],
|
||||
"444af13b": [
|
||||
4875
|
||||
],
|
||||
"49c09695": [
|
||||
7929
|
||||
],
|
||||
@@ -105,6 +108,9 @@
|
||||
"74e9e182": [
|
||||
2274
|
||||
],
|
||||
"760264af": [
|
||||
6373
|
||||
],
|
||||
"76f0de82": [
|
||||
1717
|
||||
],
|
||||
@@ -148,14 +154,14 @@
|
||||
"abad1c1c": [
|
||||
6950
|
||||
],
|
||||
"c361d1eb": [
|
||||
8175
|
||||
],
|
||||
"c4f5d8e4": [
|
||||
532,
|
||||
9523,
|
||||
4195
|
||||
],
|
||||
"c776f548": [
|
||||
9735
|
||||
],
|
||||
"ca43e8da": [
|
||||
359
|
||||
],
|
||||
@@ -165,9 +171,6 @@
|
||||
"daef9133": [
|
||||
8821
|
||||
],
|
||||
"e34e66ef": [
|
||||
6622
|
||||
],
|
||||
"e58d351b": [
|
||||
9708
|
||||
],
|
||||
@@ -203,45 +206,54 @@
|
||||
"53": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/935f2afb.0f7e606f.js",
|
||||
"hash": "481ecc5141990b51",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/935f2afb.0f7e606f.js"
|
||||
"file": "assets/js/935f2afb.a45d7d7b.js",
|
||||
"hash": "b573fe1a5062db80",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/935f2afb.a45d7d7b.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"87": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/196f2029.09e70668.js",
|
||||
"hash": "15c3c1e63783865b",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/196f2029.09e70668.js"
|
||||
"file": "assets/js/196f2029.36590c94.js",
|
||||
"hash": "7ad3f212d29df7a4",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/196f2029.36590c94.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"179": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/main.fe6ca657.js",
|
||||
"hash": "35b596252fb7aae3",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/main.fe6ca657.js"
|
||||
"file": "assets/js/main.1a3e0b01.js",
|
||||
"hash": "7935904a336f6180",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/main.1a3e0b01.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"229": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/39f79d48.84084807.js",
|
||||
"hash": "96fa19b68e78a88f",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/39f79d48.84084807.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"359": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/ca43e8da.f7ea75f9.js",
|
||||
"hash": "cd4e7aa6d047a3a5",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/ca43e8da.f7ea75f9.js"
|
||||
"file": "assets/js/ca43e8da.52aea27e.js",
|
||||
"hash": "9e7c6f71b5089e85",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/ca43e8da.52aea27e.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"445": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/43dc5fb8.f1e80e98.js",
|
||||
"hash": "c2db873bc6803de1",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/43dc5fb8.f1e80e98.js"
|
||||
"file": "assets/js/43dc5fb8.36fb169c.js",
|
||||
"hash": "21315583cf077da2",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/43dc5fb8.36fb169c.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -257,9 +269,9 @@
|
||||
"551": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/5f324ac5.025c2bbe.js",
|
||||
"hash": "2297ba12361ba4c7",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/5f324ac5.025c2bbe.js"
|
||||
"file": "assets/js/5f324ac5.6c44ed2f.js",
|
||||
"hash": "56afeb3fa211a01b",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/5f324ac5.6c44ed2f.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -267,7 +279,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/e86f980e.ad719727.js",
|
||||
"hash": "8577b2eeb8b9c2af",
|
||||
"hash": "20373a4461873377",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/e86f980e.ad719727.js"
|
||||
}
|
||||
]
|
||||
@@ -276,7 +288,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/8e930223.9f8a8e14.js",
|
||||
"hash": "a749693bf0e5f475",
|
||||
"hash": "5ebed98490f060e8",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/8e930223.9f8a8e14.js"
|
||||
}
|
||||
]
|
||||
@@ -284,36 +296,36 @@
|
||||
"1303": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/runtime~main.998dd168.js",
|
||||
"hash": "0b2c7ad12b62da0f",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/runtime~main.998dd168.js"
|
||||
"file": "assets/js/runtime~main.2e8ac0c4.js",
|
||||
"hash": "5ceb0500debc54bc",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/runtime~main.2e8ac0c4.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"1518": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/7bbbeda9.859b440a.js",
|
||||
"hash": "f9d4ff8017e8f476",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/7bbbeda9.859b440a.js"
|
||||
"file": "assets/js/7bbbeda9.fcf3209c.js",
|
||||
"hash": "64633c4a172c4cee",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/7bbbeda9.fcf3209c.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"1717": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/76f0de82.92c390d3.js",
|
||||
"hash": "ba1a3c91e41f43ea",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/76f0de82.92c390d3.js"
|
||||
"file": "assets/js/76f0de82.3bc61a08.js",
|
||||
"hash": "e80793f5114b6a26",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/76f0de82.3bc61a08.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"1822": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/f05a39b7.c2e6a6b0.js",
|
||||
"hash": "dbe13230a95c8ad3",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/f05a39b7.c2e6a6b0.js"
|
||||
"file": "assets/js/f05a39b7.1a2db08f.js",
|
||||
"hash": "25429336b0e231c1",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/f05a39b7.1a2db08f.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -321,7 +333,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/8aa4b8ad.fcf68c5f.js",
|
||||
"hash": "6e6d95bb0337d848",
|
||||
"hash": "b9ad8051f3d1d01c",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/8aa4b8ad.fcf68c5f.js"
|
||||
}
|
||||
]
|
||||
@@ -329,18 +341,18 @@
|
||||
"2247": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/5178350f.7bc23f43.js",
|
||||
"hash": "cd590c5f24b80417",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/5178350f.7bc23f43.js"
|
||||
"file": "assets/js/5178350f.a6cdc43d.js",
|
||||
"hash": "ed73bd243cd4cf99",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/5178350f.a6cdc43d.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"2274": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/74e9e182.80f78b97.js",
|
||||
"hash": "19d794c5860f28cf",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/74e9e182.80f78b97.js"
|
||||
"file": "assets/js/74e9e182.0cc07587.js",
|
||||
"hash": "66398711077dcfc7",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/74e9e182.0cc07587.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -348,7 +360,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/8ced3e65.1dd2c110.js",
|
||||
"hash": "be3ef514c9db8807",
|
||||
"hash": "e607b67dee492e4d",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/8ced3e65.1dd2c110.js"
|
||||
}
|
||||
]
|
||||
@@ -356,18 +368,18 @@
|
||||
"2419": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/28e31f38.c31224e9.js",
|
||||
"hash": "6849b27ef2c646fe",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/28e31f38.c31224e9.js"
|
||||
"file": "assets/js/28e31f38.c9b15f29.js",
|
||||
"hash": "d6755af997ee5668",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/28e31f38.c9b15f29.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"2982": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/637a4551.60e25ce1.js",
|
||||
"hash": "afbb29651ccb1b09",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/637a4551.60e25ce1.js"
|
||||
"file": "assets/js/637a4551.f0c0e2be.js",
|
||||
"hash": "a92c64b969fd0c24",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/637a4551.f0c0e2be.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -375,7 +387,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/8fb2cb35.1e565465.js",
|
||||
"hash": "a070e26df25a6b04",
|
||||
"hash": "d7d8f2c602953c86",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/8fb2cb35.1e565465.js"
|
||||
}
|
||||
]
|
||||
@@ -383,36 +395,36 @@
|
||||
"3371": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/d22033f9.bac63b20.js",
|
||||
"hash": "7ae14dd99b920d97",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/d22033f9.bac63b20.js"
|
||||
"file": "assets/js/d22033f9.c4eda647.js",
|
||||
"hash": "829f6d54a273a13d",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/d22033f9.c4eda647.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"3381": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/6a68bc41.33a46316.js",
|
||||
"hash": "5f7b4fb8b6850264",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/6a68bc41.33a46316.js"
|
||||
"file": "assets/js/6a68bc41.ff2e546e.js",
|
||||
"hash": "4f88d4c13c8cf94e",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/6a68bc41.ff2e546e.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"3477": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/f22f9b4f.67005bc0.js",
|
||||
"hash": "f932b4666288b332",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/f22f9b4f.67005bc0.js"
|
||||
"file": "assets/js/f22f9b4f.55821957.js",
|
||||
"hash": "931dbf0b5b4101df",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/f22f9b4f.55821957.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"4124": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/56125fde.93b0521c.js",
|
||||
"hash": "81a659346e3c3446",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/56125fde.93b0521c.js"
|
||||
"file": "assets/js/56125fde.58745ef5.js",
|
||||
"hash": "faad286e7527652e",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/56125fde.58745ef5.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -420,7 +432,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/0af5a0e2.281490de.js",
|
||||
"hash": "eb4dfacb0b43f43b",
|
||||
"hash": "116e6ccc2fca551a",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/0af5a0e2.281490de.js"
|
||||
}
|
||||
]
|
||||
@@ -429,17 +441,26 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/c4f5d8e4.fe5b6306.js",
|
||||
"hash": "57fb9735bba4d65f",
|
||||
"hash": "5a0f4090e4e84cc6",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/c4f5d8e4.fe5b6306.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"4875": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/444af13b.aeeda19d.js",
|
||||
"hash": "99c5763bf6442fd0",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/444af13b.aeeda19d.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"4954": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/6f635a3d.034ef8a0.js",
|
||||
"hash": "f7af1b4b22b00fbe",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/6f635a3d.034ef8a0.js"
|
||||
"file": "assets/js/6f635a3d.1303d271.js",
|
||||
"hash": "6d80cef34ec86082",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/6f635a3d.1303d271.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -452,7 +473,7 @@
|
||||
},
|
||||
{
|
||||
"file": "assets/js/1be78505.4c7d94a8.js",
|
||||
"hash": "74e2c35eb8a954c9",
|
||||
"hash": "c7395c13c7c8decc",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/1be78505.4c7d94a8.js"
|
||||
}
|
||||
]
|
||||
@@ -470,26 +491,26 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/85214b50.5f392e5f.js",
|
||||
"hash": "223000de0037d179",
|
||||
"hash": "e18493e6324956c7",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/85214b50.5f392e5f.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"6622": {
|
||||
"6373": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/e34e66ef.9f892370.js",
|
||||
"hash": "9ac80b6994c5ce8b",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/e34e66ef.9f892370.js"
|
||||
"file": "assets/js/760264af.e41efc53.js",
|
||||
"hash": "782b1e0bb49755e1",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/760264af.e41efc53.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"6815": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/6b5f52c5.3f44288c.js",
|
||||
"hash": "15f107cdcab2d783",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/6b5f52c5.3f44288c.js"
|
||||
"file": "assets/js/6b5f52c5.e7d41230.js",
|
||||
"hash": "6242596fa31dd1da",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/6b5f52c5.e7d41230.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -497,7 +518,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/abad1c1c.3a5c2084.js",
|
||||
"hash": "2e9ac1ad7a3ce9a7",
|
||||
"hash": "3ba1098d05d3cb61",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/abad1c1c.3a5c2084.js"
|
||||
}
|
||||
]
|
||||
@@ -505,18 +526,18 @@
|
||||
"7128": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/40146f88.2945f8c6.js",
|
||||
"hash": "84b5201e71d61bb5",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/40146f88.2945f8c6.js"
|
||||
"file": "assets/js/40146f88.02aef490.js",
|
||||
"hash": "9866a7ec0620f243",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/40146f88.02aef490.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"7542": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/e80564fa.d64afbda.js",
|
||||
"hash": "0421dd7917c2eda6",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/e80564fa.d64afbda.js"
|
||||
"file": "assets/js/e80564fa.d689a929.js",
|
||||
"hash": "ddd73732d07c3d60",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/e80564fa.d689a929.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -524,7 +545,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/17896441.9c2ea4c3.js",
|
||||
"hash": "60af9bef9e339c2d",
|
||||
"hash": "dc4a3a9e76c5b733",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/17896441.9c2ea4c3.js"
|
||||
}
|
||||
]
|
||||
@@ -542,17 +563,26 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/49c09695.8740c687.js",
|
||||
"hash": "be27f7230a995d99",
|
||||
"hash": "7593d8d3aca3809a",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/49c09695.8740c687.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"8175": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/c361d1eb.73ec1548.js",
|
||||
"hash": "b41c626f8014c5d2",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/c361d1eb.73ec1548.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"8254": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/a81fc991.4885b391.js",
|
||||
"hash": "d14250a981eba937",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/a81fc991.4885b391.js"
|
||||
"file": "assets/js/a81fc991.90b7bed8.js",
|
||||
"hash": "07a8f8823084a06b",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/a81fc991.90b7bed8.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -568,18 +598,18 @@
|
||||
"8494": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/5137840a.efbb9425.js",
|
||||
"hash": "b288804baeb0408d",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/5137840a.efbb9425.js"
|
||||
"file": "assets/js/5137840a.7e49d21e.js",
|
||||
"hash": "446d0bcbfbaecac3",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/5137840a.7e49d21e.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"8707": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/4c79e569.2be1cc3a.js",
|
||||
"hash": "a853fcd49ab35c08",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/4c79e569.2be1cc3a.js"
|
||||
"file": "assets/js/4c79e569.3f1e7d8c.js",
|
||||
"hash": "b39f8286cf1673d6",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/4c79e569.3f1e7d8c.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -587,7 +617,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/daef9133.ed8f7f40.js",
|
||||
"hash": "5fc3e033f2c7caec",
|
||||
"hash": "65a6ffdd7e891d84",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/daef9133.ed8f7f40.js"
|
||||
}
|
||||
]
|
||||
@@ -596,7 +626,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/ab798fff.f80365cf.js",
|
||||
"hash": "a850ad9b59d4b9f7",
|
||||
"hash": "f5c1f662f375150b",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/ab798fff.f80365cf.js"
|
||||
}
|
||||
]
|
||||
@@ -605,7 +635,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/9da45bac.a2fea472.js",
|
||||
"hash": "e5b359fc4ce74dcf",
|
||||
"hash": "9e2aa3733970cb63",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/9da45bac.a2fea472.js"
|
||||
}
|
||||
]
|
||||
@@ -613,18 +643,18 @@
|
||||
"9223": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/3546ab43.d3d1d40f.js",
|
||||
"hash": "7137b17055b91d8b",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/3546ab43.d3d1d40f.js"
|
||||
"file": "assets/js/3546ab43.8b6d0ce2.js",
|
||||
"hash": "59275babd7a462ca",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/3546ab43.8b6d0ce2.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"9313": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/7a4cde18.3223c051.js",
|
||||
"hash": "fba54d7be26cb459",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/7a4cde18.3223c051.js"
|
||||
"file": "assets/js/7a4cde18.53da6bd5.js",
|
||||
"hash": "776334f330953d3e",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/7a4cde18.53da6bd5.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -632,7 +662,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/4c99e3f0.88565af8.js",
|
||||
"hash": "4c77befdbbf9011d",
|
||||
"hash": "0825c22372539410",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/4c99e3f0.88565af8.js"
|
||||
}
|
||||
]
|
||||
@@ -641,7 +671,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/a426a3b5.816a1a92.js",
|
||||
"hash": "3507204ea5d80651",
|
||||
"hash": "466f0fa0f4a9e4ec",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/a426a3b5.816a1a92.js"
|
||||
}
|
||||
]
|
||||
@@ -650,7 +680,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/9523.37750895.js",
|
||||
"hash": "01a1742e7b227a09",
|
||||
"hash": "7232611dac636c65",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/9523.37750895.js"
|
||||
}
|
||||
]
|
||||
@@ -659,7 +689,7 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/2bc68b86.e769c1d6.js",
|
||||
"hash": "307b4639ba5eae9a",
|
||||
"hash": "09a07fc94423623e",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/2bc68b86.e769c1d6.js"
|
||||
}
|
||||
]
|
||||
@@ -668,28 +698,10 @@
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/e58d351b.64d2c68b.js",
|
||||
"hash": "40814e1fd44440ae",
|
||||
"hash": "dbe3210d148bff23",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/e58d351b.64d2c68b.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"9735": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/c776f548.8b835810.js",
|
||||
"hash": "ab7683c26c772fc6",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/c776f548.8b835810.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"9974": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/25b34da0.c091df34.js",
|
||||
"hash": "afcfb4889b16d399",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/25b34da0.c091df34.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
export default [
|
||||
require('E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\infima\\dist\\css\\default\\default.css'),
|
||||
require('E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\@docusaurus\\theme-classic\\lib\\prism-include-languages'),
|
||||
require('E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\@docusaurus\\theme-classic\\lib\\nprogress'),
|
||||
require('E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\src\\css\\custom.css'),
|
||||
require('E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\docusaurus-plugin-image-zoom\\src\\zoom'),
|
||||
require('E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\infima\\dist\\css\\default\\default.css'),
|
||||
require('E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\@docusaurus\\theme-classic\\lib\\prism-include-languages'),
|
||||
require('E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\@docusaurus\\theme-classic\\lib\\nprogress'),
|
||||
require('E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\src\\css\\custom.css'),
|
||||
require('E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\docusaurus-plugin-image-zoom\\src\\zoom'),
|
||||
];
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
"editUrl": "https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/description.mdx",
|
||||
"tags": [],
|
||||
"version": "current",
|
||||
"lastUpdatedBy": "2248356998 qq.com",
|
||||
"lastUpdatedAt": 1689499706,
|
||||
"formattedLastUpdatedAt": "Jul 16, 2023",
|
||||
"lastUpdatedBy": "Kimdiego2098",
|
||||
"lastUpdatedAt": 1691401133,
|
||||
"formattedLastUpdatedAt": "Aug 7, 2023",
|
||||
"frontMatter": {
|
||||
"id": "description",
|
||||
"title": "说明",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"tags": [],
|
||||
"version": "current",
|
||||
"lastUpdatedBy": "Kimdiego2098",
|
||||
"lastUpdatedAt": 1691392193,
|
||||
"lastUpdatedAt": 1691401133,
|
||||
"formattedLastUpdatedAt": "Aug 7, 2023",
|
||||
"frontMatter": {
|
||||
"id": "modbus",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"permalink": "/thingsgateway-docs/docs/pluginvigorvs"
|
||||
},
|
||||
"next": {
|
||||
"title": "OPCUAServer",
|
||||
"permalink": "/thingsgateway-docs/docs/pluginopcuaserver"
|
||||
"title": "DLT645-2007采集插件",
|
||||
"permalink": "/thingsgateway-docs/docs/plugindlt6452007"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"unversionedId": "plugindlt6452007",
|
||||
"id": "plugindlt6452007",
|
||||
"title": "DLT645-2007采集插件",
|
||||
"description": "一、设备扩展属性",
|
||||
"source": "@site/docs/plugindlt6452007.mdx",
|
||||
"sourceDirName": ".",
|
||||
"slug": "/plugindlt6452007",
|
||||
"permalink": "/thingsgateway-docs/docs/plugindlt6452007",
|
||||
"draft": false,
|
||||
"editUrl": "https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/plugindlt6452007.mdx",
|
||||
"tags": [],
|
||||
"version": "current",
|
||||
"frontMatter": {
|
||||
"id": "plugindlt6452007",
|
||||
"title": "DLT645-2007采集插件"
|
||||
},
|
||||
"sidebar": "docs",
|
||||
"previous": {
|
||||
"title": "罗克韦尔CIP协议采集插件",
|
||||
"permalink": "/thingsgateway-docs/docs/pluginabcip"
|
||||
},
|
||||
"next": {
|
||||
"title": "OPCUAServer",
|
||||
"permalink": "/thingsgateway-docs/docs/pluginopcuaserver"
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
"tags": [],
|
||||
"version": "current",
|
||||
"lastUpdatedBy": "Kimdiego2098",
|
||||
"lastUpdatedAt": 1689760951,
|
||||
"formattedLastUpdatedAt": "Jul 19, 2023",
|
||||
"lastUpdatedAt": 1692678105,
|
||||
"formattedLastUpdatedAt": "Aug 22, 2023",
|
||||
"frontMatter": {
|
||||
"id": "pluginmqttserver",
|
||||
"title": "MqttServer"
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
},
|
||||
"sidebar": "docs",
|
||||
"previous": {
|
||||
"title": "罗克韦尔CIP协议采集插件",
|
||||
"permalink": "/thingsgateway-docs/docs/pluginabcip"
|
||||
"title": "DLT645-2007采集插件",
|
||||
"permalink": "/thingsgateway-docs/docs/plugindlt6452007"
|
||||
},
|
||||
"next": {
|
||||
"title": "ModbusServer",
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"editUrl": "https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/upgrade.mdx",
|
||||
"tags": [],
|
||||
"version": "current",
|
||||
"lastUpdatedBy": "Kimdiego2098",
|
||||
"lastUpdatedAt": 1691392193,
|
||||
"lastUpdatedBy": "Diego2098",
|
||||
"lastUpdatedAt": 1691418711,
|
||||
"formattedLastUpdatedAt": "Aug 7, 2023",
|
||||
"frontMatter": {
|
||||
"id": "upgrade",
|
||||
|
||||
@@ -206,6 +206,12 @@
|
||||
"label": "9.6 罗克韦尔CIP",
|
||||
"href": "/thingsgateway-docs/docs/pluginabcip",
|
||||
"docId": "pluginabcip"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"label": "9.7 DLT645_2007",
|
||||
"href": "/thingsgateway-docs/docs/plugindlt6452007",
|
||||
"docId": "plugindlt6452007"
|
||||
}
|
||||
],
|
||||
"collapsed": true,
|
||||
@@ -441,6 +447,12 @@
|
||||
"description": "一、选择驱动插件",
|
||||
"sidebar": "docs"
|
||||
},
|
||||
"plugindlt6452007": {
|
||||
"id": "plugindlt6452007",
|
||||
"title": "DLT645-2007采集插件",
|
||||
"description": "一、设备扩展属性",
|
||||
"sidebar": "docs"
|
||||
},
|
||||
"pluginkafka": {
|
||||
"id": "pluginkafka",
|
||||
"title": "Kafka消息生产",
|
||||
|
||||
@@ -276,7 +276,7 @@ export default {
|
||||
"@docusaurus/preset-classic",
|
||||
{
|
||||
"docs": {
|
||||
"sidebarPath": "E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\sidebars.js",
|
||||
"sidebarPath": "E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\sidebars.js",
|
||||
"editUrl": "https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/",
|
||||
"showLastUpdateTime": true,
|
||||
"showLastUpdateAuthor": true,
|
||||
@@ -284,13 +284,13 @@ export default {
|
||||
"sidebarCollapsed": true
|
||||
},
|
||||
"theme": {
|
||||
"customCss": "E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\src\\css\\custom.css"
|
||||
"customCss": "E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\src\\css\\custom.css"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": [
|
||||
"E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\node_modules\\docusaurus-plugin-image-zoom\\src\\index.js"
|
||||
"E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\node_modules\\docusaurus-plugin-image-zoom\\src\\index.js"
|
||||
],
|
||||
"themes": [
|
||||
[
|
||||
|
||||
@@ -110,6 +110,11 @@
|
||||
"path": "/thingsgateway-docs/docs/plugindebug",
|
||||
"sidebar": "docs"
|
||||
},
|
||||
{
|
||||
"id": "plugindlt6452007",
|
||||
"path": "/thingsgateway-docs/docs/plugindlt6452007",
|
||||
"sidebar": "docs"
|
||||
},
|
||||
{
|
||||
"id": "pluginkafka",
|
||||
"path": "/thingsgateway-docs/docs/pluginkafka",
|
||||
|
||||
@@ -4,12 +4,13 @@ export default {
|
||||
'196f2029': [() => import(/* webpackChunkName: '196f2029' */ '@site/docs/pluginopcuaserver.mdx'), '@site/docs/pluginopcuaserver.mdx', require.resolveWeak('@site/docs/pluginopcuaserver.mdx')],
|
||||
'1a4e3797': [() => import(/* webpackChunkName: '1a4e3797' */ '@theme/SearchPage'), '@theme/SearchPage', require.resolveWeak('@theme/SearchPage')],
|
||||
'1be78505': [() => import(/* webpackChunkName: '1be78505' */ '@theme/DocPage'), '@theme/DocPage', require.resolveWeak('@theme/DocPage')],
|
||||
'25b34da0': [() => import(/* webpackChunkName: '25b34da0' */ 'E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\@easyops-cn\\docusaurus-search-local\\default\\plugin-route-context-module-100.json'), 'E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\@easyops-cn\\docusaurus-search-local\\default\\plugin-route-context-module-100.json', require.resolveWeak('E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\@easyops-cn\\docusaurus-search-local\\default\\plugin-route-context-module-100.json')],
|
||||
'28e31f38': [() => import(/* webpackChunkName: '28e31f38' */ '@site/docs/hardwareinfo.mdx'), '@site/docs/hardwareinfo.mdx', require.resolveWeak('@site/docs/hardwareinfo.mdx')],
|
||||
'2bc68b86': [() => import(/* webpackChunkName: '2bc68b86' */ '@site/docs/uploaddevice.mdx'), '@site/docs/uploaddevice.mdx', require.resolveWeak('@site/docs/uploaddevice.mdx')],
|
||||
'3546ab43': [() => import(/* webpackChunkName: '3546ab43' */ '@site/docs/memoryvariable.mdx'), '@site/docs/memoryvariable.mdx', require.resolveWeak('@site/docs/memoryvariable.mdx')],
|
||||
'39f79d48': [() => import(/* webpackChunkName: '39f79d48' */ '@site/docs/plugindlt6452007.mdx'), '@site/docs/plugindlt6452007.mdx', require.resolveWeak('@site/docs/plugindlt6452007.mdx')],
|
||||
'40146f88': [() => import(/* webpackChunkName: '40146f88' */ '@site/docs/hisdata.mdx'), '@site/docs/hisdata.mdx', require.resolveWeak('@site/docs/hisdata.mdx')],
|
||||
'43dc5fb8': [() => import(/* webpackChunkName: '43dc5fb8' */ '@site/docs/hisalarm.mdx'), '@site/docs/hisalarm.mdx', require.resolveWeak('@site/docs/hisalarm.mdx')],
|
||||
'444af13b': [() => import(/* webpackChunkName: '444af13b' */ 'E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\@easyops-cn\\docusaurus-search-local\\default\\plugin-route-context-module-100.json'), 'E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\@easyops-cn\\docusaurus-search-local\\default\\plugin-route-context-module-100.json', require.resolveWeak('E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\@easyops-cn\\docusaurus-search-local\\default\\plugin-route-context-module-100.json')],
|
||||
'49c09695': [() => import(/* webpackChunkName: '49c09695' */ '@site/docs/pluginrabbitmqclient.mdx'), '@site/docs/pluginrabbitmqclient.mdx', require.resolveWeak('@site/docs/pluginrabbitmqclient.mdx')],
|
||||
'4c79e569': [() => import(/* webpackChunkName: '4c79e569' */ '@site/docs/upgrade.mdx'), '@site/docs/upgrade.mdx', require.resolveWeak('@site/docs/upgrade.mdx')],
|
||||
'4c99e3f0': [() => import(/* webpackChunkName: '4c99e3f0' */ '@site/docs/pluginkafka.mdx'), '@site/docs/pluginkafka.mdx', require.resolveWeak('@site/docs/pluginkafka.mdx')],
|
||||
@@ -23,6 +24,7 @@ export default {
|
||||
'6b5f52c5': [() => import(/* webpackChunkName: '6b5f52c5' */ '@site/docs/collectdevice.mdx'), '@site/docs/collectdevice.mdx', require.resolveWeak('@site/docs/collectdevice.mdx')],
|
||||
'6f635a3d': [() => import(/* webpackChunkName: '6f635a3d' */ '@site/docs/foundation/modbus.mdx'), '@site/docs/foundation/modbus.mdx', require.resolveWeak('@site/docs/foundation/modbus.mdx')],
|
||||
'74e9e182': [() => import(/* webpackChunkName: '74e9e182' */ '@site/docs/backendlog.mdx'), '@site/docs/backendlog.mdx', require.resolveWeak('@site/docs/backendlog.mdx')],
|
||||
'760264af': [() => import(/* webpackChunkName: '760264af' */ 'E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-pages\\default\\plugin-route-context-module-100.json'), 'E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-pages\\default\\plugin-route-context-module-100.json', require.resolveWeak('E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-pages\\default\\plugin-route-context-module-100.json')],
|
||||
'76f0de82': [() => import(/* webpackChunkName: '76f0de82' */ '@site/docs/otherconfig.mdx'), '@site/docs/otherconfig.mdx', require.resolveWeak('@site/docs/otherconfig.mdx')],
|
||||
'7a4cde18': [() => import(/* webpackChunkName: '7a4cde18' */ '@site/docs/otherpage.mdx'), '@site/docs/otherpage.mdx', require.resolveWeak('@site/docs/otherpage.mdx')],
|
||||
'7bbbeda9': [() => import(/* webpackChunkName: '7bbbeda9' */ '@site/docs/realalarm.mdx'), '@site/docs/realalarm.mdx', require.resolveWeak('@site/docs/realalarm.mdx')],
|
||||
@@ -37,12 +39,11 @@ export default {
|
||||
'a81fc991': [() => import(/* webpackChunkName: 'a81fc991' */ '@site/docs/pluginmqttclient.mdx'), '@site/docs/pluginmqttclient.mdx', require.resolveWeak('@site/docs/pluginmqttclient.mdx')],
|
||||
'ab798fff': [() => import(/* webpackChunkName: 'ab798fff' */ '@site/docs/foundation/opcua.mdx'), '@site/docs/foundation/opcua.mdx', require.resolveWeak('@site/docs/foundation/opcua.mdx')],
|
||||
'abad1c1c': [() => import(/* webpackChunkName: 'abad1c1c' */ '@site/docs/pluginopcuaclient.mdx'), '@site/docs/pluginopcuaclient.mdx', require.resolveWeak('@site/docs/pluginopcuaclient.mdx')],
|
||||
'c361d1eb': [() => import(/* webpackChunkName: 'c361d1eb' */ 'E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-docs\\default\\plugin-route-context-module-100.json'), 'E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-docs\\default\\plugin-route-context-module-100.json', require.resolveWeak('E:\\Tg\\ThingsGateway\\ThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-docs\\default\\plugin-route-context-module-100.json')],
|
||||
'c4f5d8e4': [() => import(/* webpackChunkName: 'c4f5d8e4' */ '@site/src/pages/index.js'), '@site/src/pages/index.js', require.resolveWeak('@site/src/pages/index.js')],
|
||||
'c776f548': [() => import(/* webpackChunkName: 'c776f548' */ 'E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-pages\\default\\plugin-route-context-module-100.json'), 'E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-pages\\default\\plugin-route-context-module-100.json', require.resolveWeak('E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-pages\\default\\plugin-route-context-module-100.json')],
|
||||
'ca43e8da': [() => import(/* webpackChunkName: 'ca43e8da' */ '@site/docs/pluginconfig.mdx'), '@site/docs/pluginconfig.mdx', require.resolveWeak('@site/docs/pluginconfig.mdx')],
|
||||
'd22033f9': [() => import(/* webpackChunkName: 'd22033f9' */ '@site/docs/donate.mdx'), '@site/docs/donate.mdx', require.resolveWeak('@site/docs/donate.mdx')],
|
||||
'daef9133': [() => import(/* webpackChunkName: 'daef9133' */ '@site/docs/pluginvigorvs.mdx'), '@site/docs/pluginvigorvs.mdx', require.resolveWeak('@site/docs/pluginvigorvs.mdx')],
|
||||
'e34e66ef': [() => import(/* webpackChunkName: 'e34e66ef' */ 'E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-docs\\default\\plugin-route-context-module-100.json'), 'E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-docs\\default\\plugin-route-context-module-100.json', require.resolveWeak('E:\\Tg\\ThingsGateway\\NewThingsGateway\\handbook\\.docusaurus\\docusaurus-plugin-content-docs\\default\\plugin-route-context-module-100.json')],
|
||||
'e58d351b': [() => import(/* webpackChunkName: 'e58d351b' */ '@site/docs/windowsrelease.mdx'), '@site/docs/windowsrelease.mdx', require.resolveWeak('@site/docs/windowsrelease.mdx')],
|
||||
'e80564fa': [() => import(/* webpackChunkName: 'e80564fa' */ '@site/docs/pluginabcip.mdx'), '@site/docs/pluginabcip.mdx', require.resolveWeak('@site/docs/pluginabcip.mdx')],
|
||||
'e86f980e': [() => import(/* webpackChunkName: 'e86f980e' */ '@site/docs/pluginopcdaclient.mdx'), '@site/docs/pluginopcdaclient.mdx', require.resolveWeak('@site/docs/pluginopcdaclient.mdx')],
|
||||
|
||||
@@ -4,12 +4,12 @@ import ComponentCreator from '@docusaurus/ComponentCreator';
|
||||
export default [
|
||||
{
|
||||
path: '/thingsgateway-docs/search',
|
||||
component: ComponentCreator('/thingsgateway-docs/search', 'ca8'),
|
||||
component: ComponentCreator('/thingsgateway-docs/search', '738'),
|
||||
exact: true
|
||||
},
|
||||
{
|
||||
path: '/thingsgateway-docs/docs',
|
||||
component: ComponentCreator('/thingsgateway-docs/docs', '8b2'),
|
||||
component: ComponentCreator('/thingsgateway-docs/docs', '688'),
|
||||
routes: [
|
||||
{
|
||||
path: '/thingsgateway-docs/docs/',
|
||||
@@ -131,6 +131,12 @@ export default [
|
||||
exact: true,
|
||||
sidebar: "docs"
|
||||
},
|
||||
{
|
||||
path: '/thingsgateway-docs/docs/plugindlt6452007',
|
||||
component: ComponentCreator('/thingsgateway-docs/docs/plugindlt6452007', 'a37'),
|
||||
exact: true,
|
||||
sidebar: "docs"
|
||||
},
|
||||
{
|
||||
path: '/thingsgateway-docs/docs/pluginkafka',
|
||||
component: ComponentCreator('/thingsgateway-docs/docs/pluginkafka', '6c4'),
|
||||
@@ -255,7 +261,7 @@ export default [
|
||||
},
|
||||
{
|
||||
path: '/thingsgateway-docs/',
|
||||
component: ComponentCreator('/thingsgateway-docs/', 'fc9'),
|
||||
component: ComponentCreator('/thingsgateway-docs/', '8e0'),
|
||||
exact: true
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"/thingsgateway-docs/search-ca8": {
|
||||
"/thingsgateway-docs/search-738": {
|
||||
"__comp": "1a4e3797",
|
||||
"__context": {
|
||||
"plugin": "25b34da0"
|
||||
"plugin": "444af13b"
|
||||
}
|
||||
},
|
||||
"/thingsgateway-docs/docs-8b2": {
|
||||
"/thingsgateway-docs/docs-688": {
|
||||
"__comp": "1be78505",
|
||||
"__context": {
|
||||
"plugin": "e34e66ef"
|
||||
"plugin": "c361d1eb"
|
||||
},
|
||||
"versionMetadata": "935f2afb"
|
||||
},
|
||||
@@ -92,6 +92,10 @@
|
||||
"__comp": "17896441",
|
||||
"content": "56125fde"
|
||||
},
|
||||
"/thingsgateway-docs/docs/plugindlt6452007-a37": {
|
||||
"__comp": "17896441",
|
||||
"content": "39f79d48"
|
||||
},
|
||||
"/thingsgateway-docs/docs/pluginkafka-6c4": {
|
||||
"__comp": "17896441",
|
||||
"content": "4c99e3f0"
|
||||
@@ -172,10 +176,10 @@
|
||||
"__comp": "17896441",
|
||||
"content": "e58d351b"
|
||||
},
|
||||
"/thingsgateway-docs/-fc9": {
|
||||
"/thingsgateway-docs/-8e0": {
|
||||
"__comp": "c4f5d8e4",
|
||||
"__context": {
|
||||
"plugin": "c776f548"
|
||||
"plugin": "760264af"
|
||||
},
|
||||
"config": "5e9f5e1a"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
handbook/build/assets/js/196f2029.36590c94.js
Normal file
1
handbook/build/assets/js/196f2029.36590c94.js
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkthingsgateway=self.webpackChunkthingsgateway||[]).push([[2419],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},d=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=s(r),f=a,m=u["".concat(l,".").concat(f)]||u[f]||p[f]||o;return r?n.createElement(m,i(i({ref:t},d),{},{components:r})):n.createElement(m,i({ref:t},d))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=u;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var s=2;s<o;s++)i[s]=r[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}u.displayName="MDXCreateElement"},1936:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=r(7462),a=(r(7294),r(3905));const o={id:"hardwareinfo",title:"\u786c\u4ef6\u4fe1\u606f"},i=void 0,c={unversionedId:"hardwareinfo",id:"hardwareinfo",title:"\u786c\u4ef6\u4fe1\u606f",description:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",source:"@site/docs/hardwareinfo.mdx",sourceDirName:".",slug:"/hardwareinfo",permalink:"/thingsgateway-docs/docs/hardwareinfo",draft:!1,editUrl:"https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/hardwareinfo.mdx",tags:[],version:"current",lastUpdatedBy:"2248356998 qq.com",lastUpdatedAt:1689499706,formattedLastUpdatedAt:"Jul 16, 2023",frontMatter:{id:"hardwareinfo",title:"\u786c\u4ef6\u4fe1\u606f"},sidebar:"docs",previous:{title:"\u5b9e\u65f6\u62a5\u8b66",permalink:"/thingsgateway-docs/docs/realalarm"},next:{title:"\u5386\u53f2\u6570\u636e",permalink:"/thingsgateway-docs/docs/hisdata"}},l={},s=[{value:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",level:2},{value:"1\u3001\u5b9e\u65f6\u62a5\u8b66",id:"1\u5b9e\u65f6\u62a5\u8b66",level:3}],d={toc:s};function p(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"},"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"),(0,a.kt)("h3",{id:"1\u5b9e\u65f6\u62a5\u8b66"},"1\u3001\u5b9e\u65f6\u62a5\u8b66"),(0,a.kt)("p",null,(0,a.kt)("img",{src:r(3993).Z,width:"2560",height:"1550"})),(0,a.kt)("p",null," \u4ece\u4e0a\u56fe\u4e2d\u53ef\u4ee5\u770b\u5230\u6bcf\u4e2a\u533a\u57df\u7684\u529f\u80fd"),(0,a.kt)("p",null," \u5305\u542b\u8f6f\u4ef6\u73af\u5883\u3001Cpu\u72b6\u6001\u3001\u5185\u5b58\u72b6\u6001\u3001\u5f53\u524d\u78c1\u76d8(\u8f6f\u4ef6\u6240\u5728\u78c1\u76d8/\u5206\u533a)\u72b6\u6001\uff0c\u7f51\u7edc\u72b6\u6001"))}p.isMDXComponent=!0},3993:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/hardwareinfo-1-01fa4a471bad65dfe820fce8223d2608.png"}}]);
|
||||
"use strict";(self.webpackChunkthingsgateway=self.webpackChunkthingsgateway||[]).push([[2419],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},d=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=s(r),f=a,m=u["".concat(l,".").concat(f)]||u[f]||p[f]||o;return r?n.createElement(m,i(i({ref:t},d),{},{components:r})):n.createElement(m,i({ref:t},d))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=u;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var s=2;s<o;s++)i[s]=r[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}u.displayName="MDXCreateElement"},1936:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=r(7462),a=(r(7294),r(3905));const o={id:"hardwareinfo",title:"\u786c\u4ef6\u4fe1\u606f"},i=void 0,c={unversionedId:"hardwareinfo",id:"hardwareinfo",title:"\u786c\u4ef6\u4fe1\u606f",description:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",source:"@site/docs/hardwareinfo.mdx",sourceDirName:".",slug:"/hardwareinfo",permalink:"/thingsgateway-docs/docs/hardwareinfo",draft:!1,editUrl:"https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/hardwareinfo.mdx",tags:[],version:"current",lastUpdatedBy:"2248356998 qq.com",lastUpdatedAt:1689499706,formattedLastUpdatedAt:"Jul 16, 2023",frontMatter:{id:"hardwareinfo",title:"\u786c\u4ef6\u4fe1\u606f"},sidebar:"docs",previous:{title:"\u5b9e\u65f6\u62a5\u8b66",permalink:"/thingsgateway-docs/docs/realalarm"},next:{title:"\u5386\u53f2\u6570\u636e",permalink:"/thingsgateway-docs/docs/hisdata"}},l={},s=[{value:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",level:2},{value:"1\u3001\u5b9e\u65f6\u62a5\u8b66",id:"1\u5b9e\u65f6\u62a5\u8b66",level:3}],d={toc:s};function p(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"},"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"),(0,a.kt)("h3",{id:"1\u5b9e\u65f6\u62a5\u8b66"},"1\u3001\u5b9e\u65f6\u62a5\u8b66"),(0,a.kt)("p",null,(0,a.kt)("img",{src:r(1219).Z,width:"2560",height:"1550"})),(0,a.kt)("p",null," \u4ece\u4e0a\u56fe\u4e2d\u53ef\u4ee5\u770b\u5230\u6bcf\u4e2a\u533a\u57df\u7684\u529f\u80fd"),(0,a.kt)("p",null," \u5305\u542b\u8f6f\u4ef6\u73af\u5883\u3001Cpu\u72b6\u6001\u3001\u5185\u5b58\u72b6\u6001\u3001\u5f53\u524d\u78c1\u76d8(\u8f6f\u4ef6\u6240\u5728\u78c1\u76d8/\u5206\u533a)\u72b6\u6001\uff0c\u7f51\u7edc\u72b6\u6001"))}p.isMDXComponent=!0},1219:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/hardwareinfo-1-01fa4a471bad65dfe820fce8223d2608.png"}}]);
|
||||
File diff suppressed because one or more lines are too long
1
handbook/build/assets/js/39f79d48.84084807.js
Normal file
1
handbook/build/assets/js/39f79d48.84084807.js
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkthingsgateway=self.webpackChunkthingsgateway||[]).push([[7128],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},d=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=a,f=u["".concat(s,".").concat(m)]||u[m]||p[m]||o;return r?n.createElement(f,i(i({ref:t},d),{},{components:r})):n.createElement(f,i({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=r[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}u.displayName="MDXCreateElement"},3569:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={id:"hisdata",title:"\u5386\u53f2\u6570\u636e"},i=void 0,c={unversionedId:"hisdata",id:"hisdata",title:"\u5386\u53f2\u6570\u636e",description:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",source:"@site/docs/hisdata.mdx",sourceDirName:".",slug:"/hisdata",permalink:"/thingsgateway-docs/docs/hisdata",draft:!1,editUrl:"https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/hisdata.mdx",tags:[],version:"current",lastUpdatedBy:"2248356998 qq.com",lastUpdatedAt:1689499706,formattedLastUpdatedAt:"Jul 16, 2023",frontMatter:{id:"hisdata",title:"\u5386\u53f2\u6570\u636e"},sidebar:"docs",previous:{title:"\u786c\u4ef6\u4fe1\u606f",permalink:"/thingsgateway-docs/docs/hardwareinfo"},next:{title:"\u5386\u53f2\u62a5\u8b66",permalink:"/thingsgateway-docs/docs/hisalarm"}},s={},l=[{value:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",level:2},{value:"1\u3001\u5386\u53f2\u6570\u636e",id:"1\u5386\u53f2\u6570\u636e",level:3}],d={toc:l};function p(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"},"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"),(0,a.kt)("h3",{id:"1\u5386\u53f2\u6570\u636e"},"1\u3001\u5386\u53f2\u6570\u636e"),(0,a.kt)("p",null,(0,a.kt)("img",{src:r(2915).Z,width:"2560",height:"1550"})),(0,a.kt)("p",null," \u4ece\u4e0a\u56fe\u4e2d\u53ef\u4ee5\u770b\u5230\u6bcf\u4e2a\u533a\u57df\u7684\u529f\u80fd"),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("mdxAdmonitionTitle",{parentName:"admonition"},(0,a.kt)("inlineCode",{parentName:"mdxAdmonitionTitle"},"\u63d0\u793a")),(0,a.kt)("p",{parentName:"admonition"}," \u6ce8\u610f\u5386\u53f2\u53d8\u91cf\u5b58\u50a8\u670d\u52a1\u9700\u8981\u5f00\u542f\uff0c\u4ee5\u53ca\u914d\u7f6e\u53d8\u91cf\u5386\u53f2\u5c5e\u6027")))}p.isMDXComponent=!0},2915:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/hisdata-1-3bad61a2791a6a0c124339b3e81321b9.png"}}]);
|
||||
"use strict";(self.webpackChunkthingsgateway=self.webpackChunkthingsgateway||[]).push([[7128],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>m});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},d=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=a,f=u["".concat(s,".").concat(m)]||u[m]||p[m]||o;return r?n.createElement(f,i(i({ref:t},d),{},{components:r})):n.createElement(f,i({ref:t},d))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=r[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}u.displayName="MDXCreateElement"},3569:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={id:"hisdata",title:"\u5386\u53f2\u6570\u636e"},i=void 0,c={unversionedId:"hisdata",id:"hisdata",title:"\u5386\u53f2\u6570\u636e",description:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",source:"@site/docs/hisdata.mdx",sourceDirName:".",slug:"/hisdata",permalink:"/thingsgateway-docs/docs/hisdata",draft:!1,editUrl:"https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/hisdata.mdx",tags:[],version:"current",lastUpdatedBy:"2248356998 qq.com",lastUpdatedAt:1689499706,formattedLastUpdatedAt:"Jul 16, 2023",frontMatter:{id:"hisdata",title:"\u5386\u53f2\u6570\u636e"},sidebar:"docs",previous:{title:"\u786c\u4ef6\u4fe1\u606f",permalink:"/thingsgateway-docs/docs/hardwareinfo"},next:{title:"\u5386\u53f2\u62a5\u8b66",permalink:"/thingsgateway-docs/docs/hisalarm"}},s={},l=[{value:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",level:2},{value:"1\u3001\u5386\u53f2\u6570\u636e",id:"1\u5386\u53f2\u6570\u636e",level:3}],d={toc:l};function p(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"},"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"),(0,a.kt)("h3",{id:"1\u5386\u53f2\u6570\u636e"},"1\u3001\u5386\u53f2\u6570\u636e"),(0,a.kt)("p",null,(0,a.kt)("img",{src:r(6291).Z,width:"2560",height:"1550"})),(0,a.kt)("p",null," \u4ece\u4e0a\u56fe\u4e2d\u53ef\u4ee5\u770b\u5230\u6bcf\u4e2a\u533a\u57df\u7684\u529f\u80fd"),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("mdxAdmonitionTitle",{parentName:"admonition"},(0,a.kt)("inlineCode",{parentName:"mdxAdmonitionTitle"},"\u63d0\u793a")),(0,a.kt)("p",{parentName:"admonition"}," \u6ce8\u610f\u5386\u53f2\u53d8\u91cf\u5b58\u50a8\u670d\u52a1\u9700\u8981\u5f00\u542f\uff0c\u4ee5\u53ca\u914d\u7f6e\u53d8\u91cf\u5386\u53f2\u5c5e\u6027")))}p.isMDXComponent=!0},6291:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/hisdata-1-3bad61a2791a6a0c124339b3e81321b9.png"}}]);
|
||||
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkthingsgateway=self.webpackChunkthingsgateway||[]).push([[445],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>u});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(r),u=a,f=m["".concat(l,".").concat(u)]||m[u]||d[u]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function u(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var s=2;s<o;s++)i[s]=r[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},2965:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=r(7462),a=(r(7294),r(3905));const o={id:"hisalarm",title:"\u5386\u53f2\u62a5\u8b66"},i=void 0,c={unversionedId:"hisalarm",id:"hisalarm",title:"\u5386\u53f2\u62a5\u8b66",description:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",source:"@site/docs/hisalarm.mdx",sourceDirName:".",slug:"/hisalarm",permalink:"/thingsgateway-docs/docs/hisalarm",draft:!1,editUrl:"https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/hisalarm.mdx",tags:[],version:"current",lastUpdatedBy:"2248356998 qq.com",lastUpdatedAt:1689499706,formattedLastUpdatedAt:"Jul 16, 2023",frontMatter:{id:"hisalarm",title:"\u5386\u53f2\u62a5\u8b66"},sidebar:"docs",previous:{title:"\u5386\u53f2\u6570\u636e",permalink:"/thingsgateway-docs/docs/hisdata"},next:{title:"RPC\u65e5\u5fd7",permalink:"/thingsgateway-docs/docs/rpclog"}},l={},s=[{value:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",level:2},{value:"1\u3001\u5386\u53f2\u62a5\u8b66",id:"1\u5386\u53f2\u62a5\u8b66",level:3}],p={toc:s};function d(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"},"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"),(0,a.kt)("h3",{id:"1\u5386\u53f2\u62a5\u8b66"},"1\u3001\u5386\u53f2\u62a5\u8b66"),(0,a.kt)("p",null,(0,a.kt)("img",{src:r(6734).Z,width:"2560",height:"1550"})),(0,a.kt)("p",null," \u4ece\u4e0a\u56fe\u4e2d\u53ef\u4ee5\u770b\u5230\u6bcf\u4e2a\u533a\u57df\u7684\u529f\u80fd"),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("mdxAdmonitionTitle",{parentName:"admonition"},(0,a.kt)("inlineCode",{parentName:"mdxAdmonitionTitle"},"\u63d0\u793a")),(0,a.kt)("p",{parentName:"admonition"}," \u6ce8\u610f\u5386\u53f2\u62a5\u8b66\u5b58\u50a8\u670d\u52a1\u9700\u8981\u5f00\u542f\uff0c\u4ee5\u53ca\u914d\u7f6e\u53d8\u91cf\u62a5\u8b66\u5c5e\u6027")))}d.isMDXComponent=!0},6734:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/hisalarm-1-c655d9dec2689c687f58cfe9d107ff74.png"}}]);
|
||||
"use strict";(self.webpackChunkthingsgateway=self.webpackChunkthingsgateway||[]).push([[445],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>u});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(r),u=a,f=m["".concat(l,".").concat(u)]||m[u]||d[u]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function u(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var s=2;s<o;s++)i[s]=r[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},2965:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=r(7462),a=(r(7294),r(3905));const o={id:"hisalarm",title:"\u5386\u53f2\u62a5\u8b66"},i=void 0,c={unversionedId:"hisalarm",id:"hisalarm",title:"\u5386\u53f2\u62a5\u8b66",description:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",source:"@site/docs/hisalarm.mdx",sourceDirName:".",slug:"/hisalarm",permalink:"/thingsgateway-docs/docs/hisalarm",draft:!1,editUrl:"https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/hisalarm.mdx",tags:[],version:"current",lastUpdatedBy:"2248356998 qq.com",lastUpdatedAt:1689499706,formattedLastUpdatedAt:"Jul 16, 2023",frontMatter:{id:"hisalarm",title:"\u5386\u53f2\u62a5\u8b66"},sidebar:"docs",previous:{title:"\u5386\u53f2\u6570\u636e",permalink:"/thingsgateway-docs/docs/hisdata"},next:{title:"RPC\u65e5\u5fd7",permalink:"/thingsgateway-docs/docs/rpclog"}},l={},s=[{value:"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd",level:2},{value:"1\u3001\u5386\u53f2\u62a5\u8b66",id:"1\u5386\u53f2\u62a5\u8b66",level:3}],p={toc:s};function d(e){let{components:t,...o}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\u4e00\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"},"\u4e00\u3001\u9875\u9762\u529f\u80fd\u4ecb\u7ecd"),(0,a.kt)("h3",{id:"1\u5386\u53f2\u62a5\u8b66"},"1\u3001\u5386\u53f2\u62a5\u8b66"),(0,a.kt)("p",null,(0,a.kt)("img",{src:r(4197).Z,width:"2560",height:"1550"})),(0,a.kt)("p",null," \u4ece\u4e0a\u56fe\u4e2d\u53ef\u4ee5\u770b\u5230\u6bcf\u4e2a\u533a\u57df\u7684\u529f\u80fd"),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("mdxAdmonitionTitle",{parentName:"admonition"},(0,a.kt)("inlineCode",{parentName:"mdxAdmonitionTitle"},"\u63d0\u793a")),(0,a.kt)("p",{parentName:"admonition"}," \u6ce8\u610f\u5386\u53f2\u62a5\u8b66\u5b58\u50a8\u670d\u52a1\u9700\u8981\u5f00\u542f\uff0c\u4ee5\u53ca\u914d\u7f6e\u53d8\u91cf\u62a5\u8b66\u5c5e\u6027")))}d.isMDXComponent=!0},4197:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/hisalarm-1-c655d9dec2689c687f58cfe9d107ff74.png"}}]);
|
||||
@@ -1 +1 @@
|
||||
"use strict";(self.webpackChunkthingsgateway=self.webpackChunkthingsgateway||[]).push([[9974],{2776:s=>{s.exports=JSON.parse('{"name":"@easyops-cn/docusaurus-search-local","id":"default"}')}}]);
|
||||
"use strict";(self.webpackChunkthingsgateway=self.webpackChunkthingsgateway||[]).push([[4875],{2776:s=>{s.exports=JSON.parse('{"name":"@easyops-cn/docusaurus-search-local","id":"default"}')}}]);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user