提交 81f7a9ba 编写于 作者: 麦壳饼's avatar 麦壳饼

删除其他内容,

上级 83401824
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IoT.Things.ModBus
{
public class AppSettings
{
public Uri BrokerUri { get; set; }
public string AccessToken { get; set; }
public List<string> ModBusList { get; set; }
public string DeviceId { get; set; }
}
public class ModBusConfig
{
public string DataType { get; set; }
public string ValueType { get; set; }
public string KeyNameOrPrefix { get; set; }
public string Address { get; set; }
public int Lenght { get; set; }
public Uri ModBusUri { get; set; }
public int Interval { get; set; }
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup>
<Compile Remove="LogFiles\**" />
<Content Remove="LogFiles\**" />
<EmbeddedResource Remove="LogFiles\**" />
<None Remove="LogFiles\**" />
</ItemGroup>
<ItemGroup>
<Content Include="ise_modbus.service">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="CrystalQuartz.AspNetCore" Version="6.8.1" />
<PackageReference Include="HslCommunication" Version="6.2.5" />
<PackageReference Include="Quartz" Version="3.0.7" />
<PackageReference Include="QuartzHostedServiceEx" Version="0.0.7" />
<PackageReference Include="System.ServiceModel.Duplex" Version="4.6.0" />
<PackageReference Include="System.ServiceModel.Http" Version="4.6.0" />
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.7.0" />
<PackageReference Include="System.ServiceModel.Security" Version="4.6.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.0" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.Memory" Version="4.5.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IoTSharp.EdgeSdk.MQTT\IoTSharp.EdgeSdk.MQTT.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="app.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
\ No newline at end of file
using HslCommunication;
using IoT.Things.ModBus.Models;
using IoTSharp.EdgeSdk.MQTT;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IoT.Things.ModBus.Jobs
{
[DisallowConcurrentExecution]
public class Slaver : IJob
{
private readonly MQTTClient _mqtt;
private ILogger _logger;
private readonly AppSettings appSettings;
private const ushort _MAXREADLEN = 32;
public Slaver(MQTTClient mqtt, IOptions<AppSettings> options, ILogger<Slaver> logger)
{
_mqtt = mqtt;
_logger = logger;
appSettings = options.Value;
}
public Task Execute(IJobExecutionContext context)
{
var _modbusdata = context.Trigger.JobDataMap.GetString(nameof(ModBusConfig));
if (!string.IsNullOrEmpty(_modbusdata))
{
var modbusconfig = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, ModBusConfig>>(_modbusdata);
foreach (var kvmb in modbusconfig)
{
var keyname = kvmb.Key;
var mbconfig = kvmb.Value;
var _modbusuri = mbconfig.ModBusUri;
try
{
_logger.LogInformation($"{keyname} {mbconfig.ModBusUri}");
var ok = Task.Run(async () =>
{
try
{
JobResult result = new JobResult() { Code = 0, Message = "OK" };
string keynamejob = context.JobDetail.Key.Name;
var _modbus = new HslCommunication.ModBus.ModbusTcpNet(_modbusuri.Host, _modbusuri.Port, byte.Parse(_modbusuri.AbsolutePath.Trim('/','\\')));
{
_modbus.UseSynchronousNet = true;
var info = _modbus.ConnectServer();
if (!info.IsSuccess) info = _modbus.ConnectServer();
if (!info.IsSuccess) info = _modbus.ConnectServer();
if (info.IsSuccess)
{
var _datatype = mbconfig.ValueType ?? "UInt16";
var readmethod = _modbus.GetType().GetMethod($"Read{_datatype}Async",new Type[] { typeof(string),typeof(ushort)});
ushort address = ushort.Parse(mbconfig.Address);
var length = mbconfig.Lenght+ address;
for (ushort i = address; i < length; i += _MAXREADLEN)
{
ushort tmpmax = (ushort)(i + _MAXREADLEN > length ? length - i : _MAXREADLEN);
var dataresult = await (dynamic)readmethod.Invoke(_modbus, new object[] { i.ToString(), tmpmax });
if (!dataresult.IsSuccess) dataresult = await (Task<OperateResult<object[]>>)readmethod.Invoke(_modbus, new object[] { i.ToString(), tmpmax });
if (!dataresult.IsSuccess) dataresult = await (Task<OperateResult<object[]>>)readmethod.Invoke(_modbus, new object[] { i.ToString(), tmpmax });
_logger.LogInformation($"JobId: {keynamejob} ReadRanage:{i}->{tmpmax + i}) Max:{length} Data: {Newtonsoft.Json.JsonConvert.SerializeObject(dataresult)}");
if (dataresult.IsSuccess && dataresult.Content != null && dataresult.Content.Length > 0)
{
Dictionary<string, object> keys = new Dictionary<string, object>();
for (int xxx = 0; xxx < dataresult.Content.Length; xxx++)
{
keys.Add($"{mbconfig.KeyNameOrPrefix}{xxx + i}", dataresult.Content[xxx]);
}
if (mbconfig.DataType.StartsWith("attribute"))
{
await _mqtt.UploadAttributeAsync(keys);
}
else
{
await _mqtt.UploadTelemetryDataAsync(keys);
}
var resultxx1 = 0;
if (resultxx1 == 0)
{
result.Code = 0;
result.Message = "数据推送完成";
_logger.LogInformation($"{keynamejob}执行完成...");
}
else
{
result.Code = -8;
result.Message = $"{keynamejob}{resultxx1}个数据处理失败";
_logger.LogInformation(result.Message);
}
}
else
{
await _mqtt.UploadTelemetryDataAsync(new { ReadInt16_IsSuccess = info.IsSuccess, ReadInt16_Message = info.Message, ReadInt16_ErrorCode = info.ErrorCode, ReadInt16_Count = tmpmax });
if (dataresult != null)
{
string mesg = $"服务器 {keynamejob}数据读取失败,{ Newtonsoft.Json.JsonConvert.SerializeObject(dataresult)}";
_logger.LogInformation(mesg);
result.Code = -7;
result.Message = mesg;
}
else
{
result.Code = -6;
result.Message = $"服务器 {keynamejob}数据读取失败,结果为空 ";
_logger.LogInformation(result.Message);
}
}
}
_modbus.ConnectClose();
}
else
{
result.Code = -5;
result.Message = $"服务器 {keynamejob}服务器 ";
if (info != null) _logger.LogInformation($"服务器{keynamejob}连接失败:{ Newtonsoft.Json.JsonConvert.SerializeObject(info)}");
}
}
if (result.Code == 0)
{
string msg = $" {keyname}执行结果:{ result.Code}-{result.Message}";
_logger.LogInformation(msg);
}
else
{
string msg = $"{keyname}数据处理异常:{result.Code}-{result.Message} ";
_logger.LogInformation(msg);
}
}
catch (Exception ex)
{
_logger.LogInformation($" {keyname} 遇到问题{ex.Message} , {ex.StackTrace}");
}
}).Wait(TimeSpan.FromSeconds(60));
if (!ok)
{
string message = $" {keyname}超时";
_logger.LogInformation(message);
}
}
catch (Exception ex)
{
_logger.LogInformation($"{keyname} {ex.Message}");
}
}
}
return Task.CompletedTask;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IoT.Things.ModBus.Models
{
public class JobResult
{
public int Code { get; set; }
public string Message { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IoT.Things.ModBus.Models
{
public class RpcParam<T>
{
public string Address { get; set; }
public T Value { get; set; }
}
}
using IoT.Things.ModBus.Services;
using IoTSharp.Extensions;
using IoTSharp.Extensions.AspNetCore;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using QuartzHostedService;
namespace IoT.Things.ModBus
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWindowsServices()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.AllowSynchronousIO = true;
});
webBuilder.UseStartup<Startup>();
})
.ConfigureQuartzHost()
.ConfigureServices(services =>
{
services.AddHostedService<ModBusService>();
});
}
}
\ No newline at end of file
using IoT.Things.ModBus.Jobs;
using IoT.Things.ModBus.Models;
using IoTSharp.EdgeSdk.MQTT;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Quartz;
using QuartzHostedService;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace IoT.Things.ModBus.Services
{
public class ModBusService : IHostedService
{
private readonly MQTTClient _mqtt;
private readonly AppSettings _options;
private readonly ILogger _logger;
private readonly ISchedulerFactory _factory;
private Uri _modbusuri;
public ModBusService(MQTTClient mqtt, IOptions<AppSettings> options, ILogger<ModBusService> logger, ISchedulerFactory factory)
{
_logger = logger;
_options = options.Value;
_mqtt = mqtt;
_mqtt.OnExcRpc += _mqtt_OnExcCommand;
_mqtt.OnReceiveAttributes += Mqtt_OnReceiveAttributesAsync;
_factory = factory;
_mqtt.DeviceId = _options.DeviceId;
}
bool HaveModBusConfig = false;
ModBusConfig modBusConfig = null;
private async void Mqtt_OnReceiveAttributesAsync(object sender, IoTSharp.EdgeSdk.MQTT.AttributeResponse e)
{
try
{
string key = $"{e.DeviceName}_{e.KeyName}";
var sc = await _factory.GetScheduler();
var job = JobBuilder.Create<Slaver>().WithIdentity($"{e.DeviceName}_{e.KeyName}").Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(key).UsingJobData(nameof(ModBusConfig), e.Data).UsingJobData(nameof(e.DeviceName), e.DeviceName).UsingJobData(nameof(e.KeyName), e.KeyName).ForJob(job)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(10).RepeatForever()).StartNow().Build();
if (await sc.CheckExists(new JobKey(key)))
{
await sc.RescheduleJob(new TriggerKey(key), trigger);
}
else
{
await sc.ScheduleJob(job, trigger);
}
modBusConfig = JToken.Parse( e.Data).SelectToken("ModBusConfig").ToObject<ModBusConfig>();
if (modBusConfig != null )
{
_modbusuri = modBusConfig.ModBusUri;
HaveModBusConfig = true;
}
}
catch (Exception ex)
{
HaveModBusConfig = false;
_logger.LogError($"Mqtt_OnReceiveAttributesAsync: {ex.GetType().Name}{ex.Message}");
}
}
private void _mqtt_OnExcCommand(object sender, RpcRequest e)
{
if (e.Method =="WriteInt")
{
Task.Run(async () =>
{
var _modbus = new HslCommunication.ModBus.ModbusTcpNet(_modbusuri.Host, _modbusuri.Port, byte.Parse(_modbusuri.AbsolutePath.Trim('/', '\\')));
_modbus.UseSynchronousNet = true;
var info = _modbus.ConnectServer();
var paramsx = Newtonsoft.Json.JsonConvert.DeserializeObject<RpcParam<int>>(e.Params);
var result= await _modbus.WriteAsync(paramsx.Address, paramsx.Value);
await _mqtt.ResponseExecommand(new RpcResponse() { Method = e.Method, Data = JsonConvert.SerializeObject(result) , DeviceId = e.DeviceId, ResponseId = e.RequestId });
});
}
}
public Task StartAsync(CancellationToken cancellationToken)
{
return Task.Run(async () =>
{
await _mqtt.ConnectAsync(_options.BrokerUri, _options.AccessToken);
do
{
if (!HaveModBusConfig)
{
await _mqtt.RequestAttributes("me", true, "ModBusConfig");
}
await _mqtt.UploadAttributeAsync(new { ModBusServiceStatus = "OK" });
Thread.Sleep(TimeSpan.FromSeconds(60));
} while (!cancellationToken.IsCancellationRequested);
});
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}
\ No newline at end of file
using CrystalQuartz.AspNetCore;
using IoT.Things.ModBus.Jobs;
using IoT.Things.ModBus.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Quartz;
using QuartzHostedService;
using System;
using System.Linq;
using System.Reflection;
namespace IoT.Things.ModBus
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddOptions();
services.Configure<AppSettings>(Configuration);
services.AddLogging(builder =>
{
builder.AddConsole();
});
services.AddQuartzHostedService();
services.AddTransient<Slaver>();
services.AddSingleton(options =>
{
var mqtt = new IoTSharp.EdgeSdk.MQTT.MQTTClient();
return mqtt;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<AppSettings> options, ISchedulerFactory factory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseCrystalQuartz(() => factory.GetScheduler().Result);
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="quartz" type="System.Configuration.NameValueFileSectionHandler" />
</configSections>
<quartz>
<add key="quartz.plugin.recentHistory.type" value="Quartz.Plugins.RecentHistory.ExecutionHistoryPlugin, Quartz.Plugins.RecentHistory" />
<add key="quartz.plugin.recentHistory.storeType" value="Quartz.Plugins.RecentHistory.Impl.InProcExecutionHistoryStore, Quartz.Plugins.RecentHistory" />
</quartz>
</configuration>
\ No newline at end of file
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"BrokerUri": "mqtt://127.0.0.1:1883/",
"AccessToken": "d65261e993384fe9a4f57a6477b7345c",
"DeviceId": "7489bd06-54a8-4b67-a0fe-f0ccf886492c",
"ModBusList": [ "ModBusConfig" ]
}
\ No newline at end of file
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
\ No newline at end of file
[Unit]
Description=ise_modbus running on Linux
[Service]
WorkingDirectory=/var/ise_modbus/
ExecStart=/var/ise_modbus/IoTSharp.Edge.ModBus
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=ise_modbus
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
\ No newline at end of file
## ModBus 对接流程图
![20190615010115.jpg](../docs/vision/modbus.png)
相关文章请参考
https://www.cnblogs.com/MysticBoy/p/11110364.html
由于使用到的HSL组件已经闭源,本项目后期会从本项目中删除
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MQTTnet" Version="3.0.4" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
<HintPath>C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.extensions.logging.abstractions\2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
using Microsoft.Extensions.Logging;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Diagnostics;
using MQTTnet.Protocol;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace IoTSharp.EdgeSdk.MQTT
{
public class MQTTClient
{
private readonly ILogger _logger;
public MQTTClient()
{
_logger = Microsoft.Extensions.Logging.Abstractions.NullLoggerFactory.Instance.CreateLogger(typeof(MQTTClient));
}
public MQTTClient(ILogger logger)
{
_logger = logger;
}
public MQTTClient(Uri uri, ILogger logger)
{
_logger = logger;
BrokerUri = uri;
}
public string DeviceId { get; set; } = string.Empty;
public Uri BrokerUri { get; set; }
public bool IsConnected => (Client?.IsConnected).GetValueOrDefault();
private IMqttClient Client { get; set; }
public event EventHandler<RpcRequest> OnExcRpc;
public event EventHandler<AttributeResponse> OnReceiveAttributes;
public Task<bool> ConnectAsync(Uri uri, string accesstoken) => ConnectAsync(uri, accesstoken, null);
public async Task<bool> ConnectAsync(Uri uri, string username, string password)
{
if (BrokerUri == null && uri != null) BrokerUri = uri;
if (BrokerUri != null && uri == null) uri = BrokerUri;
bool initok = false;
try
{
var factory = new MqttFactory();
MqttNetLogger mqttNetLogger = new MqttNetLogger();
mqttNetLogger.LogMessagePublished += MqttNetLogger_LogMessagePublished; ;
Client = factory.CreateMqttClient(mqttNetLogger);
var clientOptions = new MqttClientOptionsBuilder()
.WithClientId(uri.ToString() + Guid.NewGuid().ToString())
.WithTcpServer(uri.Host, uri.Port)
.WithCredentials(username, password)
.Build();
Client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(args => Client_ApplicationMessageReceived(Client, args));
Client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(args => Client_ConnectedAsync(Client, args));
Client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(async e =>
{
try
{
await Client.ConnectAsync(clientOptions);
}
catch (Exception exception)
{
_logger.LogError("CONNECTING FAILED", exception);
}
});
try
{
var result = await Client.ConnectAsync(clientOptions);
initok = result.ResultCode == MqttClientConnectResultCode.Success;
}
catch (Exception exception)
{
_logger.LogError("CONNECTING FAILED", exception);
}
_logger.LogInformation("WAITING FOR APPLICATION MESSAGES");
}
catch (Exception exception)
{
_logger.LogError("CONNECTING FAILED", exception);
}
return initok;
}
private void MqttNetLogger_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
{
}
private void Client_ConnectedAsync(object sender, MqttClientConnectedEventArgs e)
{
Client.SubscribeAsync($"/devices/{DeviceId}/rpc/request/+/+");
Client.SubscribeAsync($"/devices/{DeviceId}/attributes/update/", MqttQualityOfServiceLevel.ExactlyOnce);
_logger.LogInformation($"CONNECTED WITH SERVER ");
}
private void Client_ApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
_logger.LogDebug($"ApplicationMessageReceived Topic {e.ApplicationMessage.Topic} QualityOfServiceLevel:{e.ApplicationMessage.QualityOfServiceLevel} Retain:{e.ApplicationMessage.Retain} ");
try
{
if (e.ApplicationMessage.Topic.StartsWith($"/devices/") && e.ApplicationMessage.Topic.Contains("/response/"))
{
ReceiveAttributes(e);
}
else if (e.ApplicationMessage.Topic.StartsWith($"/devices/") && e.ApplicationMessage.Topic.Contains("/rpc/request/"))
{
var tps = e.ApplicationMessage.Topic.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var rpcmethodname = tps[4];
var rpcdevicename = tps[1];
var rpcrequestid = tps[5];
_logger.LogInformation($"rpcmethodname={rpcmethodname} ");
_logger.LogInformation($"rpcdevicename={rpcdevicename } ");
_logger.LogInformation($"rpcrequestid={rpcrequestid} ");
if (!string.IsNullOrEmpty(rpcmethodname) && !string.IsNullOrEmpty(rpcdevicename) && !string.IsNullOrEmpty(rpcrequestid))
{
OnExcRpc?.Invoke(Client, new RpcRequest()
{
Method = rpcmethodname,
DeviceId = rpcdevicename,
RequestId = rpcrequestid,
Params = e.ApplicationMessage.ConvertPayloadToString()
});
}
}
}
catch (Exception ex)
{
_logger.LogError($"ClientId:{e.ClientId} Topic:{e.ApplicationMessage.Topic},Payload:{e.ApplicationMessage.ConvertPayloadToString()}", ex);
}
}
private void ReceiveAttributes(MqttApplicationMessageReceivedEventArgs e)
{
var tps = e.ApplicationMessage.Topic.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var rpcmethodname = tps[2];
var rpcdevicename = tps[1];
var rpcrequestid = tps[4];
_logger.LogInformation($"rpcmethodname={rpcmethodname} ");
_logger.LogInformation($"rpcdevicename={rpcdevicename } ");
_logger.LogInformation($"rpcrequestid={rpcrequestid} ");
if (!string.IsNullOrEmpty(rpcmethodname) && !string.IsNullOrEmpty(rpcdevicename) && !string.IsNullOrEmpty(rpcrequestid))
{
if (e.ApplicationMessage.Topic.Contains("/attributes/"))
{
OnReceiveAttributes?.Invoke(Client, new AttributeResponse()
{
KeyName = rpcmethodname,
DeviceName = rpcdevicename,
Id = rpcrequestid,
Data = e.ApplicationMessage.ConvertPayloadToString()
});
}
}
}
public Task UploadAttributeAsync(object obj) => UploadAttributeAsync("me", obj);
public Task UploadAttributeAsync(string _devicename, object obj)
{
return Client.PublishAsync($"devices/{_devicename}/attributes", Newtonsoft.Json.JsonConvert.SerializeObject(obj));
}
public Task UploadTelemetryDataAsync(object obj) => UploadTelemetryDataAsync("me", obj);
public Task UploadTelemetryDataAsync(string _devicename, object obj)
{
return Client.PublishAsync($"devices/{_devicename}/telemetry", Newtonsoft.Json.JsonConvert.SerializeObject(obj));
}
public Task ResponseExecommand(RpcResponse rpcResult)
{
///IoTSharp/Clients/RpcClient.cs#L65 var responseTopic = $"/devices/{deviceid}/rpc/response/{methodName}/{rpcid}";
string topic = $"/devices/{rpcResult.DeviceId}/rpc/response/{rpcResult.Method.ToString()}/{rpcResult.ResponseId}";
return Client.PublishAsync(topic, rpcResult.Data.ToString(), MqttQualityOfServiceLevel.ExactlyOnce);
}
public Task RequestAttributes(params string[] args) => RequestAttributes("me", false, args);
public Task RequestAttributes(string _device, params string[] args) => RequestAttributes(_device, false, args);
public Task RequestAttributes(bool anySide = true, params string[] args) => RequestAttributes("me", true, args);
public Task RequestAttributes(string _device, bool anySide , params string[] args)
{
string id = Guid.NewGuid().ToString();
string topic = $"devices/{_device}/attributes/request/{id}";
Dictionary<string, string> keys = new Dictionary<string, string>();
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);
}
}
public class RpcRequest
{
public string DeviceId { get; set; }
public string Method { get; set; }
public string RequestId { get; set; }
public string Params { get; set; }
}
public class RpcResponse
{
public string DeviceId { get; set; }
public string Method { get; set; }
public string ResponseId { get; set; }
public string Data { get; set; }
}
public class AttributeResponse
{
public string Id { get; set; }
public string DeviceName { get; set; }
public string KeyName { get; set; }
public string Data { get; set; }
}
}

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D5C97089-F896-436D-8E99-27B2E43BC65F}"
ProjectSection(SolutionItems) = preProject
appveyor.yml = appveyor.yml
GitVersion.yml = GitVersion.yml
LICENSE = LICENSE
README.md = README.md
roadmap.md = roadmap.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoAPClient", "Clients\CoAPClient\CoAPClient.csproj", "{EE801BD6-5757-4A55-BC94-7FBA6E98F393}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTClient", "Clients\MQTTClient\MQTTClient.csproj", "{E3283D95-51F9-43EE-A49A-BC419B6924DF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT-C-Client", "Clients\MQTT-C-Client\MQTT-C-Client.vcxproj", "{DD36544C-2E7C-4388-B34F-FF705E141E4A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.EdgeSdk.MQTT", "IoTSharp.EdgeSdk.MQTT\IoTSharp.EdgeSdk.MQTT.csproj", "{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.Edge.ModBus", "IoTSharp.Edge.ModBus\IoTSharp.Edge.ModBus.csproj", "{9267A0CE-ECBC-41E4-AD83-927117FD625E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|ARM.ActiveCfg = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|ARM.Build.0 = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|ARM64.Build.0 = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|x64.ActiveCfg = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|x64.Build.0 = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|x86.ActiveCfg = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Debug|x86.Build.0 = Debug|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|Any CPU.Build.0 = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|ARM.ActiveCfg = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|ARM.Build.0 = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|ARM64.ActiveCfg = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|ARM64.Build.0 = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|x64.ActiveCfg = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|x64.Build.0 = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|x86.ActiveCfg = Release|Any CPU
{EE801BD6-5757-4A55-BC94-7FBA6E98F393}.Release|x86.Build.0 = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|ARM.Build.0 = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|ARM64.Build.0 = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|x64.ActiveCfg = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|x64.Build.0 = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|x86.ActiveCfg = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Debug|x86.Build.0 = Debug|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|Any CPU.Build.0 = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|ARM.ActiveCfg = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|ARM.Build.0 = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|ARM64.ActiveCfg = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|ARM64.Build.0 = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|x64.ActiveCfg = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|x64.Build.0 = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|x86.ActiveCfg = Release|Any CPU
{E3283D95-51F9-43EE-A49A-BC419B6924DF}.Release|x86.Build.0 = Release|Any CPU
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|Any CPU.ActiveCfg = Debug|x86
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|ARM.ActiveCfg = Debug|ARM
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|ARM.Build.0 = Debug|ARM
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|ARM.Deploy.0 = Debug|ARM
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|ARM64.ActiveCfg = Debug|ARM64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|ARM64.Build.0 = Debug|ARM64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|ARM64.Deploy.0 = Debug|ARM64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|x64.ActiveCfg = Debug|x64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|x64.Build.0 = Debug|x64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|x64.Deploy.0 = Debug|x64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|x86.ActiveCfg = Debug|x86
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|x86.Build.0 = Debug|x86
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Debug|x86.Deploy.0 = Debug|x86
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|Any CPU.ActiveCfg = Release|x86
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|ARM.ActiveCfg = Release|ARM
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|ARM.Build.0 = Release|ARM
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|ARM.Deploy.0 = Release|ARM
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|ARM64.ActiveCfg = Release|ARM64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|ARM64.Build.0 = Release|ARM64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|ARM64.Deploy.0 = Release|ARM64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|x64.ActiveCfg = Release|x64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|x64.Build.0 = Release|x64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|x64.Deploy.0 = Release|x64
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|x86.ActiveCfg = Release|x86
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|x86.Build.0 = Release|x86
{DD36544C-2E7C-4388-B34F-FF705E141E4A}.Release|x86.Deploy.0 = Release|x86
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|ARM.ActiveCfg = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|ARM.Build.0 = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|ARM64.Build.0 = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|x64.ActiveCfg = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|x64.Build.0 = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|x86.ActiveCfg = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Debug|x86.Build.0 = Debug|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|Any CPU.Build.0 = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|ARM.ActiveCfg = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|ARM.Build.0 = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|ARM64.ActiveCfg = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|ARM64.Build.0 = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|x64.ActiveCfg = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|x64.Build.0 = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|x86.ActiveCfg = Release|Any CPU
{FE56C09F-89F0-4AC5-8615-AFBB4C23F937}.Release|x86.Build.0 = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|ARM.Build.0 = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|ARM64.Build.0 = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|x64.ActiveCfg = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|x64.Build.0 = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|x86.ActiveCfg = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Debug|x86.Build.0 = Debug|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|Any CPU.Build.0 = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|ARM.ActiveCfg = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|ARM.Build.0 = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|ARM64.ActiveCfg = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|ARM64.Build.0 = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|x64.ActiveCfg = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|x64.Build.0 = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|x86.ActiveCfg = Release|Any CPU
{9267A0CE-ECBC-41E4-AD83-927117FD625E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CD7ADD62-E3BD-453A-B653-BC70DB9FF817}
EndGlobalSection
EndGlobal
......@@ -44,6 +44,8 @@ services:
- 1883:1883
- 8883:8883
- 8080:8080
- 5683:5683
- 5684:5684
- 502:502
networks:
- iotsharp-network
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册