From f730b2a954877bb18a577e3afaff89635cedac87 Mon Sep 17 00:00:00 2001 From: Dave Thaler Date: Sun, 16 Jun 2024 09:34:05 -0700 Subject: [PATCH] Add dataplicity events (#52) Signed-off-by: Dave Thaler --- OrcanodeMonitor/Core/Fetcher.cs | 61 +++++++++++++++++++++++-- OrcanodeMonitor/Models/Orcanode.cs | 2 +- OrcanodeMonitor/Models/OrcanodeEvent.cs | 20 ++++++-- OrcanodeMonitor/Pages/Index.cshtml | 2 +- OrcanodeMonitor/Pages/Index.cshtml.cs | 2 +- 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/OrcanodeMonitor/Core/Fetcher.cs b/OrcanodeMonitor/Core/Fetcher.cs index a0a5e89..d57195b 100644 --- a/OrcanodeMonitor/Core/Fetcher.cs +++ b/OrcanodeMonitor/Core/Fetcher.cs @@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Mvc; using System.Net; using OrcanodeMonitor.Api; +using Newtonsoft.Json.Linq; namespace OrcanodeMonitor.Core { @@ -48,17 +49,26 @@ private static bool NameMatch(string name, string dataplicityName) return false; } - private static Orcanode FindOrCreateOrcanodeByDataplicitySerial(DbSet nodeList, string serial) + /// + /// Find or create a node using the serial number value at Dataplicity. + /// + /// Database table to look in and potentially update + /// Dataplicity serial number to look for + /// Dataplicity connection status + /// + private static Orcanode FindOrCreateOrcanodeByDataplicitySerial(DbSet nodeList, string serial, out OrcanodeOnlineStatus connectionStatus) { List nodes = nodeList.ToList(); foreach (Orcanode node in nodes) { if (node.DataplicitySerial == serial) { + connectionStatus = node.DataplicityConnectionStatus; return node; } } + connectionStatus = OrcanodeOnlineStatus.Absent; var newNode = new Orcanode(); newNode.DataplicitySerial = serial; @@ -220,7 +230,11 @@ public async static Task UpdateDataplicityDataAsync(OrcanodeMonitorContext conte { continue; } - Orcanode node = FindOrCreateOrcanodeByDataplicitySerial(context.Orcanodes, serial.ToString()); + + Orcanode node = FindOrCreateOrcanodeByDataplicitySerial(context.Orcanodes, serial.ToString(), out OrcanodeOnlineStatus oldStatus); + OrcanodeUpgradeStatus oldAgentUpgradeStatus = node.DataplicityUpgradeStatus; + long oldDiskCapacityInGigs = node.DiskCapacityInGigs; + if (device.TryGetProperty("name", out var name)) { string dataplicityName = name.ToString(); @@ -254,6 +268,24 @@ public async static Task UpdateDataplicityDataAsync(OrcanodeMonitorContext conte { node.DataplicityUpgradeAvailable = upgradeAvailable.GetBoolean(); } + + // Trigger any event changes. + OrcanodeOnlineStatus newStatus = node.DataplicityConnectionStatus; + if (newStatus != oldStatus) + { + AddDataplicityConnectionStatusEvent(context, node); + } + if (oldStatus != OrcanodeOnlineStatus.Absent) + { + if (oldAgentUpgradeStatus != node.DataplicityUpgradeStatus) + { + AddDataplicityAgentUpgradeStatusChangeEvent(context, node); + } + if (oldDiskCapacityInGigs != node.DiskCapacityInGigs) + { + AddDiskCapacityChangeEvent(context, node); + } + } } MonitorState.GetFrom(context).LastUpdatedTimestampUtc = DateTime.UtcNow; @@ -434,7 +466,28 @@ public static List GetEvents(OrcanodeMonitorContext context, int return orcanodeEvents; } - private static void AddOrcanodeStreamStatusEvent(OrcanodeMonitorContext context, Orcanode node) + private static void AddDataplicityConnectionStatusEvent(OrcanodeMonitorContext context, Orcanode node) + { + string value = (node.DataplicityConnectionStatus == OrcanodeOnlineStatus.Online) ? "up" : "OFFLINE"; + var orcanodeEvent = new OrcanodeEvent(node, "dataplicity connection", value, DateTime.UtcNow); + context.OrcanodeEvents.Add(orcanodeEvent); + } + + private static void AddDataplicityAgentUpgradeStatusChangeEvent(OrcanodeMonitorContext context, Orcanode node) + { + string value = node.DataplicityUpgradeStatus.ToString(); + var orcanodeEvent = new OrcanodeEvent(node, "agent upgrade status", value, DateTime.UtcNow); + context.OrcanodeEvents.Add(orcanodeEvent); + } + + private static void AddDiskCapacityChangeEvent(OrcanodeMonitorContext context, Orcanode node) + { + string value = string.Format("{0}G", node.DiskCapacityInGigs); + var orcanodeEvent = new OrcanodeEvent(node, "SD card size", value, DateTime.UtcNow); + context.OrcanodeEvents.Add(orcanodeEvent); + } + + private static void AddHydrophoneStreamStatusEvent(OrcanodeMonitorContext context, Orcanode node) { string value = (node.OrcasoundOnlineStatus == OrcanodeOnlineStatus.Online) ? "up" : "OFFLINE"; var orcanodeEvent = new OrcanodeEvent(node, "hydrophone stream", value, DateTime.UtcNow); @@ -472,7 +525,7 @@ public async static Task UpdateManifestTimestampAsync(OrcanodeMonitorContext con OrcanodeOnlineStatus newStatus = node.OrcasoundOnlineStatus; if (newStatus != oldStatus) { - AddOrcanodeStreamStatusEvent(context, node); + AddHydrophoneStreamStatusEvent(context, node); } } diff --git a/OrcanodeMonitor/Models/Orcanode.cs b/OrcanodeMonitor/Models/Orcanode.cs index b93f96a..942daeb 100644 --- a/OrcanodeMonitor/Models/Orcanode.cs +++ b/OrcanodeMonitor/Models/Orcanode.cs @@ -199,7 +199,7 @@ public static string DataplicityNameToDisplayName(string dataplicityName) public bool? DataplicityOnline { get; set; } public bool? DataplicityUpgradeAvailable { get; set; } public OrcanodeUpgradeStatus DataplicityUpgradeStatus => DataplicityUpgradeAvailable ?? false ? OrcanodeUpgradeStatus.UpgradeAvailable : OrcanodeUpgradeStatus.UpToDate; - public OrcanodeOnlineStatus DataplicityStatus => DataplicityOnline ?? false ? OrcanodeOnlineStatus.Online : OrcanodeOnlineStatus.Offline; + public OrcanodeOnlineStatus DataplicityConnectionStatus => DataplicityOnline ?? false ? OrcanodeOnlineStatus.Online : OrcanodeOnlineStatus.Offline; #if ORCAHELLO public string OrcaHelloName { diff --git a/OrcanodeMonitor/Models/OrcanodeEvent.cs b/OrcanodeMonitor/Models/OrcanodeEvent.cs index cd3e8a0..5cd26f3 100644 --- a/OrcanodeMonitor/Models/OrcanodeEvent.cs +++ b/OrcanodeMonitor/Models/OrcanodeEvent.cs @@ -73,7 +73,7 @@ public OrcanodeEvent(Orcanode node, string type, string value, DateTime timestam /// [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } - + public string Slug { get; set; } public string Type { get; set; } public string Value { get; set; } @@ -93,9 +93,23 @@ public OrcanodeEvent(Orcanode node, string type, string value, DateTime timestam public override string ToString() { - return string.Format("{0} {1} {2} at {3}", Slug, Type, Value, Fetcher.UtcToLocalDateTime(DateTimeUtc)); + return string.Format("{0} {1} => {2} at {3}", Slug, Type, Value, Fetcher.UtcToLocalDateTime(DateTimeUtc)); } - public string Description => string.Format("{0} hydrophone stream was detected as {1}", NodeName, Value); + public string Description + { + get + { + // Convert type from old value to new value. + // TODO: do a migration in the database itself and remove this code. + string type = Type; + if (type == "stream status") + { + type = "hydrophone stream"; + } + + return string.Format("{0} {1} was detected as {2}", NodeName, type, Value); + } + } } } diff --git a/OrcanodeMonitor/Pages/Index.cshtml b/OrcanodeMonitor/Pages/Index.cshtml index 2228683..b2165e0 100644 --- a/OrcanodeMonitor/Pages/Index.cshtml +++ b/OrcanodeMonitor/Pages/Index.cshtml @@ -50,7 +50,7 @@ --> - @Html.DisplayFor(modelItem => item.DataplicityStatus) + @Html.DisplayFor(modelItem => item.DataplicityConnectionStatus) diff --git a/OrcanodeMonitor/Pages/Index.cshtml.cs b/OrcanodeMonitor/Pages/Index.cshtml.cs index 90f3b08..31a72af 100644 --- a/OrcanodeMonitor/Pages/Index.cshtml.cs +++ b/OrcanodeMonitor/Pages/Index.cshtml.cs @@ -50,7 +50,7 @@ public string NodeOrcasoundColor(Orcanode node) public string NodeDataplicityColor(Orcanode node) { - OrcanodeOnlineStatus status = node.DataplicityStatus; + OrcanodeOnlineStatus status = node.DataplicityConnectionStatus; if (status == OrcanodeOnlineStatus.Offline) { return ColorTranslator.ToHtml(Color.Red);