diff --git a/NucuCar.Sensors/EnvironmentSensor/Sensor.cs b/NucuCar.Sensors/EnvironmentSensor/Sensor.cs index c505fe1..5246696 100644 --- a/NucuCar.Sensors/EnvironmentSensor/Sensor.cs +++ b/NucuCar.Sensors/EnvironmentSensor/Sensor.cs @@ -109,12 +109,12 @@ namespace NucuCar.Sensors.EnvironmentSensor return nameof(EnvironmentSensor); } - public Dictionary GetTelemetryData() + public Dictionary GetTelemetryData() { - Dictionary returnValue = null; + Dictionary returnValue = null; if (_lastMeasurement != null) { - returnValue = new Dictionary + returnValue = new Dictionary { ["temperature"] = _lastMeasurement.Temperature, ["humidity"] = _lastMeasurement.Humidity, diff --git a/NucuCar.Sensors/NucuCar.Sensors.csproj b/NucuCar.Sensors/NucuCar.Sensors.csproj index 7161607..a28e41f 100644 --- a/NucuCar.Sensors/NucuCar.Sensors.csproj +++ b/NucuCar.Sensors/NucuCar.Sensors.csproj @@ -10,9 +10,8 @@ + - - diff --git a/NucuCar.Sensors/Telemetry/BackgroundWorker.cs b/NucuCar.Sensors/Telemetry/BackgroundWorker.cs index b3f2d6e..ae26948 100644 --- a/NucuCar.Sensors/Telemetry/BackgroundWorker.cs +++ b/NucuCar.Sensors/Telemetry/BackgroundWorker.cs @@ -8,11 +8,7 @@ namespace NucuCar.Sensors.Telemetry { public class BackgroundWorker : BackgroundService { - private readonly string _projectId; - private readonly string _region; - private readonly string _registryId; - private readonly string _deviceId; - private readonly string _rs256KeyFile; + private readonly string _azureIotHubConnectionString; private readonly bool _serviceEnabled; private readonly int _interval; private readonly ILogger _logger; @@ -20,14 +16,9 @@ namespace NucuCar.Sensors.Telemetry public BackgroundWorker(ILogger logger, IConfiguration configuration) { _logger = logger; - var configSection = configuration.GetSection("Telemetry"); - _serviceEnabled = configSection.GetValue("Enabled"); - _interval = configSection.GetValue("Interval"); - _projectId = configSection.GetValue("ProjectId"); - _region = configSection.GetValue("Region"); - _registryId = configSection.GetValue("RegistryId"); - _deviceId = configSection.GetValue("DeviceId"); - _rs256KeyFile = configSection.GetValue("RS256File"); + _serviceEnabled = configuration.GetValue("Telemetry:Enabled"); + _interval = configuration.GetValue("Telemetry:Interval"); + _azureIotHubConnectionString = configuration.GetValue("Telemetry:AzureIotHubConnectionString"); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) @@ -42,13 +33,9 @@ namespace NucuCar.Sensors.Telemetry using var telemetryService = TelemetryService.Instance; telemetryService.SetLogger(_logger); - telemetryService.ProjectId = _projectId; - telemetryService.DeviceId = _deviceId; - telemetryService.RegistryId = _registryId; - telemetryService.Region = _region; - telemetryService.Rs256File = _rs256KeyFile; + telemetryService.AzureIotHubConnectionString = _azureIotHubConnectionString; - await telemetryService.StartAsync(); + telemetryService.Start(); while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Publishing telemetry data!"); diff --git a/NucuCar.Sensors/Telemetry/ITelemetrySensor.cs b/NucuCar.Sensors/Telemetry/ITelemetrySensor.cs index afe43a3..e68e6ab 100644 --- a/NucuCar.Sensors/Telemetry/ITelemetrySensor.cs +++ b/NucuCar.Sensors/Telemetry/ITelemetrySensor.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace NucuCar.Sensors.Telemetry @@ -7,6 +6,6 @@ namespace NucuCar.Sensors.Telemetry { string GetIdentifier(); /* Dictionary containing the topic and the value */ - Dictionary GetTelemetryData(); + Dictionary GetTelemetryData(); } } \ No newline at end of file diff --git a/NucuCar.Sensors/Telemetry/TelemetryService.cs b/NucuCar.Sensors/Telemetry/TelemetryService.cs index bb5ae14..1e361d5 100644 --- a/NucuCar.Sensors/Telemetry/TelemetryService.cs +++ b/NucuCar.Sensors/Telemetry/TelemetryService.cs @@ -1,99 +1,49 @@ using System; using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Security.Cryptography; +using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Azure.Devices.Client; using Microsoft.Extensions.Logging; -using MQTTnet; -using MQTTnet.Client.Options; -using MQTTnet.Extensions.ManagedClient; -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.OpenSsl; -using Org.BouncyCastle.Security; +using Newtonsoft.Json; namespace NucuCar.Sensors.Telemetry { public class TelemetryService : IDisposable { private readonly List _registeredSensors; - private readonly IManagedMqttClient _mqttClient; + private DeviceClient _deviceClient; private ILogger _logger; /* Singleton Instance */ public static TelemetryService Instance { get; } = new TelemetryService(); - public string ProjectId { get; set; } - public string Region { get; set; } - public string RegistryId { get; set; } - public string DeviceId { get; set; } - public string Rs256File { get; set; } + public string AzureIotHubConnectionString { get; set; } static TelemetryService() { } - private string GetMqttPassword() - { - string jwt; - AsymmetricCipherKeyPair keyPair; - - using (var sr = new StreamReader(Rs256File)) - { - var pr = new PemReader(sr); - keyPair = (AsymmetricCipherKeyPair) pr.ReadObject(); - } - - var rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyPair.Private); - - using (var rsa = new RSACryptoServiceProvider()) - { - rsa.ImportParameters(rsaParams); - jwt = Jose.JWT.Encode(new Dictionary() - { - ["iat"] = DateTime.UtcNow, - ["exp"] = DateTime.UtcNow.AddDays(60), - ["aud"] = ProjectId - }, rsa, Jose.JwsAlgorithm.RS256); - } - - return jwt; - } private TelemetryService() { _registeredSensors = new List(5); - - _mqttClient = new MqttFactory().CreateManagedMqttClient(); } public void Dispose() { } - public async Task StartAsync() + public void Start() { - _logger.LogInformation("Starting the MQTT client."); - ManagedMqttClientOptions options; try { - options = new ManagedMqttClientOptionsBuilder() - .WithAutoReconnectDelay(TimeSpan.FromSeconds(5)) - .WithClientOptions(new MqttClientOptionsBuilder() - .WithClientId($"projects/{ProjectId}/locations/{Region}/registries/{RegistryId}/devices/{DeviceId}") - .WithCredentials("unused", GetMqttPassword()) - .WithTcpServer("mqtt.googleapis.com") - .WithTls().Build()) - .Build(); + _deviceClient = DeviceClient.CreateFromConnectionString(AzureIotHubConnectionString, TransportType.Mqtt); } - catch (IOException e) + catch (FormatException) { - _logger.LogCritical(e.Message); + _logger.LogCritical("Can't start telemetry service! Malformed connection string!"); throw; } - - await _mqttClient.StartAsync(options); _logger.LogInformation("Started the MQTT client!"); } @@ -107,22 +57,23 @@ namespace NucuCar.Sensors.Telemetry _logger.LogWarning($"Warning! Data for {sensor.GetIdentifier()} is null!"); continue; } + await UploadData(data, cancellationToken); } } - private async Task UploadData(Dictionary data, CancellationToken cancellationToken) + private async Task UploadData(Dictionary data, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { _logger.LogInformation("Stopping the MQTT client, cancellation requested."); - await _mqttClient.StopAsync(); - } - - foreach (var entry in data) - { - await _mqttClient.PublishAsync(entry.Key, entry.Value.ToString(CultureInfo.InvariantCulture)); + await _deviceClient.CloseAsync(cancellationToken); + return; } + var messageString = JsonConvert.SerializeObject(data); + var message = new Message(Encoding.ASCII.GetBytes(messageString)); + _logger.LogDebug($"Telemetry message: {message}"); + await _deviceClient.SendEventAsync(message, cancellationToken); } public void RegisterSensor(ITelemetrySensor sensor) diff --git a/NucuCar.Sensors/appsettings.json b/NucuCar.Sensors/appsettings.json index a7b069d..827d326 100644 --- a/NucuCar.Sensors/appsettings.json +++ b/NucuCar.Sensors/appsettings.json @@ -2,11 +2,7 @@ "Telemetry": { "Enabled": true, "Interval": 3000, - "ProjectId": "playground-239221", - "DeviceId": "3087236321317137", - "RegistryId": "Development", - "Region": "europe-west1", - "RS256File": "/home/denis/Projects/RiderProjects/NucuCar/NucuCar.Sensors/Certificates/jwt.key" + "AzureIotHubConnectionString": "YOUR_IOT_HUB_CONNECTION_STRING" }, "EnvironmentSensor": { "Enabled": true, @@ -26,7 +22,7 @@ "Protocols": "Http2" }, "EndPoints": { - "Https":{ + "Https": { "Url": "https://0.0.0.0:8000" } }