diff --git a/.vs/IoTGateway/DesignTimeBuild/.dtbcache.v2 b/.vs/IoTGateway/DesignTimeBuild/.dtbcache.v2
index 1975894..2262c7d 100644
Binary files a/.vs/IoTGateway/DesignTimeBuild/.dtbcache.v2 and b/.vs/IoTGateway/DesignTimeBuild/.dtbcache.v2 differ
diff --git a/.vs/IoTGateway/v17/.futdcache.v1 b/.vs/IoTGateway/v17/.futdcache.v1
index 7707981..0e0b7c9 100644
Binary files a/.vs/IoTGateway/v17/.futdcache.v1 and b/.vs/IoTGateway/v17/.futdcache.v1 differ
diff --git a/.vs/IoTGateway/v17/.suo b/.vs/IoTGateway/v17/.suo
index ff962f4..8c2eaa9 100644
Binary files a/.vs/IoTGateway/v17/.suo and b/.vs/IoTGateway/v17/.suo differ
diff --git a/.vs/IoTGateway/v17/fileList.bin b/.vs/IoTGateway/v17/fileList.bin
index c8f2853..2809eb8 100644
Binary files a/.vs/IoTGateway/v17/fileList.bin and b/.vs/IoTGateway/v17/fileList.bin differ
diff --git a/IoTGateway/Areas/Rpc/Views/RpcLog/Index.cshtml b/IoTGateway/Areas/Rpc/Views/RpcLog/Index.cshtml
index 907c677..8e14f45 100644
--- a/IoTGateway/Areas/Rpc/Views/RpcLog/Index.cshtml
+++ b/IoTGateway/Areas/Rpc/Views/RpcLog/Index.cshtml
@@ -11,5 +11,5 @@
-注意:不同平台的rpc的topic和payload均不同,后期教程会更新到http://iotgateway.net/
+注意:不同平台的rpc的topic和payload均不同,后期教程会更新到http://iotgateway.net/
diff --git a/IoTGateway/Views/Login/Login.cshtml b/IoTGateway/Views/Login/Login.cshtml
index 759e23e..3432b93 100644
--- a/IoTGateway/Views/Login/Login.cshtml
+++ b/IoTGateway/Views/Login/Login.cshtml
@@ -69,7 +69,7 @@
@Model.MSD.GetFirstError()
@**@
diff --git a/IoTGateway/iotgateway.db b/IoTGateway/iotgateway.db
index 6ed324d..563f4fd 100644
Binary files a/IoTGateway/iotgateway.db and b/IoTGateway/iotgateway.db differ
diff --git a/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs b/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs
index 66e93c0..0700ed4 100644
--- a/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs
+++ b/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs
@@ -21,7 +21,6 @@ namespace DriverModbusMaster
private SerialPort port = null;
private Modbus.Device.ModbusMaster master = null;
private SerialPortAdapter adapter = null;
- private object locker=new object();
#region 配置参数
[ConfigParameter("设备Id")]
@@ -199,135 +198,119 @@ namespace DriverModbusMaster
[Method("功能码:03", description: "ReadHoldingRegisters读保持寄存器")]
public DriverReturnValueModel ReadHoldingRegisters(DriverAddressIoArgModel ioarg)
{
- lock (locker)
+ DriverReturnValueModel ret = new();
+ try
{
- DriverReturnValueModel ret = new();
- try
+ if (IsConnected)
+ ret = ReadRegistersBuffers(3, ioarg);
+ else
{
- if (IsConnected)
- ret = ReadRegistersBuffers(3, ioarg);
- else
- {
- ret.StatusType = VaribaleStatusTypeEnum.Bad;
- ret.Message = "TCP连接异常";
- }
+ ret.StatusType = VaribaleStatusTypeEnum.Bad;
+ ret.Message = "TCP连接异常";
}
- catch (Exception ex)
- {
- ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
- ret.Message = ex.Message;
-
- }
- return ret;
}
-
+ catch (Exception ex)
+ {
+ ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
+ ret.Message = ex.Message;
+
+ }
+ return ret;
}
[Method("功能码:04", description: "ReadHoldingRegisters读输入寄存器")]
public DriverReturnValueModel ReadInputRegisters(DriverAddressIoArgModel ioarg)
{
- lock (locker)
+ DriverReturnValueModel ret = new();
+ try
{
- DriverReturnValueModel ret = new();
- try
+ if (IsConnected)
+ ret = ReadRegistersBuffers(4, ioarg);
+ else
{
- if (IsConnected)
- ret = ReadRegistersBuffers(4, ioarg);
- else
- {
- ret.StatusType = VaribaleStatusTypeEnum.Bad;
- ret.Message = "TCP连接异常";
- }
+ ret.StatusType = VaribaleStatusTypeEnum.Bad;
+ ret.Message = "TCP连接异常";
}
- catch (Exception ex)
- {
- ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
- ret.Message = ex.Message;
-
- }
- return ret;
}
-
+ catch (Exception ex)
+ {
+ ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
+ ret.Message = ex.Message;
+
+ }
+ return ret;
}
[Method("功能码:01", description: "ReadCoil读线圈")]
public DriverReturnValueModel ReadCoil(DriverAddressIoArgModel ioarg)
{
- lock (locker)
+ DriverReturnValueModel ret = new();
+ try
{
- DriverReturnValueModel ret = new();
- try
+ if (IsConnected)
{
- if (IsConnected)
+ var retBool = master.ReadCoils(SlaveAddress, ushort.Parse(ioarg.Address), 1)[0];
+ if (ioarg.ValueType == DataTypeEnum.Bit)
{
- var retBool = master.ReadCoils(SlaveAddress, ushort.Parse(ioarg.Address), 1)[0];
- if (ioarg.ValueType == DataTypeEnum.Bit)
- {
- if (retBool)
- ret.Value = 1;
- else
- ret.Value = 0;
- }
+ if (retBool)
+ ret.Value = 1;
else
- ret.Value = retBool;
- ret.StatusType = VaribaleStatusTypeEnum.Good;
+ ret.Value = 0;
}
else
- {
- ret.StatusType = VaribaleStatusTypeEnum.Bad;
- ret.Message = "TCP连接异常";
- }
+ ret.Value = retBool;
+ ret.StatusType = VaribaleStatusTypeEnum.Good;
}
- catch (Exception ex)
+ else
{
- ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
- ret.Message = ex.Message;
-
+ ret.StatusType = VaribaleStatusTypeEnum.Bad;
+ ret.Message = "TCP连接异常";
}
- return ret;
}
-
+ catch (Exception ex)
+ {
+ ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
+ ret.Message = ex.Message;
+
+ }
+ return ret;
}
[Method("功能码:02", description: "ReadInput读输入")]
public DriverReturnValueModel ReadInput(DriverAddressIoArgModel ioarg)
{
- lock (locker)
+ DriverReturnValueModel ret = new();
+ try
{
- DriverReturnValueModel ret = new();
- try
+ if (IsConnected)
{
- if (IsConnected)
+ var retBool = master.ReadInputs(SlaveAddress, ushort.Parse(ioarg.Address), 1)[0];
+ if (ioarg.ValueType == DataTypeEnum.Bit)
{
- var retBool = master.ReadInputs(SlaveAddress, ushort.Parse(ioarg.Address), 1)[0];
- if (ioarg.ValueType == DataTypeEnum.Bit)
- {
- if (retBool)
- ret.Value = 1;
- else
- ret.Value = 0;
- }
+ if (retBool)
+ ret.Value = 1;
else
- ret.Value = retBool;
- ret.StatusType = VaribaleStatusTypeEnum.Good;
+ ret.Value = 0;
}
else
- {
- ret.StatusType = VaribaleStatusTypeEnum.Bad;
- ret.Message = "TCP连接异常";
- }
+ ret.Value = retBool;
+ ret.StatusType = VaribaleStatusTypeEnum.Good;
}
- catch (Exception ex)
+ else
{
- ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
- ret.Message = ex.Message;
-
+ ret.StatusType = VaribaleStatusTypeEnum.Bad;
+ ret.Message = "TCP连接异常";
}
- return ret;
}
-
+ catch (Exception ex)
+ {
+ ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
+ ret.Message = ex.Message;
+
+ }
+ return ret;
}
@@ -463,42 +446,38 @@ namespace DriverModbusMaster
public async Task WriteAsync(string RequestId, string Method, DriverAddressIoArgModel Ioarg)
{
- lock (locker)
+ RpcResponse rpcResponse = new() { IsSuccess = false };
+ try
{
- RpcResponse rpcResponse = new() { IsSuccess = false };
- try
+ ushort address = ushort.Parse(Ioarg.Address);
+ if (!IsConnected)
+ rpcResponse.Description = "设备连接已断开";
+ else
{
- ushort address = ushort.Parse(Ioarg.Address);
- if (!IsConnected)
- rpcResponse.Description = "设备连接已断开";
- else
+ //功能码01
+ if (Method == nameof(ReadCoil))
{
- //功能码01
- if (Method == nameof(ReadCoil))
- {
- bool value = Ioarg.Value.ToString() == "1" || Ioarg.Value.ToString().ToLower() == "true";
- master.WriteSingleCoilAsync(SlaveAddress, address, value);
- rpcResponse.IsSuccess = true;
- return rpcResponse;
- }
- //功能码03
- else if (Method == nameof(ReadHoldingRegisters))
- {
- master.WriteSingleRegisterAsync(SlaveAddress, address, ushort.Parse(Ioarg.Value.ToString()));
- rpcResponse.IsSuccess = true;
- return rpcResponse;
- }
- else
- rpcResponse.Description = $"不支持写入:{Method}";
+ bool value = Ioarg.Value.ToString() == "1" || Ioarg.Value.ToString().ToLower() == "true";
+ master.WriteSingleCoilAsync(SlaveAddress, address, value);
+ rpcResponse.IsSuccess = true;
+ return rpcResponse;
}
+ //功能码03
+ else if (Method == nameof(ReadHoldingRegisters))
+ {
+ master.WriteSingleRegisterAsync(SlaveAddress, address, ushort.Parse(Ioarg.Value.ToString()));
+ rpcResponse.IsSuccess = true;
+ return rpcResponse;
+ }
+ else
+ rpcResponse.Description = $"不支持写入:{Method}";
}
- catch (Exception ex)
- {
- rpcResponse.Description = $"写入失败:{Method},{Ioarg}";
- }
- return rpcResponse;
}
-
+ catch (Exception ex)
+ {
+ rpcResponse.Description = $"写入失败:{Method},{Ioarg}";
+ }
+ return rpcResponse;
}
}
public enum PLC_TYPE
diff --git a/Plugins/Plugin/DeviceService.cs b/Plugins/Plugin/DeviceService.cs
index 62d7f35..8321fa1 100644
--- a/Plugins/Plugin/DeviceService.cs
+++ b/Plugins/Plugin/DeviceService.cs
@@ -37,7 +37,6 @@ namespace Plugin
_DrvierManager = drvierManager;
_MyMqttClient = myMqttClient;
_MqttServer = mqttServer;
-
try
{
using (var DC = new DataContext(connnectSetting, DBType))
diff --git a/Plugins/Plugin/DeviceThread.cs b/Plugins/Plugin/DeviceThread.cs
index 0b1538b..b88a804 100644
--- a/Plugins/Plugin/DeviceThread.cs
+++ b/Plugins/Plugin/DeviceThread.cs
@@ -1,19 +1,11 @@
-using Microsoft.EntityFrameworkCore;
-using PluginInterface;
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using PluginInterface;
using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
using IoTGateway.DataAccess;
using IoTGateway.Model;
-using WalkingTec.Mvvm.Core;
using DynamicExpresso;
using MQTTnet.Server;
using Newtonsoft.Json;
using Microsoft.Extensions.Logging;
-using PluginInterface.IoTSharp;
namespace Plugin
{
@@ -29,7 +21,8 @@ namespace Plugin
private DateTime TsStartDt = new DateTime(1970, 1, 1);
private CancellationTokenSource tokenSource = new CancellationTokenSource();
private Interpreter Interpreter = null;
-
+ private object _lock = new object();
+ private bool lastConnected = false;
public DeviceThread(Device device, IDriver driver, string ProjectId, MyMqttClient myMqttClient, Interpreter interpreter, IMqttServer mqttServer, ILogger logger)
{
_myMqttClient = myMqttClient;
@@ -58,8 +51,9 @@ namespace Plugin
myMqttClient.UploadAttributeAsync(device.DeviceName, device.DeviceConfigs.Where(x => x.DataSide == DataSide.ClientSide).ToDictionary(x => x.DeviceConfigName, x => x.Value));
task = Task.Run(() =>
- {
- while (true)
+ {
+ Thread.Sleep(5000);
+ while (true)
{
if (tokenSource.IsCancellationRequested)
{
@@ -67,92 +61,103 @@ namespace Plugin
return;
}
- try
+ lock (_lock)
{
- Dictionary> sendModel = new() { { _device.DeviceName, new() } };
-
- var payLoad = new PayLoad() { Values = new() };
-
- if (driver.IsConnected)
+ try
{
- if (_device.DeviceVariables != null)
+ Dictionary> sendModel = new() { { _device.DeviceName, new() } };
+
+ var payLoad = new PayLoad() { Values = new() };
+
+ if (driver.IsConnected)
{
- foreach (var item in _device.DeviceVariables)
+ if (_device.DeviceVariables != null)
{
- var ret = new DriverReturnValueModel();
- var ioarg = new DriverAddressIoArgModel
+ foreach (var item in _device.DeviceVariables)
{
- ID = item.ID,
- Address = item.DeviceAddress,
- ValueType = item.DataType
- };
- var method = Methods.Where(x => x.Name == item.Method).FirstOrDefault();
- if (method == null)
- ret.StatusType = VaribaleStatusTypeEnum.MethodError;
- else
- ret = (DriverReturnValueModel)method.Invoke(_driver, new object[1] { ioarg });
+ var ret = new DriverReturnValueModel();
+ var ioarg = new DriverAddressIoArgModel
+ {
+ ID = item.ID,
+ Address = item.DeviceAddress,
+ ValueType = item.DataType
+ };
+ var method = Methods.Where(x => x.Name == item.Method).FirstOrDefault();
+ if (method == null)
+ ret.StatusType = VaribaleStatusTypeEnum.MethodError;
+ else
+ ret = (DriverReturnValueModel)method.Invoke(_driver, new object[1] { ioarg });
- if (ret.StatusType == VaribaleStatusTypeEnum.Good && !string.IsNullOrWhiteSpace(item.Expressions?.Trim()))
+ if (ret.StatusType == VaribaleStatusTypeEnum.Good && !string.IsNullOrWhiteSpace(item.Expressions?.Trim()))
+ {
+ try
+ {
+ ret.CookedValue = interpreter.Eval(DealMysqlStr(item.Expressions).Replace("raw", ret.Value?.ToString()));
+ }
+ catch (Exception)
+ {
+ ret.StatusType = VaribaleStatusTypeEnum.ExpressionError;
+ }
+ }
+ else
+ ret.CookedValue = ret.Value;
+
+ payLoad.Values[item.Name] = ret.CookedValue;
+
+ ret.VarId = item.ID;
+
+ //变化了才推送到mqttserver,用于前端展示
+ if (DeviceValues[item.ID].StatusType != ret.StatusType || DeviceValues[item.ID].Value?.ToString() != ret.Value?.ToString() || DeviceValues[item.ID].CookedValue?.ToString() != ret.CookedValue?.ToString())
+ {
+ //这是设备变量列表要用的
+ mqttServer.PublishAsync($"internal/v1/gateway/telemetry/{_device.DeviceName}/{item.Name}", JsonConvert.SerializeObject(ret));
+ //这是在线组态要用的
+ mqttServer.PublishAsync($"v1/gateway/telemetry/{_device.DeviceName}/{item.Name}", JsonConvert.SerializeObject(ret.CookedValue));
+ }
+
+ DeviceValues[item.ID] = ret;
+
+ }
+ payLoad.TS = (long)(DateTime.UtcNow - TsStartDt).TotalMilliseconds;
+
+ if (DeviceValues.Any(x => x.Value.Value == null))
{
- try
- {
- ret.CookedValue = interpreter.Eval(DealMysqlStr(item.Expressions).Replace("raw", ret.Value?.ToString()));
- }
- catch (Exception)
- {
- ret.StatusType = VaribaleStatusTypeEnum.ExpressionError;
- }
+ payLoad.Values = null;
+ payLoad.DeviceStatus = DeviceStatusTypeEnum.Bad;
}
else
- ret.CookedValue = ret.Value;
-
- payLoad.Values[item.Name] = ret.CookedValue;
-
- ret.VarId = item.ID;
-
- //变化了才推送到mqttserver,用于前端展示
- if (DeviceValues[item.ID].StatusType != ret.StatusType || DeviceValues[item.ID].Value?.ToString() != ret.Value?.ToString() || DeviceValues[item.ID].CookedValue?.ToString() != ret.CookedValue?.ToString())
{
- //这是设备变量列表要用的
- mqttServer.PublishAsync($"internal/v1/gateway/telemetry/{_device.DeviceName}/{item.Name}", JsonConvert.SerializeObject(ret));
- //这是在线组态要用的
- mqttServer.PublishAsync($"v1/gateway/telemetry/{_device.DeviceName}/{item.Name}", JsonConvert.SerializeObject(ret.CookedValue));
+ payLoad.DeviceStatus = DeviceStatusTypeEnum.Good;
+ sendModel[_device.DeviceName] = new List { payLoad };
+ myMqttClient.PublishTelemetry(_device, sendModel);
}
-
- DeviceValues[item.ID] = ret;
-
}
- payLoad.TS = (long)(DateTime.Now - TsStartDt).TotalMilliseconds;
- if (DeviceValues.Any(x => x.Value.Value == null))
+ }
+ else
+ {
+ if (driver.Connect())
+ _myMqttClient.DeviceConnected(_device.DeviceName);
+ else if (lastConnected)
{
- payLoad.Values = null;
- payLoad.DeviceStatus = DeviceStatusTypeEnum.Bad;
- }
- else
- {
- payLoad.DeviceStatus = DeviceStatusTypeEnum.Good;
- sendModel[_device.DeviceName] = new List { payLoad };
- myMqttClient.PublishTelemetry(_device, sendModel);
+ lastConnected = false;
+ _myMqttClient.DeviceDisconnected(_device.DeviceName);
}
}
-
}
- else
+ catch (Exception ex)
{
- driver.Connect();
+ _logger.LogError($"线程循环异常,{_device.DeviceName}", ex);
}
}
- catch (Exception ex)
- {
- _logger.LogError($"线程循环异常,{_device.DeviceName}", ex);
- }
+
Thread.Sleep((int)_driver.MinPeriod);
}
});
}
-
+ else
+ _myMqttClient.DeviceDisconnected(_device.DeviceName);
}
private void MyMqttClient_OnExcRpc(object? sender, RpcRequest e)
@@ -173,47 +178,55 @@ namespace Plugin
//执行写入变量RPC
if (e.Method.ToLower() == "write")
{
- //没连接就连接
- if (!_driver.IsConnected)
- _driver.Connect();
-
- //连接成功就尝试一个一个的写入,注意:目前写入地址和读取地址是相同的,对于PLC来说没问题,其他的要自己改........
- if (_driver.IsConnected)
+ lock (_lock)
{
- foreach (var para in e.Params)
+ bool RpcConnected = false;
+ //没连接就连接
+ if (!_driver.IsConnected)
+ if (_driver.Connect())
+ RpcConnected = true;
+
+ //连接成功就尝试一个一个的写入,注意:目前写入地址和读取地址是相同的,对于PLC来说没问题,其他的要自己改........
+ if (_driver.IsConnected)
{
- //先查配置项,要用到配置的地址、数据类型、方法(方法最主要是用于区分写入数据的辅助判断,比如modbus不同的功能码)
- var deviceVariable = _device.DeviceVariables.Where(x => x.Name == para.Key).FirstOrDefault();
- if (deviceVariable != null)
+ foreach (var para in e.Params)
{
- DriverAddressIoArgModel ioArgModel = new()
+ //先查配置项,要用到配置的地址、数据类型、方法(方法最主要是用于区分写入数据的辅助判断,比如modbus不同的功能码)
+ var deviceVariable = _device.DeviceVariables.Where(x => x.Name == para.Key).FirstOrDefault();
+ if (deviceVariable != null)
{
- Address = deviceVariable.DeviceAddress,
- Value = para.Value,
- ValueType = deviceVariable.DataType
- };
- var writeResponse = _driver.WriteAsync(e.RequestId, deviceVariable.Method, ioArgModel).Result;
- rpcResponse.IsSuccess = writeResponse.IsSuccess;
- if (!writeResponse.IsSuccess)
+ DriverAddressIoArgModel ioArgModel = new()
+ {
+ Address = deviceVariable.DeviceAddress,
+ Value = para.Value,
+ ValueType = deviceVariable.DataType
+ };
+ var writeResponse = _driver.WriteAsync(e.RequestId, deviceVariable.Method, ioArgModel).Result;
+ rpcResponse.IsSuccess = writeResponse.IsSuccess;
+ if (!writeResponse.IsSuccess)
+ {
+ rpcResponse.Description = writeResponse.Description;
+ break;
+ }
+ }
+ else
{
- rpcResponse.Description = writeResponse.Description;
+ rpcResponse.IsSuccess = false;
+ rpcResponse.Description = $"未能找到变量:{para.Key}";
break;
}
}
- else
- {
- rpcResponse.IsSuccess = false;
- rpcResponse.Description = $"未能找到变量:{para.Key}";
- break;
- }
- }
+ if (RpcConnected)
+ _driver.Close();
+ }
+ else//连接失败
+ {
+ rpcResponse.IsSuccess = false;
+ rpcResponse.Description = $"{e.DeviceName} 连接失败";
+ }
}
- else//连接失败
- {
- rpcResponse.IsSuccess = false;
- rpcResponse.Description = $"{e.DeviceName} 连接失败";
- }
+
}
//其他RPC TODO
else
@@ -227,12 +240,12 @@ namespace Plugin
//纪录入库
rpcLog.IsSuccess = rpcResponse.IsSuccess;
rpcLog.Description = rpcResponse.Description;
- rpcLog.EndTime=DateTime.Now;
+ rpcLog.EndTime = DateTime.Now;
using (var DC = new DataContext(IoTBackgroundService.connnectSetting, IoTBackgroundService.DBType))
{
- DC.Set().Add(rpcLog);
+ DC.Set().Add(rpcLog);
DC.SaveChanges();
}
}
@@ -241,6 +254,7 @@ namespace Plugin
public void StopThread()
{
_logger.LogInformation($"线程停止:{_device.DeviceName}");
+ _myMqttClient.DeviceDisconnected(_device.DeviceName);
if (task != null)
{
_myMqttClient.OnExcRpc -= MyMqttClient_OnExcRpc;
diff --git a/Plugins/Plugin/MyMqttClient.cs b/Plugins/Plugin/MyMqttClient.cs
index d18d754..3f202bd 100644
--- a/Plugins/Plugin/MyMqttClient.cs
+++ b/Plugins/Plugin/MyMqttClient.cs
@@ -101,21 +101,39 @@ namespace Plugin
}
}
+ private readonly string tbRpcTopic = "v1/gateway/rpc";
private void OnConnected()
{
- //v1/gateway/attributes
- //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}}
-
- //v1/gateway/rpc
- //{"device": "Device A", "data": {"id": $request_id, "method": "toggle_gpio", "params": {"pin":1}}}
- Client.SubscribeAsync(tbRpcTopic, MqttQualityOfServiceLevel.ExactlyOnce);//tb server side rpc
- Client.SubscribeAsync($"devices/+/rpc/request/+/+", MqttQualityOfServiceLevel.ExactlyOnce);
- Client.SubscribeAsync($"devices/Modbus/attributes/update/", MqttQualityOfServiceLevel.ExactlyOnce);
- Client.SubscribeAsync($"devices/+/attributes/response/+", MqttQualityOfServiceLevel.ExactlyOnce);
+ switch (_systemConfig.IoTPlatformType)
+ {
+ case IoTPlatformType.ThingsBoard:
+ //{"device": "Device A", "data": {"id": $request_id, "method": "toggle_gpio", "params": {"pin":1}}}
+ Client.SubscribeAsync(tbRpcTopic, MqttQualityOfServiceLevel.ExactlyOnce);
+ //Message: {"id": $request_id, "device": "Device A", "value": "value1"}
+ Client.SubscribeAsync("v1/gateway/attributes/response", MqttQualityOfServiceLevel.ExactlyOnce);
+ //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}}
+ Client.SubscribeAsync("v1/gateway/attributes", MqttQualityOfServiceLevel.ExactlyOnce);
+ break;
+ case IoTPlatformType.IoTSharp:
+ Client.SubscribeAsync("devices/+/rpc/response/+/+", MqttQualityOfServiceLevel.ExactlyOnce);
+ Client.SubscribeAsync("devices/+/attributes/update", MqttQualityOfServiceLevel.ExactlyOnce);
+ //Message: {"device": "Device A", "data": {"attribute1": "value1", "attribute2": 42}}
+ Client.SubscribeAsync("devices/+/attributes/response/+", MqttQualityOfServiceLevel.ExactlyOnce);
+ break;
+ case IoTPlatformType.AliCloudIoT:
+ break;
+ case IoTPlatformType.TencentIoTHub:
+ break;
+ case IoTPlatformType.BaiduIoTCore:
+ break;
+ case IoTPlatformType.OneNET:
+ break;
+ default:
+ break;
+ }
_logger.LogInformation($"MQTT CONNECTED WITH SERVER ");
}
- private readonly string tbRpcTopic = @"v1/gateway/rpc";
private Task Client_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
{
@@ -299,18 +317,47 @@ namespace Plugin
}
- public Task RequestAttributes(string _device, bool anySide, params string[] args)
+ public Task RequestAttributes(string _devicename, bool anySide, params string[] args)
{
- //Topic: v1/gateway/attributes/request
- // Message: { "id": $request_id, "device": "Device A", "client": true, "key": "attribute1"}
- //Topic: v1/gateway/attributes/response
- //Message: {"id": $request_id, "device": "Device A", "value": "value1"}
- string id = Guid.NewGuid().ToString();
- string topic = $"devices/{_device}/attributes/request/{id}";
- Dictionary keys = new Dictionary();
- keys.Add(anySide ? "anySide" : "server", string.Join(",", args));
- Client.SubscribeAsync($"devices/{_device}/attributes/response/{id}", MqttQualityOfServiceLevel.ExactlyOnce);
- return Client.PublishAsync(topic, Newtonsoft.Json.JsonConvert.SerializeObject(keys), MqttQualityOfServiceLevel.ExactlyOnce);
+ try
+ {
+ string id = Guid.NewGuid().ToString();
+ switch (_systemConfig.IoTPlatformType)
+ {
+ case IoTPlatformType.ThingsBoard:
+ //{"id": $request_id, "device": "Device A", "client": true, "key": "attribute1"}
+ Dictionary tbRequestData = new Dictionary
+ {
+ { "id",id},
+ { "device",_devicename},
+ { "client",true},
+ { "key",args[0]}
+ };
+ return Client.PublishAsync("v1/gateway/attributes/request", JsonConvert.SerializeObject(tbRequestData), MqttQualityOfServiceLevel.ExactlyOnce);
+ case IoTPlatformType.IoTSharp:
+ string topic = $"devices/{_devicename}/attributes/request/{id}";
+ Dictionary keys = new Dictionary();
+ keys.Add(anySide ? "anySide" : "server", string.Join(",", args));
+ Client.SubscribeAsync($"devices/{_devicename}/attributes/response/{id}", MqttQualityOfServiceLevel.ExactlyOnce);
+ return Client.PublishAsync(topic, JsonConvert.SerializeObject(keys), MqttQualityOfServiceLevel.ExactlyOnce);
+ case IoTPlatformType.AliCloudIoT:
+ break;
+ case IoTPlatformType.TencentIoTHub:
+ break;
+ case IoTPlatformType.BaiduIoTCore:
+ break;
+ case IoTPlatformType.OneNET:
+ break;
+ default:
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+
+ _logger.LogError($"RequestAttributes:{_devicename}", ex);
+ }
+ return Task.CompletedTask;
}
public void PublishTelemetry(Device device, Dictionary> SendModel)
@@ -353,16 +400,60 @@ namespace Plugin
}
- public void DeviceConnected()
+ public async Task DeviceConnected(string DeviceName)
{
- //Topic: v1/gateway/connect
- //Message: { "device":"Device A"}
+ try
+ {
+ switch (_systemConfig.IoTPlatformType)
+ {
+ case IoTPlatformType.ThingsBoard:
+ case IoTPlatformType.IoTSharp:
+ await Client.PublishAsync("v1/gateway/connect", JsonConvert.SerializeObject(new Dictionary { { "device", DeviceName } }));
+ break;
+ case IoTPlatformType.AliCloudIoT:
+ break;
+ case IoTPlatformType.TencentIoTHub:
+ break;
+ case IoTPlatformType.BaiduIoTCore:
+ break;
+ case IoTPlatformType.OneNET:
+ break;
+ default:
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"DeviceConnected:{DeviceName}", ex);
+ }
}
- public void DeviceDisconnected()
+ public async Task DeviceDisconnected(string DeviceName)
{
- //Topic: v1/gateway/connect
- //Message: { "device":"Device A"}
+ try
+ {
+ switch (_systemConfig.IoTPlatformType)
+ {
+ case IoTPlatformType.ThingsBoard:
+ case IoTPlatformType.IoTSharp:
+ await Client.PublishAsync("v1/gateway/disconnect", JsonConvert.SerializeObject(new Dictionary { { "device", DeviceName } }));
+ break;
+ case IoTPlatformType.AliCloudIoT:
+ break;
+ case IoTPlatformType.TencentIoTHub:
+ break;
+ case IoTPlatformType.BaiduIoTCore:
+ break;
+ case IoTPlatformType.OneNET:
+ break;
+ default:
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"DeviceDisconnected:{DeviceName}", ex);
+ }
}
diff --git a/drivers/net6.0/DriverModbusMaster.dll b/drivers/net6.0/DriverModbusMaster.dll
index b8748b6..d584d62 100644
Binary files a/drivers/net6.0/DriverModbusMaster.dll and b/drivers/net6.0/DriverModbusMaster.dll differ
diff --git a/drivers/net6.0/DriverModbusMaster.pdb b/drivers/net6.0/DriverModbusMaster.pdb
index fbfe581..a243577 100644
Binary files a/drivers/net6.0/DriverModbusMaster.pdb and b/drivers/net6.0/DriverModbusMaster.pdb differ
diff --git a/iotgateway.db b/iotgateway.db
index 6ed324d..563f4fd 100644
Binary files a/iotgateway.db and b/iotgateway.db differ