From 2ef541d72f2bf5c99e7993ff0dfbc510b98d41a4 Mon Sep 17 00:00:00 2001 From: Chris Kaczor Date: Mon, 4 Mar 2024 16:32:33 -0500 Subject: [PATCH] Fix models in environment service and add more SignalR messaging --- Environment/Service/MessageHandler.cs | 36 +++++++++++++++++-- .../Service/Models/Indoor/DeviceMessage.cs | 7 ++++ Environment/Service/Models/Readings.cs | 33 ++++++++++++++++- Environment/Service/Models/ReadingsGrouped.cs | 10 ++++++ .../Service/Properties/launchSettings.json | 3 +- Hub/Service/.vscode/launch.json | 2 +- Hub/Service/Hubs/EnvironmentHub.cs | 12 +++++-- 7 files changed, 96 insertions(+), 7 deletions(-) diff --git a/Environment/Service/MessageHandler.cs b/Environment/Service/MessageHandler.cs index 027a41b..b14b8e4 100644 --- a/Environment/Service/MessageHandler.cs +++ b/Environment/Service/MessageHandler.cs @@ -1,4 +1,5 @@ using ChrisKaczor.HomeMonitor.Environment.Service.Data; +using ChrisKaczor.HomeMonitor.Environment.Service.Models; using ChrisKaczor.HomeMonitor.Environment.Service.Models.Indoor; using Microsoft.AspNetCore.SignalR.Client; using MQTTnet; @@ -41,8 +42,12 @@ public class MessageHandler : IHostedService public async Task StartAsync(CancellationToken cancellationToken) { if (_hubConnection != null) + { await _hubConnection.StartAsync(cancellationToken); + _hubConnection.On("RequestLatest", SendStoredMessage); + } + var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer(_configuration["Mqtt:Server"]).Build(); await _mqttClient.ConnectAsync(mqttClientOptions, cancellationToken); @@ -85,9 +90,36 @@ public class MessageHandler : IHostedService if (_hubConnection.State == HubConnectionState.Disconnected) await _hubConnection.StartAsync(); - var json = JsonSerializer.Serialize(message); + var deviceReadings = new Readings(message); - await _hubConnection.InvokeAsync("SendMessage", json); + var json = JsonSerializer.Serialize(deviceReadings); + + await _hubConnection.InvokeAsync("SendLatest", json); + } + catch (Exception exception) + { + WriteLog($"Hub exception: {exception}"); + } + } + + private async Task SendStoredMessage() + { + try + { + if (_hubConnection == null) + return; + + if (_hubConnection.State == HubConnectionState.Disconnected) + await _hubConnection.StartAsync(); + + var recentReadings = await _database.GetRecentReadings(); + + foreach (var recentReading in recentReadings) + { + var json = JsonSerializer.Serialize(recentReading); + + await _hubConnection.InvokeAsync("SendLatest", json); + } } catch (Exception exception) { diff --git a/Environment/Service/Models/Indoor/DeviceMessage.cs b/Environment/Service/Models/Indoor/DeviceMessage.cs index d455c04..ec8a294 100644 --- a/Environment/Service/Models/Indoor/DeviceMessage.cs +++ b/Environment/Service/Models/Indoor/DeviceMessage.cs @@ -16,17 +16,24 @@ public class DeviceMessage [JsonPropertyName("timestamp")] public required DateTimeOffset Timestamp { get; set; } + [JsonPropertyName("air_quality_index")] public decimal AirQualityIndex => Readings.AirQualityIndex; + [JsonPropertyName("color_temperature")] public decimal ColorTemperature => Readings.ColorTemperature; + [JsonPropertyName("gas_resistance")] public decimal GasResistance => Readings.GasResistance; + [JsonPropertyName("humidity")] public decimal Humidity => Readings.Humidity; + [JsonPropertyName("luminance")] public decimal Luminance => Readings.Luminance; + [JsonPropertyName("pressure")] public decimal Pressure => Readings.Pressure; + [JsonPropertyName("temperature")] public decimal Temperature => Readings.Temperature; } \ No newline at end of file diff --git a/Environment/Service/Models/Readings.cs b/Environment/Service/Models/Readings.cs index 8c583ab..717527e 100644 --- a/Environment/Service/Models/Readings.cs +++ b/Environment/Service/Models/Readings.cs @@ -1,24 +1,55 @@ -namespace ChrisKaczor.HomeMonitor.Environment.Service.Models; +using ChrisKaczor.HomeMonitor.Environment.Service.Models.Indoor; +using System.Text.Json.Serialization; + +namespace ChrisKaczor.HomeMonitor.Environment.Service.Models; public class Readings { + public Readings() + { + } + + public Readings(DeviceMessage message) + { + Time = message.Timestamp; + Name = message.Name; + Model = message.Model; + AirQualityIndex = message.AirQualityIndex; + ColorTemperature = message.ColorTemperature; + GasResistance = message.GasResistance; + Humidity = message.Humidity; + Luminance = message.Luminance; + Pressure = message.Pressure; + Temperature = message.Temperature; + } + + [JsonPropertyName("time")] public DateTimeOffset Time { get; set; } + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("model")] public string? Model { get; set; } + [JsonPropertyName("airQualityIndex")] public decimal AirQualityIndex { get; set; } + [JsonPropertyName("colorTemperature")] public decimal ColorTemperature { get; set; } + [JsonPropertyName("gasResistance")] public decimal GasResistance { get; set; } + [JsonPropertyName("humidity")] public decimal Humidity { get; set; } + [JsonPropertyName("luminance")] public decimal Luminance { get; set; } + [JsonPropertyName("pressure")] public decimal Pressure { get; set; } + [JsonPropertyName("temperature")] public decimal Temperature { get; set; } } \ No newline at end of file diff --git a/Environment/Service/Models/ReadingsGrouped.cs b/Environment/Service/Models/ReadingsGrouped.cs index 5c3d9bb..6f72bd9 100644 --- a/Environment/Service/Models/ReadingsGrouped.cs +++ b/Environment/Service/Models/ReadingsGrouped.cs @@ -1,25 +1,35 @@ using JetBrains.Annotations; +using System.Text.Json.Serialization; namespace ChrisKaczor.HomeMonitor.Environment.Service.Models; [PublicAPI] public class ReadingsGrouped { + [JsonPropertyName("bucket")] public DateTimeOffset Bucket { get; set; } + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("averageTemperature")] public decimal AverageTemperature { get; set; } + [JsonPropertyName("averagePressure")] public decimal AveragePressure { get; set; } + [JsonPropertyName("averageHumidity")] public decimal AverageHumidity { get; set; } + [JsonPropertyName("averageLuminance")] public decimal AverageLuminance { get; set; } + [JsonPropertyName("averageGasResistance")] public decimal AverageGasResistance { get; set; } + [JsonPropertyName("averageColorTemperature")] public decimal AverageColorTemperature { get; set; } + [JsonPropertyName("averageAirQualityIndex")] public decimal AverageAirQualityIndex { get; set; } } \ No newline at end of file diff --git a/Environment/Service/Properties/launchSettings.json b/Environment/Service/Properties/launchSettings.json index 2ca9931..ce1fdc9 100644 --- a/Environment/Service/Properties/launchSettings.json +++ b/Environment/Service/Properties/launchSettings.json @@ -4,7 +4,8 @@ "commandName": "Project", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "applicationUrl": "http://localhost:5050" } } } \ No newline at end of file diff --git a/Hub/Service/.vscode/launch.json b/Hub/Service/.vscode/launch.json index 5c2caea..b2d68b9 100644 --- a/Hub/Service/.vscode/launch.json +++ b/Hub/Service/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/bin/Debug/net5.0/ChrisKaczor.HomeMonitor.Hub.Service.dll", + "program": "${workspaceFolder}/bin/Debug/net8.0/ChrisKaczor.HomeMonitor.Hub.Service.dll", "args": [], "cwd": "${workspaceFolder}", "stopAtEntry": false, diff --git a/Hub/Service/Hubs/EnvironmentHub.cs b/Hub/Service/Hubs/EnvironmentHub.cs index d87767d..77bb19c 100644 --- a/Hub/Service/Hubs/EnvironmentHub.cs +++ b/Hub/Service/Hubs/EnvironmentHub.cs @@ -9,11 +9,19 @@ namespace ChrisKaczor.HomeMonitor.Hub.Service.Hubs public class EnvironmentHub(ILogger logger) : Microsoft.AspNetCore.SignalR.Hub { [UsedImplicitly] - public async Task SendMessage(string message) + public async Task SendLatest(string message) { logger.LogInformation(message); - await Clients.Others.SendAsync("Message", message); + await Clients.Others.SendAsync("Latest", message); + } + + [UsedImplicitly] + public async Task RequestLatest() + { + logger.LogInformation("RequestLatest"); + + await Clients.Others.SendAsync("RequestLatest"); } } } \ No newline at end of file