100 Commits
2.0 ... master

Author SHA1 Message Date
Martijn Scheepers
8665a54d6d mobotix viewer telegram messages 2026-03-24 08:00:24 +01:00
Martijn Scheepers
4924a13810 ldap optimazition 2026-03-09 12:03:14 +01:00
Martijn Scheepers
235ca7aa81 fix test 2026-03-09 11:40:38 +01:00
Martijn Scheepers
b0e5f32d13 update nuget packages 2026-03-09 11:36:19 +01:00
Martijn Scheepers
1aad8a476b Update nuget packanges 2026-03-09 11:33:01 +01:00
Martijn Scheepers
82eb700776 add metrics 2026-01-08 13:53:23 +01:00
Martijn Scheepers
bd0ad8c1b5 windows login test 2026-01-08 13:07:26 +01:00
Martijn Scheepers
562a28277b remove sensors 2026-01-06 15:13:08 +01:00
Martijn Scheepers
c3fc3de8c8 clean up 2026-01-06 15:04:01 +01:00
Martijn Scheepers
34e92ff8c9 remove last will with delete 2026-01-05 13:37:42 +01:00
Martijn Scheepers
6c516c19b4 test 2025-12-03 15:09:39 +01:00
Martijn Scheepers
4854b7272c Send remove message 2025-12-03 13:47:31 +01:00
Martijn Scheepers
fe1fce12bb Bot answer test 2025-12-03 13:47:18 +01:00
Martijn Scheepers
25ac08b4d0 Use telegram message channel 2025-12-02 15:51:43 +01:00
Martijn Scheepers
4e26ff8d12 changed to Ihostedservice, removed the while loop 2025-12-02 11:43:47 +01:00
Martijn Scheepers
1c89154197 Getdevice with generic 2025-12-02 10:33:25 +01:00
Martijn Scheepers
ee40e504cc Change cookie name 2025-12-02 09:38:33 +01:00
Martijn Scheepers
d55865f7e4 fix name 2025-12-02 09:26:31 +01:00
Martijn Scheepers
24cee0af4d Fix warnings in test 2025-12-02 09:22:05 +01:00
Martijn Scheepers
5465551d13 do not update connection state with status message 2025-12-02 09:07:05 +01:00
Martijn Scheepers
5f4d64ba91 update publish to .net10 2025-11-13 15:46:26 +01:00
Martijn Scheepers
9e83c0d69b Update to .net 10 2025-11-13 15:13:55 +01:00
Martijn Scheepers
fe04e0ebf8 Update telegram bot 2025-11-10 09:29:45 +01:00
Martijn Scheepers
06bcb507b7 axis cam test 2025-11-06 13:12:54 +01:00
Martijn Scheepers
dbcfce9bf4 remove prtg/wsen 2025-11-06 09:51:33 +01:00
Martijn Scheepers
3e10acadba DI monitor devices 2025-11-06 09:47:00 +01:00
Martijn Scheepers
cb241b2290 clean up 2025-11-06 08:41:45 +01:00
Martijn Scheepers
c06f1fee93 remove unused packages 2025-11-06 08:23:12 +01:00
Martijn Scheepers
db20b3eedc Update telegram bot 2025-11-06 08:11:48 +01:00
Martijn Scheepers
5cbcc6d08f Fix UCSSystem status change 2025-11-05 15:09:48 +01:00
Martijn Scheepers
b786455bbf Changed cookie name 2025-10-27 14:07:56 +01:00
Martijn Scheepers
14a18b0a6b Check for name also in connectionstates 2025-10-15 09:50:23 +02:00
Martijn Scheepers
d335a03c72 update nuget packages 2025-10-15 09:23:25 +02:00
Martijn Scheepers
cbc9463e14 Format date time 2025-10-15 08:30:18 +02:00
Martijn Scheepers
84693aab7d Add monitordevice timeout on page 2025-10-14 14:38:07 +02:00
Martijn Scheepers
37d569e21d add missing interface 2025-10-14 12:32:12 +02:00
Martijn Scheepers
d7696c6053 Add telegram bot 2025-10-14 12:27:59 +02:00
Martijn Scheepers
23c3e27008 cleared some warnings 2025-10-14 11:02:01 +02:00
Martijn Scheepers
ef96c0b32c clean up 2025-10-14 10:10:17 +02:00
Martijn Scheepers
2a301356ae Code cleanup 2025-10-14 09:58:39 +02:00
Martijn Scheepers
403ec19322 monitor devices with interfaces 2025-10-14 09:45:52 +02:00
Martijn Scheepers
f73bfc7d0c Add tests 2025-10-08 11:32:18 +02:00
Martijn Scheepers
3cd65eb37e update nuget packages 2025-06-13 09:41:12 +02:00
Martijn Scheepers
144c3c3eb6 Make usage value bigger 2025-05-26 15:27:12 +02:00
Martijn Scheepers
1a9d40a4be Add ucsdevice message for mobotix video players 2025-05-01 09:41:19 +02:00
Martijn Scheepers
efc5a13605 Update nuget packages 2025-05-01 08:07:30 +02:00
Martijn Scheepers
87f90cae80 Remove dataprotection add antiforgy token to login 2025-03-13 11:07:11 +01:00
Martijn Scheepers
c10187c024 Update nuget packages 2025-03-13 09:59:21 +01:00
Martijn Scheepers
c4e25cf209 Use tryparse exact for all date's 2025-03-05 12:05:16 +01:00
Martijn Scheepers
8f838948a0 Use tryparseexact 2025-03-05 11:39:25 +01:00
Martijn Scheepers
5f59389c24 disable debug line 2025-03-05 11:11:34 +01:00
Martijn Scheepers
9d9adddab1 Use tryparse 2025-03-05 11:10:50 +01:00
Martijn Scheepers
5829b1decf Dispose certs 2025-03-05 10:35:33 +01:00
Martijn Scheepers
6f0040864f Mqtt cert via appsettings 2025-03-05 09:56:28 +01:00
Martijn Scheepers
c8cf2f9c2f Key location for server 2025-03-05 09:09:42 +01:00
Martijn Scheepers
451113c9fb add keys to location from appconfig 2025-03-05 09:02:41 +01:00
Martijn Scheepers
9fe0d9f480 Use the same namespace 2025-03-04 13:11:50 +01:00
Martijn Scheepers
e11e735b15 Fix ldap test 2025-03-04 13:08:32 +01:00
Martijn Scheepers
9f5404b75d add AllowAnonymous 2025-03-04 12:27:22 +01:00
Martijn Scheepers
dce9f1d1d6 Use certificateloader 2025-03-04 11:38:50 +01:00
Martijn Scheepers
514da8e58a Use endpoints direct 2025-03-04 11:27:00 +01:00
Martijn Scheepers
f49c617362 axis cams have grid and list 2025-03-04 08:23:56 +01:00
Martijn Scheepers
b97cc0b19b Use after render 2025-02-24 08:32:20 +01:00
Martijn Scheepers
fb75623b78 use <li> 2025-02-24 08:07:49 +01:00
Martijn Scheepers
c53746c46f Changed to .net9 2025-02-21 13:17:21 +01:00
Martijn Scheepers
90438079c4 to afterrender 2025-02-21 13:13:23 +01:00
Martijn Scheepers
04e5ad53ed better sorting 2025-02-21 12:40:09 +01:00
Martijn Scheepers
47cfbf245e data loading in onafterrender 2025-02-21 11:06:31 +01:00
Martijn Scheepers
ebc9eb9323 save 2025-02-20 15:28:55 +01:00
Martijn Scheepers
0c3247df6e Add router sorting 2025-02-20 15:06:41 +01:00
Martijn Scheepers
f707a130a0 Remove router function 2025-02-19 09:05:12 +01:00
Martijn Scheepers
ab30ac4005 Update axis mqtt messages 2025-01-21 14:15:53 +01:00
Martijn Scheepers
0740c0569f Update 2025-01-08 13:34:48 +01:00
Martijn Scheepers
21054c4687 Update mqttnet package 2025-01-08 13:27:08 +01:00
Martijn Scheepers
e9fb456d54 Restyle login page 2025-01-08 13:26:46 +01:00
Martijn Scheepers
948c15a051 device change event 2024-12-12 15:03:31 +01:00
Martijn Scheepers
a1e17372e2 Save 2024-12-12 14:18:14 +01:00
Martijn Scheepers
f5da1ed00d Add event log creator tool 2024-12-12 14:01:21 +01:00
Martijn Scheepers
76fc4a8990 Single startup file 2024-12-12 13:44:07 +01:00
Martijn Scheepers
9381b8c502 Moved usc systems to seperate controller 2024-12-12 13:26:59 +01:00
Martijn Scheepers
6ad2f4754f Cleanup 2024-12-12 12:39:10 +01:00
Martijn Scheepers
27171b93da Changes to blazor pages 2024-12-12 12:35:46 +01:00
Martijn Scheepers
f115256bdb fix warnings 2024-12-05 15:25:40 +01:00
Martijn Scheepers
b0b8ecf502 Fixed warnings 2024-12-05 15:06:31 +01:00
Martijn Scheepers
67d5f788a7 Log message via code generator 2024-12-05 14:39:26 +01:00
Martijn Scheepers
47784a7df8 update connection chart 2024-12-02 10:23:25 +01:00
Martijn Scheepers
9d5eb44f7f log connection state 2024-11-29 16:07:19 +01:00
Martijn Scheepers
8bef4bc3c5 A lot of changes 2024-11-29 15:54:42 +01:00
Martijn Scheepers
20a53a9fbe save 2024-11-29 12:19:59 +01:00
Martijn Scheepers
834c64ecbf Reuse db context 2024-11-29 11:31:29 +01:00
Martijn Scheepers
f8730c580a update nuget packages 2024-11-29 10:02:02 +01:00
Martijn Scheepers
ddce2d1de9 online offline fix 2024-11-29 09:59:53 +01:00
Martijn Scheepers
cb4f0bfe3d offline message for axis cams 2024-10-18 09:22:25 +02:00
Martijn Scheepers
4dc6567c2e update ipaddres 2024-08-23 14:14:54 +02:00
Martijn Scheepers
6e2b164763 X64 project 2024-08-20 09:23:05 +02:00
Martijn Scheepers
bd8d8e1c18 update nuget 2024-08-20 09:12:58 +02:00
Martijn Scheepers
7c889ca4d1 extra check 2024-08-20 08:58:22 +02:00
Martijn Scheepers
8eca7ae39e do not check location for db device 2024-08-02 16:21:34 +02:00
Martijn Scheepers
f6610531d4 using in ldap 2024-08-02 16:18:50 +02:00
Martijn Scheepers
e4ea355a9f Better axis camera handler 2024-08-02 14:48:19 +02:00
173 changed files with 8551 additions and 5237 deletions

View File

@@ -4,6 +4,9 @@ root = true
# C# files
[*.cs]
dotnet_diagnostic.IDE0058.severity = none
dotnet_diagnostic.CA1310.severity = none
#### Core EditorConfig Options ####
# Indentation and spacing
@@ -229,6 +232,8 @@ dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
csharp_prefer_system_threading_lock = true:suggestion
dotnet_diagnostic.CA1515.severity = silent
[*.{cs,vb}]
dotnet_style_operator_placement_when_wrapping = beginning_of_line
@@ -254,4 +259,8 @@ dotnet_style_namespace_match_folder = true:suggestion
dotnet_diagnostic.CA1707.severity = none
dotnet_diagnostic.CA1008.severity = none
dotnet_diagnostic.CA2007.severity = none
dotnet_diagnostic.CA2217.severity = none
dotnet_diagnostic.CA2217.severity = none
dotnet_diagnostic.CA1002.severity = none
dotnet_diagnostic.CA1031.severity = none
dotnet_diagnostic.CA1307.severity = none
dotnet_diagnostic.CA1305.severity = none

1
.gitignore vendored
View File

@@ -20,3 +20,4 @@ bin
/UCS_Status_Monitor/wwwroot/bootstrap
TestResults
/UCS_Status_Monitor/keys

View File

@@ -0,0 +1,33 @@
using System.Diagnostics;
namespace UCS_Status_Monitor.EventLogCreator
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Create a Status_Monitor event logger (run this as admin)");
try
{
if (!EventLog.SourceExists("Status_Monitor"))
{
EventLog.CreateEventSource("Status_Monitor", "Status_Monitor");
Console.WriteLine("Status_Monitor source created");
Console.WriteLine("Restart PC to use event log source");
}
else
{
Console.WriteLine("Status_Monitor source already exists");
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.WriteLine("Press any key to close");
Console.ReadKey();
}
}
}

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Diagnostics.EventLog" Version="10.0.5" />
</ItemGroup>
</Project>

View File

@@ -1,15 +1,10 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UCS_Status_Monitor.Extensions;
using UCS_Status_Monitor.Models.Database;
namespace UCS_Status_Monitor.UnitTest
{
{
[TestClass]
public class DataBaseModel_Test
{
@@ -17,20 +12,19 @@ namespace UCS_Status_Monitor.UnitTest
public void TabelColor_Test()
{
UCSSystem uCSSystem = new();
Assert.AreEqual("table-danger", uCSSystem.TableColor());
Assert.AreEqual("border-danger", uCSSystem.TableColor());
uCSSystem.ConnectionState = false;
Assert.AreEqual("table-danger", uCSSystem.TableColor());
Assert.AreEqual("border-danger", uCSSystem.TableColor());
uCSSystem.ConnectionState = true;
Assert.AreEqual("table-success", uCSSystem.TableColor());
Assert.AreEqual("border-success", uCSSystem.TableColor());
uCSSystem.Devices = new List<UCSDevice>();
uCSSystem.Devices.Add(new UCSDevice() { State = true, Id = 1, UCSSystem = uCSSystem });
Assert.AreEqual("table-success", uCSSystem.TableColor());
Assert.AreEqual("border-success", uCSSystem.TableColor());
uCSSystem.Devices.Add(new UCSDevice() { State = false, Id = 2, UCSSystem = uCSSystem });
Assert.AreEqual("table-warning", uCSSystem.TableColor());
Assert.AreEqual("border-warning", uCSSystem.TableColor());
}
[TestMethod]
@@ -42,7 +36,6 @@ namespace UCS_Status_Monitor.UnitTest
uCSSystem.ComputerName = "PXX-1234";
Assert.AreEqual("PXX-1234", uCSSystem.ComputerNameWithError());
uCSSystem.Errors = new List<EventLogError>();
uCSSystem.Errors.Add(new EventLogError() { Id = 1, Message = "error", UCSSystem = uCSSystem, Index = 123, TimeGenerated = DateTime.Now.AddDays(-2) });
Assert.AreEqual("PXX-1234", uCSSystem.ComputerNameWithError());
@@ -62,11 +55,11 @@ namespace UCS_Status_Monitor.UnitTest
Location = "Testlocation",
Device = "Testdevice",
Temperature = 36.0F,
Uptime = TimeSpan.FromSeconds(100680),
//Uptime = TimeSpan.FromSeconds(100680),
ThisMonthRX = 631408118,
ThisMonthTX = 967449262,
LastMonthRX = 63108118,
LastMonthTX = 94926132,
//LastMonthRX = 63108118,
//LastMonthTX = 94926132,
RSSI = -62,
WanIp = "178.224.157.191",
Timestamp = now,
@@ -79,8 +72,8 @@ namespace UCS_Status_Monitor.UnitTest
Assert.AreEqual(36.0F, router.Temperature);
Assert.AreEqual("36℃", router.GetTemperature());
Assert.AreEqual(TimeSpan.FromSeconds(100680), router.Uptime);
Assert.AreEqual("1 days 3 hours 58 min 0 sec", router.GetUptime());
//Assert.AreEqual(TimeSpan.FromSeconds(100680), router.Uptime);
//Assert.AreEqual("1 days 3 hours 58 min 0 sec", router.Uptime.GetUptime());
Assert.AreEqual((UInt32)631408118, router.ThisMonthRX);
//Assert.AreEqual("631 MB", router.GetThisMonthRX());
@@ -93,16 +86,16 @@ namespace UCS_Status_Monitor.UnitTest
//Assert.AreEqual("1598 MB", router.ThisMonthTotal());
Assert.AreEqual("1524 MB", router.ThisMonthTotal());
Assert.AreEqual((UInt32)63108118, router.LastMonthRX);
//Assert.AreEqual("63 MB", router.GetLastMonthRX());
Assert.AreEqual("60 MB", router.GetLastMonthRX());
//Assert.AreEqual((UInt32)63108118, router.LastMonthRX);
////Assert.AreEqual("63 MB", router.GetLastMonthRX());
//Assert.AreEqual("60 MB", router.GetLastMonthRX());
Assert.AreEqual((UInt32)94926132, router.LastMonthTX);
//Assert.AreEqual("94 MB", router.GetLastMonthTX());
Assert.AreEqual("90 MB", router.GetLastMonthTX());
//Assert.AreEqual((UInt32)94926132, router.LastMonthTX);
////Assert.AreEqual("94 MB", router.GetLastMonthTX());
//Assert.AreEqual("90 MB", router.GetLastMonthTX());
//Assert.AreEqual("158 MB", router.LastMonthTotal());
Assert.AreEqual("150 MB", router.LastMonthTotal());
//Assert.AreEqual("150 MB", router.LastMonthTotal());
Assert.AreEqual(-62, router.RSSI);
Assert.AreEqual("-62 dBm", router.GetRSSI());
@@ -111,8 +104,5 @@ namespace UCS_Status_Monitor.UnitTest
Assert.AreEqual(now, router.Timestamp);
}
}
}

View File

@@ -0,0 +1,36 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using UCS_Status_Monitor.Extensions;
namespace UCS_Status_Monitor.UnitTest
{
[TestClass]
public class ExtensionsTest
{
public static IEnumerable<object[]> AdditionData
{
get
{
return
[
["", new TimeSpan(0, 0, 0, 0)],
["hsdfkjdf", new TimeSpan(0, 0, 0, 0)],
["8 days 13:00:15", new TimeSpan(8, 13, 00, 15)],
["0 days 09:17:02", new TimeSpan(0, 9, 17, 2)],
["29 days 09:11:28", new TimeSpan(29, 9, 11, 28)],
];
}
}
[TestMethod]
[DynamicData(nameof(AdditionData))]
public void ToTimespan_Test(string value, TimeSpan ts)
{
Assert.AreEqual(ts.Days, value.ToTimespan().Days);
Assert.AreEqual(ts.Hours, value.ToTimespan().Hours);
Assert.AreEqual(ts.Minutes, value.ToTimespan().Minutes);
Assert.AreEqual(ts.Seconds, value.ToTimespan().Seconds);
}
}
}

View File

@@ -1,6 +1,9 @@
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics.CodeAnalysis;
using Moq;
using System.Collections.Generic;
using UCS_Status_Monitor.LDAP;
namespace UCS_Status_Monitor.UnitTest
{
@@ -16,7 +19,6 @@ namespace UCS_Status_Monitor.UnitTest
});
[TestMethod]
[DataTestMethod]
[DataRow(null, null)]
[DataRow(null, "")]
[DataRow("", null)]
@@ -29,42 +31,47 @@ namespace UCS_Status_Monitor.UnitTest
[DataRow("tester", "kjsdjksdfjksdhfjksdfjkhj")]
public void LDAPService_ValidateUser_False(string user, string pass)
{
LDAP.LDAPService ldapService = new(_ldapOptions);
Assert.AreEqual(false, ldapService.ValidateUser(user, pass));
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
Assert.IsFalse(ldapService.ValidateUser(user, pass));
}
[TestMethod]
[DataTestMethod]
[DataRow("tester", "TeStUsEr2426%$")]
public void LDAPService_ValidateUser_True(string user, string pass)
{
LDAP.LDAPService ldapService = new(_ldapOptions);
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
//Assert.AreEqual(true, ldapService.ValidateUser(user, pass));
Assert.AreEqual(false, ldapService.ValidateUser(user, pass));
Assert.IsFalse(ldapService.ValidateUser(user, pass));
}
[TestMethod]
[DataTestMethod]
[DataRow("ms", "Martijn Scheepers")]
[DataRow("jws", "Jan-Willem Schoppers")]
//[DataRow("tester", "Tester")]
[DataRow("wrongUser", "")]
public void LDAPService_GetUserFullName(string user, string fullname)
{
LDAP.LDAPService ldapService = new(_ldapOptions);
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
Assert.AreEqual(fullname, ldapService.GetUserFullName(user));
}
[TestMethod]
[DataTestMethod]
[DataRow("ms")]
[DataRow("jws")]
public void LDAPService_ValidateUserGroup_True(string user)
{
LDAP.LDAPService ldapService = new(_ldapOptions);
Assert.AreEqual(true, ldapService.ValidateUserGroup(user));
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
Assert.IsTrue(ldapService.ValidateUserGroup(user));
}
[TestMethod]
@@ -73,114 +80,136 @@ namespace UCS_Status_Monitor.UnitTest
_ldapOptions.Value.GroupName = "Testgroup";
Assert.AreEqual("Testgroup", _ldapOptions.Value.GroupName);
LDAP.LDAPService ldapService = new(_ldapOptions);
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
//Assert.AreEqual(true, ldapService.ValidateUserGroup("tester"));
Assert.AreEqual(false, ldapService.ValidateUserGroup("tester"));
Assert.IsFalse(ldapService.ValidateUserGroup("tester"));
}
[TestMethod]
[DataTestMethod]
[DataRow(null)]
[DataRow("")]
[DataRow("billy")]
[DataRow("billy")]
[DataRow("tester")]
public void LDAPService_ValidateUserGroup_False(string user)
{
LDAP.LDAPService ldapService = new(_ldapOptions);
Assert.AreEqual(false, ldapService.ValidateUserGroup(user));
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
Assert.IsFalse(ldapService.ValidateUserGroup(user));
}
[TestMethod]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public void LDAPService_GetAllUsers()
{
LDAP.LDAPService ldapService = new(_ldapOptions);
var result = ldapService.GetAllUsers();
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
Assert.AreEqual(9, result.Count);
LDAPService ldapService = new(_ldapOptions, logger);
List<string> result = ldapService.GetAllUsers();
Assert.AreEqual("Administrator", result[0].Name);
Assert.AreEqual("Guest", result[1].Name);
//Assert.AreEqual("DefaultAccount", result[2].Name);
Assert.AreEqual("krbtgt", result[2].Name);
Assert.AreEqual("Jan-Willem Schoppers", result[3].Name);
Assert.AreEqual("Rozan Schoppers", result[4].Name);
Assert.AreEqual("Martijn Scheepers", result[5].Name);
Assert.HasCount(13, result);
Assert.AreEqual("Administrator", result[0]);
Assert.AreEqual("Jan-Willem Schoppers", result[1]);
Assert.AreEqual("Rozan Schoppers", result[2]);
Assert.AreEqual("Martijn Scheepers", result[3]);
Assert.AreEqual("Julia Schoppers", result[4]);
Assert.AreEqual("Officemail", result[5]);
Assert.AreEqual("ADcheck", result[6]);
Assert.AreEqual("Wallboard", result[7]);
Assert.AreEqual("Tech02", result[8]);
Assert.AreEqual("Tech01", result[9]);
Assert.AreEqual("NextCloud", result[10]);
Assert.AreEqual("User-AS03", result[11]);
Assert.AreEqual("User-AS05", result[12]);
}
[TestMethod]
[DataRow(null, 0)]
[DataRow("", 0)]
[DataRow("Not a real group", 0)]
[DataRow("UCSmonitor", 3)]
[DataRow("Users", 0)]
[DataRow("UCSmonitor", 4)]
[DataRow("Domain Users", 13)]
[DataRow("Administrators", 1)]
[DataRow("Guests", 1)]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
[DataRow("PartsDB", 3)]
public void LDAPService_GetAllUsersForGroup(string group, int count)
{
LDAP.LDAPService ldapService = new(_ldapOptions);
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
var result = ldapService.GetAllUsersForGroup(group);
Assert.AreEqual(count, result.Count);
Assert.HasCount(count, result);
}
[TestMethod]
public void LDAPService_GetAllUsersForUCSMonitor()
{
LDAP.LDAPService ldapService = new(_ldapOptions);
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
var result = ldapService.GetAllUsersForGroup("UCSmonitor");
Assert.AreEqual(3, result.Count);
Assert.HasCount(4, result);
Assert.AreEqual("Administrator", result[0].Name);
Assert.AreEqual("Jan-Willem Schoppers", result[1].Name);
Assert.AreEqual("Martijn Scheepers", result[2].Name);
Assert.AreEqual("Administrator", result[0]);
Assert.AreEqual("Jan-Willem Schoppers", result[1]);
Assert.AreEqual("Martijn Scheepers", result[2]);
Assert.AreEqual("Wallboard", result[3]);
}
[TestMethod]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public void LDAPService_GetAllGroups()
{
LDAP.LDAPService ldapService = new(_ldapOptions);
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
var result = ldapService.GetAllGroups();
Assert.AreEqual(64, result.Count);
Assert.HasCount(66, result);
Assert.AreEqual("Administrators", result[0].Name);
Assert.AreEqual("Users", result[1].Name);
Assert.AreEqual("Guests", result[2].Name);
Assert.AreEqual("Print Operators", result[3].Name);
Assert.AreEqual("Administrators", result[0]);
Assert.AreEqual("Users", result[1]);
Assert.AreEqual("Guests", result[2]);
Assert.AreEqual("Print Operators", result[3]);
Assert.AreEqual("Backup Operators", result[4]);
Assert.AreEqual("Replicator", result[5]);
}
[TestMethod]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public void LDAPService_GetAllGroupsForUser()
{
LDAP.LDAPService ldapService = new(_ldapOptions);
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
var result = ldapService.GetAllGroupsForUser("ms");
Assert.AreEqual(6, result.Count);
Assert.HasCount(6, result);
Assert.AreEqual("Domain Users", result[0].Name);
Assert.AreEqual("SDN technicians", result[1].Name);
Assert.AreEqual("Screenconnect_technicians", result[2].Name);
Assert.AreEqual("PartsDB", result[3].Name);
Assert.AreEqual("Git-editors", result[4].Name);
Assert.AreEqual("UCSmonitor", result[5].Name);
Assert.AreEqual("Domain Users", result[0]);
Assert.AreEqual("SDN technicians", result[1]);
Assert.AreEqual("Screenconnect_technicians", result[2]);
Assert.AreEqual("PartsDB", result[3]);
Assert.AreEqual("Git-editors", result[4]);
Assert.AreEqual("UCSmonitor", result[5]);
}
[TestMethod]
[DataRow(null, "")]
[DataRow("", "")]
[DataRow("S-1-5-21-3689940051-815477299-1342572857-1105", "ms")]
//[DataRow("UCSmonitor", 4)]
//[DataRow("Domain Users", 10)]
//[DataRow("Administrators", 1)]
//[DataRow("PartsDB", 3)]
public void LDAPService_GetUserFromSID(string sid, string name)
{
ILogger<LDAPService> logger = Mock.Of<ILogger<LDAPService>>();
LDAPService ldapService = new(_ldapOptions, logger);
string result = ldapService.GetUserFromSID(sid);
//Assert.AreEqual("Domain Users", result[0].Name);
//Assert.AreEqual("Git-editors", result[1].Name);
//Assert.AreEqual("Grafana_editors", result[2].Name);
//Assert.AreEqual("SDN technicians", result[3].Name);
//Assert.AreEqual("Wiki_SDN_editors", result[4].Name);
//Assert.AreEqual("Screenconnect_administrators", result[5].Name);
//Assert.AreEqual("PRTG editors", result[6].Name);
//Assert.AreEqual("HardwareDB", result[7].Name);
//Assert.AreEqual("UCSmonitor", result[8].Name);
Assert.AreEqual(name, result);
}
}
}

View File

@@ -4,14 +4,13 @@ using System;
using System.Collections.Generic;
using UCS_Status_Monitor.MQTT;
using UCS_Status_Monitor.MQTT.Axis;
using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext;
namespace UCS_Status_Monitor.UnitTest
{
[TestClass]
public class MQTT_Test
{
private static readonly Dictionary<string, string> inMemorySettings = new()
private static readonly Dictionary<string, string?> inMemorySettings = new()
{
{ "Database", "UCSStatusMonitorTestDB.db" },
{ "SectionName:SomeKey", "SectionValue" },
@@ -142,8 +141,41 @@ namespace UCS_Status_Monitor.UnitTest
//}
//[TestMethod]
//public void AxisCam_Parse_Json()
//{
// //{
// // "serialNumber": "B8A44F4A646C",
// // "timestamp": "2022-07-26T08:33:59.336107Z",
// // "connected": true,
// // "description": "Connected"
// //}
// string json = "";
// string device = "testdevice";
// string location = "somewhere";
// var message = AxisCamConnectionMessage.Deserialize(json, device, location);
// Assert.IsNull(message);
// json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
// message = AxisCamConnectionMessage.Deserialize(json, device, location);
// Assert.IsNull(message);
// json = "{ \"serialNumber\": \"B8A44F4A646C\",\"timestamp\": \"2022-07-26T08:33:59.336107Z\",\"connected\": true,\"description\": \"Connected\"}";
// message = AxisCamConnectionMessage.Deserialize(json, device, location);
// Assert.IsNotNull(message);
// Assert.IsInstanceOfType(message, typeof(AxisCamConnectionMessage));
// Assert.AreEqual(device, message.Device);
// Assert.AreEqual(location, message.Location);
// Assert.AreEqual("B8A44F4A646C", message.SerialNumber);
// Assert.AreEqual("26-7-2022 08:33:59", message.Timestamp.ToString());
// Assert.AreEqual(true, message.Connected);
// Assert.AreEqual("Connected", message.Description);
//}
[TestMethod]
public void AxisCam_Parse_Json()
public void AxisCamConnectionMessage_Parse_Connected_Json()
{
//{
// "serialNumber": "B8A44F4A646C",
@@ -155,26 +187,86 @@ namespace UCS_Status_Monitor.UnitTest
string json = "";
string device = "testdevice";
string location = "somewhere";
var message = AxisCamConnectionMessage.Deserialize(json, device, location);
var message = MQTTDeviceMessage.Deserialize<AxisCamConnectionMessage>(json, device, location);
Assert.IsNull(message);
json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
message = AxisCamConnectionMessage.Deserialize(json, device, location);
message = MQTTDeviceMessage.Deserialize<AxisCamConnectionMessage>(json, device, location);
Assert.IsNull(message);
json = "{ \"serialNumber\": \"B8A44F4A646C\",\"timestamp\": \"2022-07-26T08:33:59.336107Z\",\"connected\": true,\"description\": \"Connected\"}";
message = AxisCamConnectionMessage.Deserialize(json, device, location);
message = MQTTDeviceMessage.Deserialize<AxisCamConnectionMessage>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(AxisCamConnectionMessage));
Assert.IsInstanceOfType<AxisCamConnectionMessage>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
Assert.AreEqual("B8A44F4A646C", message.SerialNumber);
Assert.AreEqual("26-7-2022 08:33:59", message.Timestamp.ToString());
Assert.AreEqual(true, message.Connected);
Assert.IsTrue(message.Connected);
Assert.AreEqual("Connected", message.Description);
}
[TestMethod]
public void AxisCamConnectionMessage_Parse_Connectionlost_Json()
{
//{
// "serialNumber": "B8A44F9173E6",
// "timestamp": null,
// "connected": false,
// "description": "Connection Lost"
//}
string device = "testdevice";
string location = "somewhere";
string json = "{ \"serialNumber\": \"B8A44F4A646C\",\"timestamp\": \"2022-07-26T08:33:59.336107Z\",\"connected\": false,\"description\": \"Connection Lost\"}";
var message = MQTTDeviceMessage.Deserialize<AxisCamConnectionMessage>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType<AxisCamConnectionMessage>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
Assert.AreEqual("B8A44F4A646C", message.SerialNumber);
Assert.AreEqual("26-7-2022 08:33:59", message.Timestamp.ToString());
Assert.IsFalse(message.Connected);
Assert.AreEqual("Connection Lost", message.Description);
}
//[TestMethod]
//public void AxisCam_SystemReady_Json()
//{
// //{
// // "topic":"onvif:Device/axis:Status/SystemReady",
// // "timestamp":1659948819367,
// // "serial":"B8A44F4A65CD",
// // "message":{
// // "source":{},
// // "key":{},
// // "data":{"ready":"1"}
// // }
// //}
// string json = "{\"topic\":\"onvif:Device/axis:Status/SystemReady\",\"timestamp\":1659948819367,\"serial\":\"B8A44F4A65CD\",\"message\":{\"source\":{},\"key\":{},\"data\":{\"ready\":\"1\"}}}";
// string device = "testdevice";
// string location = "somewhere";
// var message = AxisCamStatusMessage.Deserialize(json, device, location);
// Assert.IsNotNull(message);
// Assert.IsInstanceOfType(message, typeof(AxisCamStatusMessage));
// Assert.AreEqual(device, message.Device);
// Assert.AreEqual(location, message.Location);
// Assert.AreEqual("onvif:Device/axis:Status/SystemReady", message.Topic);
// Assert.AreEqual("B8A44F4A65CD", message.SerialNumber);
// Assert.AreEqual((UInt64)1659948819367, message.TimestampUnix);
// Assert.AreEqual("8-8-2022 08:53:39", message.TimeStampUTC.ToString());
// Assert.IsInstanceOfType(message.Message, typeof(AxisCamStatus));
// Assert.AreEqual(0, message.Message.Source.Count);
// Assert.AreEqual(0, message.Message.Key.Count);
// Assert.AreEqual(1, message.Message.Data.Count);
// Assert.AreEqual("1", message.Message.Data["ready"]);
//}
[TestMethod]
public void AxisCam_SystemReady_Json()
{
@@ -192,9 +284,9 @@ namespace UCS_Status_Monitor.UnitTest
string json = "{\"topic\":\"onvif:Device/axis:Status/SystemReady\",\"timestamp\":1659948819367,\"serial\":\"B8A44F4A65CD\",\"message\":{\"source\":{},\"key\":{},\"data\":{\"ready\":\"1\"}}}";
string device = "testdevice";
string location = "somewhere";
var message = AxisCamStatusMessage.Deserialize(json, device, location);
var message = MQTTDeviceMessage.Deserialize<AxisCamStatusMessage>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(AxisCamStatusMessage));
Assert.IsInstanceOfType<AxisCamStatusMessage>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
@@ -203,14 +295,51 @@ namespace UCS_Status_Monitor.UnitTest
Assert.AreEqual((UInt64)1659948819367, message.TimestampUnix);
Assert.AreEqual("8-8-2022 08:53:39", message.TimeStampUTC.ToString());
Assert.IsInstanceOfType(message.Message, typeof(AxisCamStatus));
Assert.AreEqual(0, message.Message.Source.Count);
Assert.AreEqual(0, message.Message.Key.Count);
Assert.IsInstanceOfType<AxisCamStatus>(message.Message);
Assert.IsEmpty(message.Message.Source);
Assert.IsEmpty(message.Message.Key);
Assert.AreEqual(1, message.Message.Data.Count);
Assert.HasCount(1, message.Message.Data);
Assert.AreEqual("1", message.Message.Data["ready"]);
}
//[TestMethod]
//public void AxisCam_Above_or_below_Json()
//{
// //{
// // "topic":"onvif:Device/axis:Status/Temperature/Above_or_below",
// // "timestamp":1659948787950,
// // "serial":"B8A44F4A65CD",
// // "message":{
// // "source":{},
// // "key":{},
// // "data":{"sensor_level":"0"}
// // }
// //}
// string json = "{\"topic\":\"onvif:Device/axis:Status/Temperature/Above_or_below\",\"timestamp\":1659948787950,\"serial\":\"B8A44F4A65CD\",\"message\":{\"source\":{},\"key\":{},\"data\":{\"sensor_level\":\"0\"}}}";
// string device = "testdevice";
// string location = "somewhere";
// var message = AxisCamStatusMessage.Deserialize(json, device, location);
// Assert.IsNotNull(message);
// Assert.IsInstanceOfType(message, typeof(AxisCamStatusMessage));
// Assert.AreEqual(device, message.Device);
// Assert.AreEqual(location, message.Location);
// Assert.AreEqual("onvif:Device/axis:Status/Temperature/Above_or_below", message.Topic);
// Assert.AreEqual("B8A44F4A65CD", message.SerialNumber);
// Assert.AreEqual((UInt64)1659948787950, message.TimestampUnix);
// Assert.AreEqual("8-8-2022 08:53:07", message.TimeStampUTC.ToString());
// Assert.IsInstanceOfType(message.Message, typeof(AxisCamStatus));
// Assert.AreEqual(0, message.Message.Source.Count);
// Assert.AreEqual(0, message.Message.Key.Count);
// Assert.AreEqual(1, message.Message.Data.Count);
// Assert.AreEqual("0", message.Message.Data["sensor_level"]);
//}
[TestMethod]
public void AxisCam_Above_or_below_Json()
{
@@ -228,9 +357,9 @@ namespace UCS_Status_Monitor.UnitTest
string json = "{\"topic\":\"onvif:Device/axis:Status/Temperature/Above_or_below\",\"timestamp\":1659948787950,\"serial\":\"B8A44F4A65CD\",\"message\":{\"source\":{},\"key\":{},\"data\":{\"sensor_level\":\"0\"}}}";
string device = "testdevice";
string location = "somewhere";
var message = AxisCamStatusMessage.Deserialize(json, device, location);
var message = MQTTDeviceMessage.Deserialize<AxisCamStatusMessage>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(AxisCamStatusMessage));
Assert.IsInstanceOfType<AxisCamStatusMessage>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
@@ -239,14 +368,52 @@ namespace UCS_Status_Monitor.UnitTest
Assert.AreEqual((UInt64)1659948787950, message.TimestampUnix);
Assert.AreEqual("8-8-2022 08:53:07", message.TimeStampUTC.ToString());
Assert.IsInstanceOfType(message.Message, typeof(AxisCamStatus));
Assert.AreEqual(0, message.Message.Source.Count);
Assert.AreEqual(0, message.Message.Key.Count);
Assert.IsInstanceOfType<AxisCamStatus>(message.Message);
Assert.IsEmpty(message.Message.Source);
Assert.IsEmpty(message.Message.Key);
Assert.AreEqual(1, message.Message.Data.Count);
Assert.HasCount(1, message.Message.Data);
Assert.AreEqual("0", message.Message.Data["sensor_level"]);
}
//[TestMethod]
//public void AxisCam_VMD3_Json()
//{
// //{
// // "topic":"onvif:RuleEngine/axis:VMD3/vmd3_video_1",
// // "timestamp":1659954945303,
// // "serial":"B8A44F4A646C",
// // "message":{
// // "source":{"areaid":"0"},
// // "key":{},
// // "data":{"active":"0"}
// // }
// //}
// string json = "{\"topic\":\"onvif:RuleEngine/axis:VMD3/vmd3_video_1\",\"timestamp\":1659955213858,\"serial\":\"B8A44F4A646C\",\"message\":{\"source\":{\"areaid\":\"0\"},\"key\":{},\"data\":{\"active\":\"1\"}}}";
// string device = "testdevice";
// string location = "somewhere";
// var message = AxisCamStatusMessage.Deserialize(json, device, location);
// Assert.IsNotNull(message);
// Assert.IsInstanceOfType(message, typeof(AxisCamStatusMessage));
// Assert.AreEqual(device, message.Device);
// Assert.AreEqual(location, message.Location);
// Assert.AreEqual("onvif:RuleEngine/axis:VMD3/vmd3_video_1", message.Topic);
// Assert.AreEqual("B8A44F4A646C", message.SerialNumber);
// Assert.AreEqual((UInt64)1659955213858, message.TimestampUnix);
// Assert.AreEqual("8-8-2022 10:40:13", message.TimeStampUTC.ToString());
// Assert.IsInstanceOfType(message.Message, typeof(AxisCamStatus));
// Assert.AreEqual(1, message.Message.Source.Count);
// Assert.AreEqual("0", message.Message.Source["areaid"]);
// Assert.AreEqual(0, message.Message.Key.Count);
// Assert.AreEqual(1, message.Message.Data.Count);
// Assert.AreEqual("1", message.Message.Data["active"]);
//}
[TestMethod]
public void AxisCam_VMD3_Json()
{
@@ -264,9 +431,9 @@ namespace UCS_Status_Monitor.UnitTest
string json = "{\"topic\":\"onvif:RuleEngine/axis:VMD3/vmd3_video_1\",\"timestamp\":1659955213858,\"serial\":\"B8A44F4A646C\",\"message\":{\"source\":{\"areaid\":\"0\"},\"key\":{},\"data\":{\"active\":\"1\"}}}";
string device = "testdevice";
string location = "somewhere";
var message = AxisCamStatusMessage.Deserialize(json, device, location);
var message = MQTTDeviceMessage.Deserialize<AxisCamStatusMessage>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(AxisCamStatusMessage));
Assert.IsInstanceOfType<AxisCamStatusMessage>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
@@ -275,13 +442,13 @@ namespace UCS_Status_Monitor.UnitTest
Assert.AreEqual((UInt64)1659955213858, message.TimestampUnix);
Assert.AreEqual("8-8-2022 10:40:13", message.TimeStampUTC.ToString());
Assert.IsInstanceOfType(message.Message, typeof(AxisCamStatus));
Assert.AreEqual(1, message.Message.Source.Count);
Assert.IsInstanceOfType<AxisCamStatus>(message.Message);
Assert.HasCount(1, message.Message.Source);
Assert.AreEqual("0", message.Message.Source["areaid"]);
Assert.AreEqual(0, message.Message.Key.Count);
Assert.IsEmpty(message.Message.Key);
Assert.AreEqual(1, message.Message.Data.Count);
Assert.HasCount(1, message.Message.Data);
Assert.AreEqual("1", message.Message.Data["active"]);
}
}

View File

@@ -0,0 +1,175 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.MQTT.Axis;
namespace UCS_Status_Monitor.UnitTest.Monitor.AxisDeviceTest
{
[TestClass]
public class ConnectionMessages_Test : MonitorTestSetup
{
public TestContext TestContext { get; set; }
[TestMethod]
public async Task AxisDevice_ConnectionMessage_Empty_Test()
{
IDbContextFactory<MonitorDbContext> factory = CreateDataBaseFactory();
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
AxisCamMonitorDevice? axisDevice = new(factory, testingTelegramBot);
AxisCamConnectionMessage message = new() { };
await axisDevice.Update(message, db, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(axisDevice);
Assert.IsFalse(axisDevice.IsConnected);
Assert.AreEqual("??", axisDevice.DeviceName);
Assert.AreEqual("??", axisDevice.Location);
Assert.IsGreaterThan(638980183227861967, axisDevice.LastData.Ticks);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("SendDeviceAdded - ?? - ??", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task AxisDevice_ConnectionMessage_Fields_Test()
{
IDbContextFactory<MonitorDbContext> factory = CreateDataBaseFactory();
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
AxisCamMonitorDevice? axisDevice = new(factory, testingTelegramBot);
AxisCamConnectionMessage message = new()
{
Device = "Test Device",
Location = "Test Location",
SerialNumber = "1234",
Description = "Test camera",
Connected = true,
Timestamp = new(2025, 11, 6),
};
await axisDevice.Update(message, db, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(axisDevice);
Assert.IsFalse(axisDevice.IsConnected);
Assert.AreEqual("Test Device", axisDevice.DeviceName);
Assert.AreEqual("Test Location", axisDevice.Location);
Assert.IsGreaterThan(638980183227861967, axisDevice.LastData.Ticks);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("SendDeviceAdded - Test Location - Test Device", testingTelegramBot.Messages[0]);
var cam = db.AxisCams.First();
Assert.IsNotNull(cam);
Assert.AreEqual("Test Device", cam.Device);
Assert.AreEqual("Test Location", cam.Location);
Assert.AreEqual("1234", cam.SerialNumber);
Assert.IsTrue(cam.Connected);
Assert.AreEqual("Test camera", cam.Description);
Assert.IsFalse(cam.SystemReady);
Assert.AreEqual("", cam.Temperature);
Assert.AreEqual(638979840000000000, cam.Timestamp.Ticks);
}
//[TestMethod]
//public async Task AxisDevice_UpdateErrors_Empty_Test()
//{
// using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
// Assert.IsNotNull(db);
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Computer",
// ConfigFileName = "Config File",
// };
// system = await UCSSystemMonitorDevice.UpdateErrors(system, [], db, testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.IsEmpty(system.Errors);
// Assert.HasCount(0, testingTelegramBot.Messages);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateErrors_AddError_Test()
//{
// using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
// Assert.IsNotNull(db);
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Computer",
// ConfigFileName = "Config File",
// };
// List<ErrorEventMessage>? errors = [new() {
// Index = 42,
// Message = "Error Message",
// TimeGenerated = new(2025,11,5)
// }];
// system = await UCSSystemMonitorDevice.UpdateErrors(system, errors, db, testingTelegramBot, TestContext.CancellationToken);
// await db.SaveChangesAsync(TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.HasCount(1, system.Errors);
// Assert.AreEqual(2, system.Errors.ToList()[0].Id);
// Assert.AreEqual(42, system.Errors.ToList()[0].Index);
// Assert.AreEqual("woensdag 5 november 2025", system.Errors.ToList()[0].TimeGenerated.ToLongDateString());
// Assert.AreEqual("Error Message", system.Errors.ToList()[0].Message);
// Assert.HasCount(2, db.Errors);
// Assert.HasCount(1, testingTelegramBot.Messages);
// Assert.AreEqual("Send - ‼️ <b>Computer - Config File</b>\r\n Error Message", testingTelegramBot.Messages[0]);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateErrors_UpdateError_Test()
//{
// using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
// Assert.IsNotNull(db);
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = db.UCSSystems.FirstOrDefault();
// List<ErrorEventMessage>? errors = [new() {
// Index = 42,
// }];
// system = await UCSSystemMonitorDevice.UpdateErrors(system, errors, db, testingTelegramBot, TestContext.CancellationToken);
// await db.SaveChangesAsync(TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.HasCount(1, db.Errors);
// Assert.HasCount(0, testingTelegramBot.Messages);
//}
}
}

View File

@@ -0,0 +1,235 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.MQTT.Axis;
namespace UCS_Status_Monitor.UnitTest.Monitor.AxisDeviceTest
{
[TestClass]
public class StatusMessages_Test : MonitorTestSetup
{
public TestContext TestContext { get; set; }
[TestMethod]
public async Task AxisDevice_StatusMessage_Empty_Test()
{
IDbContextFactory<MonitorDbContext> factory = CreateDataBaseFactory();
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
AxisCamMonitorDevice? axisDevice = new(factory, testingTelegramBot);
AxisCamStatusMessage message = new() { };
await axisDevice.Update(message, db, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(axisDevice);
Assert.IsFalse(axisDevice.IsConnected);
Assert.AreEqual("??", axisDevice.DeviceName);
Assert.AreEqual("??", axisDevice.Location);
Assert.IsGreaterThan(638980183227861967, axisDevice.LastData.Ticks);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("SendDeviceAdded - ?? - ??", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task AxisDevice_StatusMessage_SystemReady_Test()
{
IDbContextFactory<MonitorDbContext> factory = CreateDataBaseFactory();
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
AxisCamMonitorDevice? axisDevice = new(factory, testingTelegramBot);
AxisCamStatusMessage message = new()
{
Topic = "onvif:Device/axis:Status/SystemReady",
Device = "Test Device",
Location = "Test Location",
SerialNumber = "1234",
Message = new()
{
Data = new() { { "ready", "1" } }
}
};
await axisDevice.Update(message, db, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(axisDevice);
Assert.IsFalse(axisDevice.IsConnected);
Assert.AreEqual("Test Device", axisDevice.DeviceName);
Assert.AreEqual("Test Location", axisDevice.Location);
Assert.IsGreaterThan(638980183227861967, axisDevice.LastData.Ticks);
Assert.HasCount(2, testingTelegramBot.Messages);
Assert.AreEqual("SendDeviceAdded - Test Location - Test Device", testingTelegramBot.Messages[0]);
Assert.AreEqual("Send - ✅ <b>Test Location - Test Device</b>\r\n Camera is ready", testingTelegramBot.Messages[1]);
var cam = db.AxisCams.First();
Assert.IsNotNull(cam);
Assert.AreEqual("Test Device", cam.Device);
Assert.AreEqual("Test Location", cam.Location);
Assert.AreEqual("1234", cam.SerialNumber);
Assert.IsFalse(cam.Connected);
Assert.AreEqual("", cam.Description);
Assert.IsTrue(cam.SystemReady);
Assert.AreEqual("", cam.Temperature);
//Assert.AreEqual(638979840000000000, cam.Timestamp.Ticks);
Assert.AreEqual(0, cam.Timestamp.Ticks);
}
[TestMethod]
public async Task AxisDevice_StatusMessage_SystemReady_True_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
AxisCam axisCam = new()
{
Device = "Camera",
Location = "some place"
};
AxisCamStatus status = new()
{
Data = new() { { "ready", "1" } }
};
await AxisCamMonitorDevice.SetSystemReady(axisCam, status, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(axisCam);
Assert.IsTrue(axisCam.SystemReady);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("Send - ✅ <b>some place - Camera</b>\r\n Camera is ready", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task AxisDevice_StatusMessage_SystemReady_False_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
AxisCam axisCam = new()
{
Device = "Camera",
Location = "some place"
};
AxisCamStatus status = new()
{
Data = new() { { "ready", "0" } }
};
await AxisCamMonitorDevice.SetSystemReady(axisCam, status, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(axisCam);
Assert.IsFalse(axisCam.SystemReady);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("Send - ⚠️ <b>some place - Camera</b>\r\n Camera not ready", testingTelegramBot.Messages[0]);
}
//[TestMethod]
//public async Task AxisDevice_UpdateErrors_Empty_Test()
//{
// using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
// Assert.IsNotNull(db);
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Computer",
// ConfigFileName = "Config File",
// };
// system = await UCSSystemMonitorDevice.UpdateErrors(system, [], db, testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.IsEmpty(system.Errors);
// Assert.HasCount(0, testingTelegramBot.Messages);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateErrors_AddError_Test()
//{
// using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
// Assert.IsNotNull(db);
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Computer",
// ConfigFileName = "Config File",
// };
// List<ErrorEventMessage>? errors = [new() {
// Index = 42,
// Message = "Error Message",
// TimeGenerated = new(2025,11,5)
// }];
// system = await UCSSystemMonitorDevice.UpdateErrors(system, errors, db, testingTelegramBot, TestContext.CancellationToken);
// await db.SaveChangesAsync(TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.HasCount(1, system.Errors);
// Assert.AreEqual(2, system.Errors.ToList()[0].Id);
// Assert.AreEqual(42, system.Errors.ToList()[0].Index);
// Assert.AreEqual("woensdag 5 november 2025", system.Errors.ToList()[0].TimeGenerated.ToLongDateString());
// Assert.AreEqual("Error Message", system.Errors.ToList()[0].Message);
// Assert.HasCount(2, db.Errors);
// Assert.HasCount(1, testingTelegramBot.Messages);
// Assert.AreEqual("Send - ‼️ <b>Computer - Config File</b>\r\n Error Message", testingTelegramBot.Messages[0]);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateErrors_UpdateError_Test()
//{
// using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
// Assert.IsNotNull(db);
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = db.UCSSystems.FirstOrDefault();
// List<ErrorEventMessage>? errors = [new() {
// Index = 42,
// }];
// system = await UCSSystemMonitorDevice.UpdateErrors(system, errors, db, testingTelegramBot, TestContext.CancellationToken);
// await db.SaveChangesAsync(TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.HasCount(1, db.Errors);
// Assert.HasCount(0, testingTelegramBot.Messages);
//}
}
}

View File

@@ -0,0 +1,25 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UCS_Status_Monitor.Monitor;
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
namespace UCS_Status_Monitor.UnitTest.Monitor
{
[TestClass]
public class BaseMonitorDevice_Test : MonitorTestSetup
{
[TestMethod]
public void BaseMonitorDevice_Contructor_Test()
{
Assert.IsNotNull(_dbContextFactory);
Assert.IsNotNull(_testingTelegramBot);
BaseMonitorDevice monitorDevice = new(5, _dbContextFactory, _testingTelegramBot);
Assert.IsNotNull(monitorDevice);
Assert.AreEqual("", monitorDevice.DeviceName);
Assert.AreEqual("", monitorDevice.Location);
Assert.IsFalse(monitorDevice.IsConnected);
Assert.AreEqual("1-1-0001 00:00:00", monitorDevice.LastData.ToString());
}
}
}

View File

@@ -0,0 +1,411 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.Threading;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Models.Database;
namespace UCS_Status_Monitor.UnitTest.Monitor
{
[TestClass]
public class MonitorTestSetup
{
private protected IDbContextFactory<MonitorDbContext>? _dbContextFactory;
private protected TestingTelegramBot? _testingTelegramBot;
//private protected Mock<ConnectionContext> _connectionMoq = new();
//private protected TestingAperioConnectionContext? _aperioConnectionContext;
//private protected ILogger<AperioDeviceList>? _deviceListLogger;
//private protected TestingScreenLogger? _screenLogging;
//private protected TestingStatusBroadcastHandler? _statusBroadcast;
//private protected AperioDeviceList? _devicesList;
//private protected CancellationTokenSource _cts = new();
//private protected CancellationToken _token;
//private static readonly Dictionary<string, string?> inMemorySettings = new()
// {
// { "ACS:UseAuthorization", "false" }
// };
//private readonly IConfiguration configuration = new ConfigurationBuilder()
// .AddInMemoryCollection(inMemorySettings)
// .Build();
public static IDbContextFactory<MonitorDbContext> CreateDataBaseFactory()
{
//Runs before each test. (Optional)
Guid jitter = Guid.NewGuid();
DbContextOptions<MonitorDbContext> dbOptions = new DbContextOptionsBuilder<MonitorDbContext>()
.UseInMemoryDatabase(databaseName: $"TestDb{jitter}")
.Options;
Mock<IDbContextFactory<MonitorDbContext>> mockDbFactory = new();
mockDbFactory.Setup(f => f.CreateDbContext())
.Returns(() => new MonitorDbContext(dbOptions));
mockDbFactory.Setup(f => f.CreateDbContextAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(() => new MonitorDbContext(dbOptions));
SeedDatabase(mockDbFactory.Object.CreateDbContext());
return mockDbFactory.Object;
}
[TestInitialize]
public void Setup()
{
//Runs before each test. (Optional)
Guid jitter = Guid.NewGuid();
DbContextOptions<MonitorDbContext> dbOptions = new DbContextOptionsBuilder<MonitorDbContext>()
.UseInMemoryDatabase(databaseName: $"TestDb{jitter}")
.Options;
Mock<IDbContextFactory<MonitorDbContext>> mockDbFactory = new();
mockDbFactory.Setup(f => f.CreateDbContext())
.Returns(() => new MonitorDbContext(dbOptions));
mockDbFactory.Setup(f => f.CreateDbContextAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(() => new MonitorDbContext(dbOptions));
SeedDatabase(mockDbFactory.Object.CreateDbContext());
_dbContextFactory = mockDbFactory.Object;
//_deviceListLogger = Mock.Of<ILogger<AperioDeviceList>>();
//_screenLogging = new TestingScreenLogger();
//_statusBroadcast = new TestingStatusBroadcastHandler();
//_connectionMoq = new Mock<ConnectionContext>();
//_ = _connectionMoq.Setup(s => s.RemoteEndPoint).Returns(new IPEndPoint(IPAddress.Parse("64.226.1.0"), 1234));
//_ = _connectionMoq.Setup(s => s.Transport.Output.WriteAsync(It.IsAny<ReadOnlyMemory<byte>>(), It.IsAny<CancellationToken>()));
//_ = _connectionMoq.Setup(s => s.Features.Get<IScreenLogger>()).Returns(_screenLogging);
//_aperioConnectionContext = new TestingAperioConnectionContext();
//_aperioConnectionContext.SetConnection(_connectionMoq.Object);
//_aperioConnectionContext = new TestingAperioConnectionContext();
//_aperioConnectionContext = new AperioConnectionContext();
//_aperioConnectionContext.SetConnection(_connectionMoq.Object);
//ServiceCollection services = new();
//services.AddTransient<AperioHubDevice>();
//services.AddTransient<AperioLockDevice>();
//services.AddTransient<AperioOptaDevice>();
//services.AddSingleton<IScreenLogger>(_screenLogging);
//services.AddSingleton<IStatusBroadcastHandler>(_statusBroadcast);
//services.AddDbContextFactory<ACSDatabaseContext>(o =>
//{
// o.UseInMemoryDatabase(databaseName: $"TestDb{jitter}");
//});
//ServiceProvider serviceProvider = services.BuildServiceProvider();
//_devicesList = new(serviceProvider, _deviceListLogger, _screenLogging);
_testingTelegramBot = new TestingTelegramBot();
}
private static void SeedDatabase(MonitorDbContext dbContext)
{
UCSSystem system = new()
{
ComputerName = "Test",
ConfigFileName = "TestConfig",
};
dbContext.UCSSystems.Add(system);
dbContext.Errors.Add(new EventLogError()
{
Index = 42,
Message = "Database Error",
TimeGenerated = new(0),
UCSSystem = system,
});
dbContext.UCSDevices.Add(new UCSDevice()
{
BoxID = "Device ID 1",
Name = "Device 1",
State = true,
Message = "OK",
UCSSystem = system
});
//dbContext.Devices.Add(new Device()
//{
// Id = 1,
// DeviceId = "AA11BB",
// Name = "TestDevice",
// Active = ActiveStates.Active,
// ConnectionState = ConnectionStates.Online,
// Ipaddress = "64.226.1.0",
// ProductClass = ProductClass.LOCK,
//});
//dbContext.Devices.Add(new Device()
//{
// Id = 2,
// DeviceId = "445566",
// Name = "TestHost 2",
// Active = ActiveStates.Active,
// ProductClass = ProductClass.GATEWAY,
// Ipaddress = "64.226.1.0",
// LocationId = 1
//});
//dbContext.Devices.Add(new Device()
//{
// Id = 3,
// DeviceId = "0412F5",
// Name = "Opta lock",
// Active = ActiveStates.Active,
// ConnectionState = ConnectionStates.Online,
// ProductClass = ProductClass.OPTA_V1,
// //Ipaddress = "[::ffff:192.168.0.172]:49494",
// Ipaddress = "64.226.1.0",
// LocationId = 1,
// UnlockTime = 42
//});
// dbContext.Timezones.Add(new Timezone()
// {
// Name = "Altijd",
// BeginTime = new TimeSpan(0),
// EndTime = new TimeSpan(0),
// WeekDays = WeekDaysTypes.Daily,
// TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// });
// dbContext.Timezones.Add(new Timezone()
// {
// Name = "Nooit",
// BeginTime = new TimeSpan(0),
// EndTime = new TimeSpan(0),
// WeekDays = WeekDaysTypes.None,
// TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// });
// dbContext.Timezones.Add(new Timezone()
// {
// Name = "Inactive",
// BeginTime = new TimeSpan(0),
// EndTime = new TimeSpan(0),
// WeekDays = WeekDaysTypes.Daily,
// TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
// Active = ActiveStates.Inactive,
// LastChanged = DateTime.UtcNow,
// });
// dbContext.Timezones.Add(new Timezone()
// {
// Name = "night active",
// BeginTime = new TimeSpan(0),
// EndTime = TimeSpan.FromHours(5),
// WeekDays = WeekDaysTypes.Daily,
// TwentyFourHours = TwentyFourHoursTypes.Timeselected,
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// });
// dbContext.Groups.Add(new Group()
// {
// Name = "Active Group",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// TimezoneId = 2
// });
// dbContext.Groups.Add(new Group()
// {
// Name = "Inactive Group",
// Active = ActiveStates.Inactive,
// LastChanged = DateTime.UtcNow,
// TimezoneId = 1
// });
// dbContext.Groups.Add(new Group()
// {
// Name = "Group",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// TimezoneId = 1
// });
// dbContext.Groups.Add(new Group()
// {
// Name = "Group",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// TimezoneId = 3
// });
// dbContext.Groups.Add(new Group()
// {
// Name = "Group",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// TimezoneId = 4
// });
// dbContext.Groups.Add(new Group()
// {
// Name = "Access Group",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// TimezoneId = 1
// });
// dbContext.Groups.Add(new Group()
// {
// Name = "Access Group",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// TimezoneId = 1
// });
// dbContext.DeviceGroupJoins.Add(new DeviceGroupJoin()
// {
// DeviceId = 2,
// GroupId = 1
// });
// dbContext.DeviceGroupJoins.Add(new DeviceGroupJoin()
// {
// DeviceId = 2,
// GroupId = 4
// });
// dbContext.DeviceGroupJoins.Add(new DeviceGroupJoin()
// {
// DeviceId = 2,
// GroupId = 5
// });
// dbContext.DeviceGroupJoins.Add(new DeviceGroupJoin()
// {
// DeviceId = 2,
// GroupId = 6
// });
// dbContext.DeviceGroupJoins.Add(new DeviceGroupJoin()
// {
// DeviceId = 4,
// GroupId = 6
// });
//dbContext.Locations.Add(new Location()
//{
// Id = 1,
// Zipcode = "1234AB",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
//});
//dbContext.Locations.Add(new Location()
//{
// Id = 2,
// Zipcode = "5684XA",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
//});
// dbContext.Users.Add(new User()
// {
// CredentialString = "0A1B2C3D",
// CredentialType = CredentialTypes.Mifare,
// Name = "Inactive User",
// Active = ActiveStates.Inactive,
// LastChanged = DateTime.UtcNow,
// Created = DateTime.UtcNow
// });
// dbContext.Users.Add(new User()
// {
// CredentialString = "987654",
// PassNumber = 1234,
// CredentialType = CredentialTypes.Mifare,
// Name = "Active User",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// Created = DateTime.UtcNow,
// });
// dbContext.Users.Add(new User()
// {
// CredentialString = "AA7654",
// PassNumber = 1234,
// CredentialType = CredentialTypes.Mifare,
// Name = "Active User",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// Created = DateTime.UtcNow,
// GroupId = 2
// });
// dbContext.Users.Add(new User()
// {
// CredentialString = "BB7654",
// PassNumber = 1234,
// CredentialType = CredentialTypes.Mifare,
// Name = "Active User",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// Created = DateTime.UtcNow,
// GroupId = 1
// });
// dbContext.Users.Add(new User()
// {
// CredentialString = "CC7654",
// PassNumber = 1234,
// CredentialType = CredentialTypes.Mifare,
// Name = "Active User",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// Created = DateTime.UtcNow,
// GroupId = 3
// });
// dbContext.Users.Add(new User()
// {
// CredentialString = "DD7654",
// PassNumber = 1234,
// CredentialType = CredentialTypes.Mifare,
// Name = "Active User",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// Created = DateTime.UtcNow,
// GroupId = 4
// });
// dbContext.Users.Add(new User()
// {
// CredentialString = "EE7654",
// PassNumber = 1234,
// CredentialType = CredentialTypes.Mifare,
// Name = "Active User",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// Created = DateTime.UtcNow,
// GroupId = 5
// });
// dbContext.Users.Add(new User()
// {
// CredentialString = "F17654",
// PassNumber = 1234,
// CredentialType = CredentialTypes.Mifare,
// Name = "Access User",
// Active = ActiveStates.Active,
// LastChanged = DateTime.UtcNow,
// Created = DateTime.UtcNow,
// GroupId = 6
// });
// dbContext.GlobalSettings.Add(new GlobalSetting()
// {
// Name = "SectorKey",
// Value = "2C3D0400000508112233445500050811"
// });
dbContext.SaveChanges();
}
[TestCleanup]
public void Cleanup()
{
//_cts.Cancel();
//_cts.Dispose();
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.Telegram;
namespace UCS_Status_Monitor.UnitTest.Monitor
{
internal class TestingTelegramBot : ITelegramBotMessageChannel
{
public List<String> Messages { get; set; } = [];
public Task<string> DequeueMessage(CancellationToken token)
{
throw new NotImplementedException();
}
public Task EnqueueMessage(string message, CancellationToken token)
{
Messages.Add($"Send - {message}");
return Task.CompletedTask;
}
public Task Send(string msg, CancellationToken token)
{
Messages.Add($"Send - {msg}");
return Task.CompletedTask;
}
public Task SendConnectionStatus(string computerName, bool state, CancellationToken token)
{
Messages.Add($"SendConnectionStatus - {computerName} - {state}");
return Task.CompletedTask;
}
public Task SendConnectionStatus(IBaseMonitorDevice device, CancellationToken token)
{
Messages.Add($"SendConnectionStatus - {device.DeviceName} - {device.Location} - {device.IsConnected}");
return Task.CompletedTask;
}
public Task SendDeviceAdded(string device, CancellationToken token)
{
Messages.Add($"SendDeviceAdded - {device}");
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,331 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.Telemetry;
namespace UCS_Status_Monitor.UnitTest.Monitor
{
[TestClass]
public class UCSSystemMonitorDevice_Test : MonitorTestSetup
{
public TestContext TestContext { get; set; }
[TestMethod]
public void UCSSystemMonitorDevice_Constructor_Test()
{
Assert.IsNotNull(_dbContextFactory);
Assert.IsNotNull(_testingTelegramBot);
UCSSystemMonitorDevice ucsDevice = new(5, _dbContextFactory, _testingTelegramBot);
Assert.IsNotNull(ucsDevice);
Assert.AreEqual("", ucsDevice.DeviceName);
Assert.AreEqual("", ucsDevice.Location);
Assert.IsFalse(ucsDevice.IsConnected);
Assert.AreEqual("1-1-0001 00:00:00", ucsDevice.LastData.ToString());
}
[TestMethod]
public void UCSSystemMonitorDevice_SetConnectionState_Test()
{
Assert.IsNotNull(_dbContextFactory);
Assert.IsNotNull(_testingTelegramBot);
UCSSystemMonitorDevice ucsDevice = new(5, _dbContextFactory, _testingTelegramBot);
Assert.IsNotNull(ucsDevice);
ucsDevice.DeviceName = "Test";
using MonitorDbContext db = _dbContextFactory.CreateDbContext();
ucsDevice.SetConnectionState(true, db, default).Wait(TestContext.CancellationToken);
Assert.AreEqual("Test", ucsDevice.DeviceName);
Assert.AreEqual("", ucsDevice.Location);
Assert.IsTrue(ucsDevice.IsConnected);
Assert.IsGreaterThan(1000000000, ucsDevice.LastData.Ticks);
Assert.HasCount(1, _testingTelegramBot.Messages);
Assert.AreEqual("SendConnectionStatus - Test - TestConfig - True", _testingTelegramBot.Messages[0]);
//Assert.AreEqual(1, db.Loggings.);
}
[TestMethod]
public void UCSSystemMonitorDevice_Update_Add_Test()
{
Assert.IsNotNull(_dbContextFactory);
Assert.IsNotNull(_testingTelegramBot);
UCSSystemMonitorDevice ucsDevice = new(5, _dbContextFactory, _testingTelegramBot);
Assert.IsNotNull(ucsDevice);
using MonitorDbContext db = _dbContextFactory.CreateDbContext();
TelemetryPacket packet = new()
{
ComputerName = "New Test",
ConfigFileName = "New Config File"
};
ucsDevice.Update(packet, db, default).Wait(TestContext.CancellationToken);
Assert.AreEqual("New Test", ucsDevice.DeviceName);
Assert.AreEqual("", ucsDevice.Location);
Assert.IsFalse(ucsDevice.IsConnected);
Assert.IsGreaterThan(1000000000, ucsDevice.LastData.Ticks);
Assert.HasCount(1, _testingTelegramBot.Messages);
Assert.AreEqual("SendDeviceAdded - New Test - New Config File", _testingTelegramBot.Messages[0]);
}
[TestMethod]
public void UCSSystemMonitorDevice_StartTime_Test()
{
Assert.IsNotNull(_dbContextFactory);
Assert.IsNotNull(_testingTelegramBot);
UCSSystemMonitorDevice ucsDevice = new(5, _dbContextFactory, _testingTelegramBot);
Assert.IsNotNull(ucsDevice);
ucsDevice.DeviceName = "Test";
using MonitorDbContext db = _dbContextFactory.CreateDbContext();
TelemetryPacket packet = new()
{
ComputerName = "Test",
ConfigFileName = "Config File",
StartTime = "14-10-2025 08:52:00"
};
ucsDevice.Update(packet, db, default).Wait(TestContext.CancellationToken);
Assert.AreEqual("Test", ucsDevice.DeviceName);
Assert.AreEqual("", ucsDevice.Location);
Assert.IsFalse(ucsDevice.IsConnected);
Assert.IsGreaterThan(1000000000, ucsDevice.LastData.Ticks);
Assert.HasCount(1, _testingTelegramBot.Messages);
Assert.AreEqual("Send - ♻️ <b>Test - TestConfig</b>\r\n UCS restarted", _testingTelegramBot.Messages[0]);
}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_GetUCSSystem_Test()
//{
// IDbContextFactory<MonitorDbContext> dbFactory = CreateDataBaseFactory();
// Assert.IsNotNull(dbFactory);
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystemMonitorDevice ucsDevice = new(5, dbFactory, testingTelegramBot); ;
// Assert.IsNotNull(ucsDevice);
// using MonitorDbContext db = dbFactory.CreateDbContext();
// TelemetryPacket packet = new()
// {
// ComputerName = "Test",
// ConfigFileName = "Config File",
// StartTime = "14-10-2025 08:52:00"
// };
// UCSSystem ucssystem = await ucsDevice.GetUCSSystem(packet, db, TestContext.CancellationToken);
// Assert.AreEqual("Test", ucssystem.ComputerName);
// Assert.AreEqual("TestConfig", ucssystem.ConfigFileName);
// Assert.HasCount(0, testingTelegramBot.Messages);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_GetUCSSystem_new_Test()
//{
// IDbContextFactory<MonitorDbContext> dbFactory = CreateDataBaseFactory();
// Assert.IsNotNull(dbFactory);
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystemMonitorDevice ucsDevice = new(5, dbFactory, testingTelegramBot); ;
// Assert.IsNotNull(ucsDevice);
// using MonitorDbContext db = dbFactory.CreateDbContext();
// TelemetryPacket packet = new()
// {
// ComputerName = "New Device",
// ConfigFileName = "Config File",
// StartTime = "14-10-2025 08:52:00"
// };
// UCSSystem ucssystem = await ucsDevice.GetUCSSystem(packet, db, TestContext.CancellationToken);
// Assert.AreEqual("New Device", ucssystem.ComputerName);
// Assert.AreEqual("Config File", ucssystem.ConfigFileName);
// Assert.HasCount(1, testingTelegramBot.Messages);
// Assert.AreEqual("SendDeviceAdded - New Device - Config File", testingTelegramBot.Messages[0]);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateUSBDevices_null_Test()
//{
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Test",
// ConfigFileName = "Config File",
// };
// system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, null, testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.AreEqual("No USB disks", system.USBDisks);
// Assert.HasCount(0, testingTelegramBot.Messages);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateUSBDevices_empty_Test()
//{
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Test",
// ConfigFileName = "Config File",
// };
// system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, [], testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.AreEqual("No USB disks", system.USBDisks);
// Assert.HasCount(0, testingTelegramBot.Messages);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateUSBDevices_NoDisk_Test()
//{
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Test",
// ConfigFileName = "Config File",
// };
// List<string> usbDisks = ["No USB disks"];
// system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.AreEqual("No USB disks", system.USBDisks);
// Assert.HasCount(0, testingTelegramBot.Messages);
// //Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk removed", testingTelegramBot.Messages[0]);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateUSBDevices_NoDiskUpdate_Test()
//{
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Test",
// ConfigFileName = "Config File",
// USBDisks = "No USB disks"
// };
// List<string> usbDisks = ["No USB disks"];
// system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.AreEqual("No USB disks", system.USBDisks);
// Assert.HasCount(0, testingTelegramBot.Messages);
// //Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk removed", testingTelegramBot.Messages[0]);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateUSBDevices_DiskRemoved_Test()
//{
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Test",
// ConfigFileName = "Config File",
// USBDisks = "disk 1\r\ndisk 2\r\ndisk 3"
// };
// List<string> usbDisks = ["No USB disks"];
// system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.AreEqual("No USB disks", system.USBDisks);
// Assert.HasCount(1, testingTelegramBot.Messages);
// Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk removed", testingTelegramBot.Messages[0]);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateUSBDevices_Adddisks_Test()
//{
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Test",
// ConfigFileName = "Config File",
// };
// List<string> usbDisks = ["disk 1", "disk 2", "disk 3"];
// system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.AreEqual("disk 1\r\ndisk 2\r\ndisk 3", system.USBDisks);
// Assert.HasCount(3, testingTelegramBot.Messages);
// Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk disk 1 detected", testingTelegramBot.Messages[0]);
// Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk disk 2 detected", testingTelegramBot.Messages[1]);
// Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk disk 3 detected", testingTelegramBot.Messages[2]);
//}
//[TestMethod]
//public async Task UCSSystemMonitorDevice_UpdateUSBDevices_Update_Test()
//{
// TestingTelegramBot testingTelegramBot = new();
// Assert.IsNotNull(testingTelegramBot);
// UCSSystem? system = new()
// {
// ComputerName = "Test",
// ConfigFileName = "Config File",
// USBDisks = "disk 1\r\ndisk 2\r\ndisk 3"
// };
// List<string> usbDisks = ["disk 1", "disk 2", "disk 3"];
// system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
// Assert.IsNotNull(system);
// Assert.AreEqual("disk 1\r\ndisk 2\r\ndisk 3", system.USBDisks);
// Assert.HasCount(0, testingTelegramBot.Messages);
//}
}
}

View File

@@ -0,0 +1,276 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.Telemetry;
namespace UCS_Status_Monitor.UnitTest.Monitor.UCSSystemTest
{
[TestClass]
public class UpdateConnectionStates_Test : MonitorTestSetup
{
public TestContext TestContext { get; set; }
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateConnectionStates_Null_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = db.UCSSystems.FirstOrDefault();
system = await UCSSystemMonitorDevice.UpdateConnectionStates(system, null, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(0, system.Devices);
Assert.HasCount(0, db.UCSDevices);
Assert.HasCount(0, testingTelegramBot.Messages);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateConnectionStates_Empty_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = db.UCSSystems.FirstOrDefault();
system = await UCSSystemMonitorDevice.UpdateConnectionStates(system, [], db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(0, system.Devices);
Assert.HasCount(0, db.UCSDevices);
Assert.HasCount(0, testingTelegramBot.Messages);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateConnectionStates_Add_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = db.UCSSystems.FirstOrDefault();
List<ConnectionState>? connectionstates = [new() {
ID = "ID42",
Name = "Device 42",
State = true,
Message = "Message 1",
LastStateChange = "now"
}];
system = await UCSSystemMonitorDevice.UpdateConnectionStates(system, connectionstates, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(1, system.Devices);
Assert.HasCount(1, db.UCSDevices);
Assert.AreEqual("ID42", db.UCSDevices.ToList()[0].BoxID);
Assert.AreEqual("Device 42", db.UCSDevices.ToList()[0].Name);
Assert.AreEqual("Message 1", db.UCSDevices.ToList()[0].Message);
Assert.IsTrue(db.UCSDevices.ToList()[0].State);
Assert.HasCount(2, testingTelegramBot.Messages);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n ID42 Device 42 Added", testingTelegramBot.Messages[0]);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n Device ID 1 Device 1 Removed", testingTelegramBot.Messages[1]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateConnectionStates_Offline_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = db.UCSSystems.FirstOrDefault();
List<ConnectionState>? connectionstates = [new() {
ID = "Device ID 1",
Name = "Device 1",
State = false,
Message = "OK",
}];
system = await UCSSystemMonitorDevice.UpdateConnectionStates(system, connectionstates, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(1, system.Devices);
Assert.HasCount(1, db.UCSDevices);
Assert.AreEqual("Device ID 1", db.UCSDevices.ToList()[0].BoxID);
Assert.AreEqual("Device 1", db.UCSDevices.ToList()[0].Name);
Assert.AreEqual("OK", db.UCSDevices.ToList()[0].Message);
Assert.IsFalse(db.UCSDevices.ToList()[0].State);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("Send - ⚠️ <b>Test - TestConfig</b>\r\n Device ID 1 Device 1 Lost Connection", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateConnectionStates_Online_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
db.UCSDevices.First().State = false;
await db.SaveChangesAsync(TestContext.CancellationToken);
UCSSystem? system = db.UCSSystems.FirstOrDefault();
List<ConnectionState>? connectionstates = [new() {
ID = "Device ID 1",
Name = "Device 1",
State = true,
Message = "OK",
}];
system = await UCSSystemMonitorDevice.UpdateConnectionStates(system, connectionstates, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(1, system.Devices);
Assert.HasCount(1, db.UCSDevices);
Assert.AreEqual("Device ID 1", db.UCSDevices.ToList()[0].BoxID);
Assert.AreEqual("Device 1", db.UCSDevices.ToList()[0].Name);
Assert.AreEqual("OK", db.UCSDevices.ToList()[0].Message);
Assert.IsTrue(db.UCSDevices.ToList()[0].State);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n Device ID 1 Device 1 Online", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateConnectionStates_Double_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = db.UCSSystems.FirstOrDefault();
List<ConnectionState>? connectionstates = [new() {
ID = "ID 2",
Name = "Device 2",
State = true,
Message = "OK",
}, new(){
ID = "ID 2",
Name = "Device 2",
State = true,
Message = "OK",
}];
system = await UCSSystemMonitorDevice.UpdateConnectionStates(system, connectionstates, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(2, system.Devices);
Assert.HasCount(2, db.UCSDevices);
Assert.AreEqual("ID 2", db.UCSDevices.ToList()[0].BoxID);
Assert.AreEqual("Device 2", db.UCSDevices.ToList()[0].Name);
Assert.AreEqual("OK", db.UCSDevices.ToList()[0].Message);
Assert.IsTrue(db.UCSDevices.ToList()[0].State);
Assert.AreEqual("ID 2", db.UCSDevices.ToList()[1].BoxID);
Assert.AreEqual("Device 2", db.UCSDevices.ToList()[1].Name);
Assert.AreEqual("OK", db.UCSDevices.ToList()[1].Message);
Assert.IsTrue(db.UCSDevices.ToList()[1].State);
Assert.HasCount(3, testingTelegramBot.Messages);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n ID 2 Device 2 Added", testingTelegramBot.Messages[0]);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n ID 2 Device 2 Added", testingTelegramBot.Messages[1]);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n Device ID 1 Device 1 Removed", testingTelegramBot.Messages[2]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateConnectionStates_DoubleCCTV_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = db.UCSSystems.FirstOrDefault();
Assert.IsNotNull(system);
db.UCSDevices.Add(new UCSDevice()
{
BoxID = "rtsp://10.68.40.2:554/stream/profile0",
Name = "Camera 7",
UCSSystem = system
});
db.UCSDevices.Add(new UCSDevice()
{
BoxID = "rtsp://10.68.40.2:554/stream/profile0",
Name = "Camera 8",
UCSSystem = system
});
db.UCSDevices.Add(new UCSDevice()
{
BoxID = "rtsp://10.68.40.2:554/stream/profile0",
Name = "Camera 2",
UCSSystem = system
});
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.HasCount(4, db.UCSDevices);
List<ConnectionState>? connectionstates = [new() {
ID = "rtsp://10.68.40.2:554/stream/profile0",
Name = "Camera 2",
State = true,
Message = "OK",
}];
system = await UCSSystemMonitorDevice.UpdateConnectionStates(system, connectionstates, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(1, system.Devices);
Assert.HasCount(1, db.UCSDevices);
Assert.AreEqual("rtsp://10.68.40.2:554/stream/profile0", db.UCSDevices.ToList()[0].BoxID);
Assert.AreEqual("Camera 2", db.UCSDevices.ToList()[0].Name);
Assert.AreEqual("OK", db.UCSDevices.ToList()[0].Message);
Assert.IsTrue(db.UCSDevices.ToList()[0].State);
//Assert.AreEqual("ID 2", db.UCSDevices.ToList()[1].BoxID);
//Assert.AreEqual("Device 2", db.UCSDevices.ToList()[1].Name);
//Assert.AreEqual("OK", db.UCSDevices.ToList()[1].Message);
//Assert.IsTrue(db.UCSDevices.ToList()[1].State);
Assert.HasCount(4, testingTelegramBot.Messages);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n rtsp://10.68.40.2:554/stream/profile0 Camera 2 Online", testingTelegramBot.Messages[0]);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n Device ID 1 Device 1 Removed", testingTelegramBot.Messages[1]);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n rtsp://10.68.40.2:554/stream/profile0 Camera 7 Removed", testingTelegramBot.Messages[2]);
Assert.AreEqual("Send - ✅ <b>Test - TestConfig</b>\r\n rtsp://10.68.40.2:554/stream/profile0 Camera 8 Removed", testingTelegramBot.Messages[3]);
}
}
}

View File

@@ -0,0 +1,125 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.Telemetry;
namespace UCS_Status_Monitor.UnitTest.Monitor.UCSSystemTest
{
[TestClass]
public class UpdateErrors_Test : MonitorTestSetup
{
public TestContext TestContext { get; set; }
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateErrors_Null_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Computer",
ConfigFileName = "Config File",
};
system = await UCSSystemMonitorDevice.UpdateErrors(system, null, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.IsEmpty(system.Errors);
Assert.HasCount(0, testingTelegramBot.Messages);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateErrors_Empty_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Computer",
ConfigFileName = "Config File",
};
system = await UCSSystemMonitorDevice.UpdateErrors(system, [], db, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.IsEmpty(system.Errors);
Assert.HasCount(0, testingTelegramBot.Messages);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateErrors_AddError_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Computer",
ConfigFileName = "Config File",
};
List<ErrorEventMessage>? errors = [new() {
Index = 42,
Message = "Error Message",
TimeGenerated = new(2025,11,5)
}];
system = await UCSSystemMonitorDevice.UpdateErrors(system, errors, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(1, system.Errors);
Assert.AreEqual(2, system.Errors.ToList()[0].Id);
Assert.AreEqual(42, system.Errors.ToList()[0].Index);
Assert.AreEqual("woensdag 5 november 2025", system.Errors.ToList()[0].TimeGenerated.ToLongDateString());
Assert.AreEqual("Error Message", system.Errors.ToList()[0].Message);
Assert.HasCount(2, db.Errors);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("Send - ‼️ <b>Computer - Config File</b>\r\n Error Message", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateErrors_UpdateError_Test()
{
using MonitorDbContext db = CreateDataBaseFactory().CreateDbContext();
Assert.IsNotNull(db);
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = db.UCSSystems.FirstOrDefault();
List<ErrorEventMessage>? errors = [new() {
Index = 42,
}];
system = await UCSSystemMonitorDevice.UpdateErrors(system, errors, db, testingTelegramBot, TestContext.CancellationToken);
await db.SaveChangesAsync(TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.HasCount(1, db.Errors);
Assert.HasCount(0, testingTelegramBot.Messages);
}
}
}

View File

@@ -0,0 +1,74 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.Monitor;
namespace UCS_Status_Monitor.UnitTest.Monitor.UCSSystemTest
{
[TestClass]
public class UpdateStartTime_Test : MonitorTestSetup
{
public TestContext TestContext { get; set; }
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateStartTime_Null_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Computer",
ConfigFileName = "Config File",
};
system = await UCSSystemMonitorDevice.UpdateStartTime(system, null, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("1-1-0001 00:00:00", system.StartTime.ToString());
Assert.HasCount(0, testingTelegramBot.Messages);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateStartTime_Empty_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Computer",
ConfigFileName = "Config File",
};
system = await UCSSystemMonitorDevice.UpdateStartTime(system, "", testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("1-1-0001 00:00:00", system.StartTime.ToString());
Assert.HasCount(0, testingTelegramBot.Messages);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateStartTime_Update_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Computer",
ConfigFileName = "Config File",
StartTime = new DateTime(2025, 1, 5)
};
system = await UCSSystemMonitorDevice.UpdateStartTime(system, "31-10-2025 02:04:00", testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("31-10-2025 02:04:00", system.StartTime.ToString());
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("Send - ♻️ <b>Computer - Config File</b>\r\n UCS restarted", testingTelegramBot.Messages[0]);
}
}
}

View File

@@ -0,0 +1,165 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Threading.Tasks;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.Monitor;
namespace UCS_Status_Monitor.UnitTest.Monitor.UCSSystemTest
{
[TestClass]
public class UpdateUSBDevices_Test : MonitorTestSetup
{
public TestContext TestContext { get; set; }
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateUSBDevices_Null_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Test",
ConfigFileName = "Config File",
};
system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, null, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("No USB disks", system.USBDisks);
Assert.HasCount(0, testingTelegramBot.Messages);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateUSBDevices_Empty_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Test",
ConfigFileName = "Config File",
};
system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, [], testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("No USB disks", system.USBDisks);
Assert.HasCount(0, testingTelegramBot.Messages);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateUSBDevices_NoDisk_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Test",
ConfigFileName = "Config File",
};
List<string> usbDisks = ["No USB disks"];
system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("No USB disks", system.USBDisks);
Assert.HasCount(0, testingTelegramBot.Messages);
//Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk removed", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateUSBDevices_NoDiskUpdate_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Test",
ConfigFileName = "Config File",
USBDisks = "No USB disks"
};
List<string> usbDisks = ["No USB disks"];
system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("No USB disks", system.USBDisks);
Assert.HasCount(0, testingTelegramBot.Messages);
//Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk removed", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateUSBDevices_DiskRemoved_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Test",
ConfigFileName = "Config File",
USBDisks = "disk 1\r\ndisk 2\r\ndisk 3"
};
List<string> usbDisks = ["No USB disks"];
system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("No USB disks", system.USBDisks);
Assert.HasCount(1, testingTelegramBot.Messages);
Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk removed", testingTelegramBot.Messages[0]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateUSBDevices_Adddisks_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Test",
ConfigFileName = "Config File",
};
List<string> usbDisks = ["disk 1", "disk 2", "disk 3"];
system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("disk 1\r\ndisk 2\r\ndisk 3", system.USBDisks);
Assert.HasCount(3, testingTelegramBot.Messages);
Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk disk 1 detected", testingTelegramBot.Messages[0]);
Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk disk 2 detected", testingTelegramBot.Messages[1]);
Assert.AreEqual("Send - ⚠️ <b>Test - Config File</b>\r\n USB disk disk 3 detected", testingTelegramBot.Messages[2]);
}
[TestMethod]
public async Task UCSSystemMonitorDevice_UpdateUSBDevices_Update_Test()
{
TestingTelegramBot testingTelegramBot = new();
Assert.IsNotNull(testingTelegramBot);
UCSSystem? system = new()
{
ComputerName = "Test",
ConfigFileName = "Config File",
USBDisks = "disk 1\r\ndisk 2\r\ndisk 3"
};
List<string> usbDisks = ["disk 1", "disk 2", "disk 3"];
system = await UCSSystemMonitorDevice.UpdateUSBDevices(system, usbDisks, testingTelegramBot, TestContext.CancellationToken);
Assert.IsNotNull(system);
Assert.AreEqual("disk 1\r\ndisk 2\r\ndisk 3", system.USBDisks);
Assert.HasCount(0, testingTelegramBot.Messages);
}
}
}

View File

@@ -1,231 +0,0 @@
//using Microsoft.Extensions.Configuration;
//using Microsoft.Extensions.Logging;
//using Microsoft.VisualStudio.TestTools.UnitTesting;
//using Moq;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading;
//using System.Threading.Tasks;
//using UCS_Status_Monitor.Database;
//using UCS_Status_Monitor.Sensors;
//using UCS_Status_Monitor.Telegram;
//using UCS_Status_Monitor.Extensions;
//namespace UCS_Status_Monitor.UnitTest
//{
// [TestClass]
// public class SensorService_Test
// {
// private static readonly Dictionary<string, string> inMemorySettings = new()
// {
// { "Database", "UCSStatusMonitorTestDB.db" },
// { "SectionName:SomeKey", "SectionValue" },
// };
// private readonly IConfiguration configuration = new ConfigurationBuilder()
// .AddInMemoryCollection(inMemorySettings)
// .Build();
// //[ClassInitialize]
// //public static void CreateNewDatabase(TestContext context)
// //{
// // //database is in bin folder van testporject
// // using var dbContext = new MonitorDbContext();
// // dbContext.Database.EnsureDeleted();
// // dbContext.Database.EnsureCreated();
// //}
// [TestInitialize]
// public void CreateNewDatabase()
// {
// //database is in bin folder van testproject
// using var dbContext = new MonitorDbContext(configuration);
// dbContext.Database.EnsureDeleted();
// dbContext.Database.EnsureCreated();
// }
// //{"Date":"2021-11-18T11:43:55.3638576+01:00",
// //"ComputerName":"S01-PCD04",
// //"Configfile":"Remote ID List Test - DEBUG BUILD",
// //"UCSId":"C1",
// //"TxString":"Rust",
// //"TxData":"K.03 - geen lekkage",
// //"Count":3}
// [TestMethod]
// public void SensorPacketTest()
// {
// ILogger<SensorService> logger = Mock.Of<ILogger<SensorService>>();
// ITelegramBotService telegrambot = Mock.Of<ITelegramBotService>();
// SensorService sensorService = new(logger, configuration, telegrambot);
// SensorPacket sensorPacket = new()
// {
// Date = DateTime.Parse("2021-11-18T11:43:55.3638576+01:00"),
// ComputerName = "S01-PCD04",
// Configfile = "Remote ID List Test",
// UCSId = "C1",
// TxString = "Rust",
// TxData = "K.03 - geen lekkage",
// Count = 3
// };
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(1, sensorService.GetSensorCount());
// Assert.AreEqual("S01-PCD04", sensorService.GetLastSensor().ComputerName);
// Assert.AreEqual("Remote ID List Test", sensorService.GetLastSensor().Configfile);
// Assert.AreEqual("C1", sensorService.GetLastSensor().UCSId);
// Assert.AreEqual("Rust", sensorService.GetLastSensor().TxString);
// Assert.AreEqual("K.03 - geen lekkage", sensorService.GetLastSensor().TxData);
// Assert.AreEqual(3, sensorService.GetLastSensor().Count);
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.ComputerName = "P01-UCS99";
// sensorPacket.Count = 10;
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(2, sensorService.GetSensorCount());
// Assert.AreEqual("P01-UCS99", sensorService.GetLastSensor().ComputerName);
// Assert.AreEqual("Remote ID List Test", sensorService.GetLastSensor().Configfile);
// Assert.AreEqual("C1", sensorService.GetLastSensor().UCSId);
// Assert.AreEqual("Rust", sensorService.GetLastSensor().TxString);
// Assert.AreEqual("K.03 - geen lekkage", sensorService.GetLastSensor().TxData);
// Assert.AreEqual(10, sensorService.GetLastSensor().Count);
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.ComputerName = "P10-UCS00";
// sensorPacket.Count = 100;
// sensorPacket.TxString = "alARM";
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(3, sensorService.GetSensorCount());
// Assert.AreEqual("P10-UCS00", sensorService.GetLastSensor().ComputerName);
// Assert.AreEqual("Remote ID List Test", sensorService.GetLastSensor().Configfile);
// Assert.AreEqual("C1", sensorService.GetLastSensor().UCSId);
// Assert.AreEqual("alARM", sensorService.GetLastSensor().TxString);
// Assert.AreEqual("K.03 - geen lekkage", sensorService.GetLastSensor().TxData);
// Assert.AreEqual(100, sensorService.GetLastSensor().Count);
// Assert.IsTrue(sensorService.GetLastSensor().IsAlarm());
// }
// [TestMethod]
// public void MissingValuesPacketTest()
// {
// ILogger<SensorService> logger = Mock.Of<ILogger<SensorService>>();
// ITelegramBotService telegrambot = Mock.Of<ITelegramBotService>();
// SensorService sensorService = new(logger, configuration, telegrambot);
// SensorPacket sensorPacket = new()
// {
// //Date = DateTime.Parse("2021-11-18T11:43:55.3638576+01:00"),
// //ComputerName = "S01-PCD04",
// //Configfile = "Remote ID List Test",
// //UCSId = "C1",
// //TxString = "Rust",
// //TxData = "K.03 - geen lekkage",
// //Count = 3
// };
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(1, sensorService.GetSensorCount());
// Assert.AreEqual("??", sensorService.GetLastSensor().ComputerName);
// Assert.AreEqual("??", sensorService.GetLastSensor().Configfile);
// Assert.AreEqual("??", sensorService.GetLastSensor().UCSId);
// Assert.AreEqual("??", sensorService.GetLastSensor().TxString);
// Assert.AreEqual("??", sensorService.GetLastSensor().TxData);
// Assert.AreEqual(0, sensorService.GetLastSensor().Count);
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// }
// [TestMethod]
// public void IsAlarmTest()
// {
// ILogger<SensorService> logger = Mock.Of<ILogger<SensorService>>();
// ITelegramBotService telegrambot = Mock.Of<ITelegramBotService>();
// SensorService sensorService = new(logger, configuration, telegrambot);
// SensorPacket sensorPacket = new()
// {
// TxString = "Rust",
// };
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(1, sensorService.GetSensorCount());
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.TxString = "rust";
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(2, sensorService.GetSensorCount());
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.TxString = "lsdjfkdl";
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(3, sensorService.GetSensorCount());
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.TxString = "";
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(4, sensorService.GetSensorCount());
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.TxString = null;
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(5, sensorService.GetSensorCount());
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.TxString = "alarm";
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(6, sensorService.GetSensorCount());
// Assert.IsTrue(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.TxString = "ALARM";
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(7, sensorService.GetSensorCount());
// Assert.IsTrue(sensorService.GetLastSensor().IsAlarm());
// sensorPacket.TxString = "AlArM";
// sensorService.ProcessPacket(sensorPacket);
// Assert.AreEqual(8, sensorService.GetSensorCount());
// Assert.IsTrue(sensorService.GetLastSensor().IsAlarm());
// }
// [TestMethod]
// public void SensorLoadTest()
// {
// ILogger<SensorService> logger = Mock.Of<ILogger<SensorService>>();
// ITelegramBotService telegrambot = Mock.Of<ITelegramBotService>();
// SensorService sensorService = new(logger, configuration, telegrambot);
// sensorService.StartAsync(CancellationToken.None);
// for (int i = 0; i < 1000; i++)
// {
// SensorPacket sensorPacket = new()
// {
// Date = DateTime.Parse("2021-11-18T11:43:55.3638576+01:00"),
// ComputerName = "S01-PCD04",
// Configfile = "Remote ID List Test",
// UCSId = "C1",
// TxString = "Rust",
// TxData = "K.03 - geen lekkage",
// Count = 3
// };
// _ = sensorService.EnqueuePacket(sensorPacket);
// }
// while (sensorService.IsChannelEmpty() == false)
// {
// Thread.Sleep(100);
// }
// Assert.AreEqual(1000, sensorService.GetSensorCount());
// Assert.AreEqual("S01-PCD04", sensorService.GetLastSensor().ComputerName);
// Assert.AreEqual("Remote ID List Test", sensorService.GetLastSensor().Configfile);
// Assert.AreEqual("C1", sensorService.GetLastSensor().UCSId);
// Assert.AreEqual("Rust", sensorService.GetLastSensor().TxString);
// Assert.AreEqual("K.03 - geen lekkage", sensorService.GetLastSensor().TxData);
// Assert.AreEqual(3, sensorService.GetLastSensor().Count);
// Assert.IsFalse(sensorService.GetLastSensor().IsAlarm());
// }
// }
//}

View File

@@ -1,13 +1,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UCS_Status_Monitor.Telegram;
namespace UCS_Status_Monitor.UnitTest

View File

@@ -0,0 +1,53 @@
{
"Base": {
"time": 1755783197,
"local_time": "2025-08-21 15:33:17",
"fw": "RUT2_R_00.07.06.19",
"name": "R11ROUT01",
"id": "1"
},
"GSM": {
"connstate": "Connected",
"psstate": "attached",
"imei": "864431061231637",
"iccid": "8931163200127397054F",
"model": "SLM750-VE",
"manuf": "Meiglink",
"serial": "750VE14LHD101002311",
"revision": "SLM750-V_4.57.20_EQ101",
"imsi": "204163406761217",
"simstate": "inserted",
"pinstate": "OK",
"modemtime": "25/08/21,13:33:16",
"rssi": -69,
"rscp": 0,
"ecio": 0,
"rsrp": -107,
"sinr": 9,
"rsrq": -13,
"operator": "20416",
"opernum": 20416,
"conntype": "LTE",
"temp": 390,
"pincount": 3,
"network": "LTE,20416",
"serving": "3,LTE,FDD LTE,204,16",
"modem": "1-1",
"ip": [
"178.225.75.54"
],
"ipv6": []
},
"Usage": {
"tx": 84,
"rx": 24069
},
"MNF": {
"name": "RUT2400DXXXX",
"serial": "1127218922",
"mac": "001E42586F09",
"maceth": "001E42586F0A",
"batch": "0114",
"hwver": "0011"
}
}

View File

@@ -0,0 +1,45 @@
{
"Base": {
"time": 1748264319,
"local_time": "2025-05-26 14:58:39",
"fw": "RUT2_R_00.07.06.16",
"name": "S11ROUT01",
"id": "1"
},
"GSM": {
"connstate": "Connected",
"psstate": "attached",
"imei": "864431061227585",
"iccid": "8931163200123557453F",
"model": "SLM750-VE",
"manuf": "Meiglink",
"serial": "750VE14LHD101001906",
"revision": "SLM750-V_4.57.20_EQ101",
"imsi": "204163405749807",
"simstate": "inserted",
"pinstate": "OK",
"modemtime": "25/05/26,12:58:29",
"operator": "Odido Odido",
"opernum": 20416,
"conntype": "LTE",
"temp": 470,
"pincount": 3,
"network": "LTE,20416",
"serving": "3,LTE,FDD LTE,204,16",
"modem": "1-1",
"ip": [ "178.225.152.54" ],
"ipv6": []
},
"Usage": {
"tx": 2629954194,
"rx": 1450717947
},
"MNF": {
"name": "RUT2400DXXXX",
"serial": "1127211127",
"mac": "001E425E548A",
"maceth": "001E425E548B",
"batch": "0114",
"hwver": "0011"
}
}

View File

@@ -2,6 +2,7 @@
using System;
using System.Diagnostics;
using System.IO;
using UCS_Status_Monitor.MQTT;
using UCS_Status_Monitor.MQTT.Teltonika;
namespace UCS_Status_Monitor.UnitTest
@@ -9,46 +10,46 @@ namespace UCS_Status_Monitor.UnitTest
[TestClass]
public class Teltonika_Test
{
[TestMethod]
public void Parse_Teltonika_Json()
{
string json = "";
string device = "testdevice";
string location = "somewhere";
var message = TeltonikaMessage.Deserialize(json, device, location);
Assert.IsNull(message);
//[TestMethod]
//public void Parse_Teltonika_Json()
//{
// string json = "";
// string device = "testdevice";
// string location = "somewhere";
// var message = TeltonikaMessage.Deserialize(json, device, location);
// Assert.IsNull(message);
json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
message = TeltonikaMessage.Deserialize(json, device, location);
Assert.IsNull(message);
// json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
// message = TeltonikaMessage.Deserialize(json, device, location);
// Assert.IsNull(message);
json = "[\"Temp\":\"360\",\"Uptime\":\"100680\",\"ThisMonthRX\":\"631408118\",\"ThisMonthTX\":\"967449262\",\"RSSI\":\"-62\",\"LastMonthRX\":\"63108118\",\"LastMonthTX\":\"94926132\",\"WanIp\":\"178,224,157,191\"]";
message = TeltonikaMessage.Deserialize(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(TeltonikaMessage));
// json = "[\"Temp\":\"360\",\"Uptime\":\"100680\",\"ThisMonthRX\":\"631408118\",\"ThisMonthTX\":\"967449262\",\"RSSI\":\"-62\",\"LastMonthRX\":\"63108118\",\"LastMonthTX\":\"94926132\",\"WanIp\":\"178,224,157,191\"]";
// message = TeltonikaMessage.Deserialize(json, device, location);
// Assert.IsNotNull(message);
// Assert.IsInstanceOfType(message, typeof(TeltonikaMessage));
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
//Temp
Assert.AreEqual(36.0, message.TempValue());
Assert.AreEqual("36℃", message.Temp);
//Uptime
TimeSpan uptime = TimeSpan.FromSeconds(100680);
Assert.AreEqual(uptime, message.UptimeValue());
Assert.AreEqual("1 days 3 hours 58 min 0 sec", message.Uptime);
//ThisMonthRX
Assert.AreEqual((UInt32)631408118, message.ThisMonthRX);
//ThisMonthTX
Assert.AreEqual((UInt32)967449262, message.ThisMonthTX);
//LastMonthRX
Assert.AreEqual((UInt32)63108118, message.LastMonthRX);
//LastMonthTX
Assert.AreEqual((UInt32)94926132, message.LastMonthTX);
//RSSI
Assert.AreEqual(-62, message.RSSI);
//WanIp
Assert.AreEqual("178.224.157.191", message.WanIp);
}
// Assert.AreEqual(device, message.Device);
// Assert.AreEqual(location, message.Location);
// //Temp
// Assert.AreEqual(36.0, message.TempValue());
// Assert.AreEqual("36℃", message.Temp);
// //Uptime
// TimeSpan uptime = TimeSpan.FromSeconds(100680);
// Assert.AreEqual(uptime, message.UptimeValue());
// Assert.AreEqual("1 days 3 hours 58 min 0 sec", message.Uptime);
// //ThisMonthRX
// Assert.AreEqual((UInt32)631408118, message.ThisMonthRX);
// //ThisMonthTX
// Assert.AreEqual((UInt32)967449262, message.ThisMonthTX);
// //LastMonthRX
// Assert.AreEqual((UInt32)63108118, message.LastMonthRX);
// //LastMonthTX
// Assert.AreEqual((UInt32)94926132, message.LastMonthTX);
// //RSSI
// Assert.AreEqual(-62, message.RSSI);
// //WanIp
// Assert.AreEqual("178.224.157.191", message.WanIp);
//}
[TestMethod]
[DeploymentItem(@"TeltonikaV2.json")]
@@ -62,18 +63,77 @@ namespace UCS_Status_Monitor.UnitTest
}
//[TestMethod]
//[DeploymentItem(@"TeltonikaV2.json")]
//public void Parse_Teltonika_V2_Json()
//{
// string json = "";
// string device = "testdevice";
// string location = "somewhere";
// var message = TeltonikaMessageV2.Deserialize(json, device, location);
// Assert.IsNull(message);
// json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
// message = TeltonikaMessageV2.Deserialize(json, device, location);
// Assert.IsNull(message);
// var myfile = "TeltonikaV2.json";
// Assert.IsTrue(File.Exists(myfile), "Deployment failed: {0} did not get deployed.", myfile);
// json = File.ReadAllText(myfile);
// Debug.WriteLine(json);
// message = TeltonikaMessageV2.Deserialize(json, device, location);
// Assert.IsNotNull(message);
// Assert.IsInstanceOfType(message, typeof(TeltonikaMessageV2));
// Assert.AreEqual(device, message.Device);
// Assert.AreEqual(location, message.Location);
// //Temp
// Assert.AreEqual(380, message.GSM.Temperature);
// Assert.AreEqual(38.0, message.GSM.TempValue());
// Assert.AreEqual("38℃", message.GSM.TempString());
// message.GSM.Temperature = null;
// Assert.IsNull(message.GSM.Temperature);
// Assert.AreEqual(0, message.GSM.TempValue());
// Assert.AreEqual("??℃", message.GSM.TempString());
// //Uptime
// //Assert.AreEqual(1698233689, message.Base.Time);
// //TimeSpan uptime = TimeSpan.FromSeconds(1698233689);
// //Assert.AreEqual(uptime, message.Base.UptimeValue());
// //Assert.AreEqual("1 days 3 hours 58 min 0 sec", message.Base.UptimeString(new DateTime(2023, 10, 9, 0, 0, 00)));
// //ThisMonthRX
// Assert.AreEqual(30888399, message.Usage.Rx);
// //ThisMonthTX
// Assert.AreEqual(4918720, message.Usage.Tx);
// ////LastMonthRX
// //Assert.AreEqual((UInt32)63108118, message.LastMonthRX);
// ////LastMonthTX
// //Assert.AreEqual((UInt32)94926132, message.LastMonthTX);
// //RSSI
// Assert.AreEqual(-72, message.GSM.RSSI);
// //WanIp
// Assert.AreEqual("100.65.5.230", message.GSM.IpV4[0]);
//}
[TestMethod]
[DeploymentItem(@"TeltonikaV2.json")]
[DeploymentItem(@"TeltonikaV2-7_06_19.json")]
public void Parse_Teltonika_V2_Json()
{
string json = "";
string device = "testdevice";
string location = "somewhere";
var message = TeltonikaMessageV2.Deserialize(json, device, location);
TeltonikaMessageV2? message = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(json, device, location);
Assert.IsNull(message);
json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
message = TeltonikaMessageV2.Deserialize(json, device, location);
message = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(json, device, location);
Assert.IsNull(message);
var myfile = "TeltonikaV2.json";
@@ -81,28 +141,35 @@ namespace UCS_Status_Monitor.UnitTest
json = File.ReadAllText(myfile);
Debug.WriteLine(json);
message = TeltonikaMessageV2.Deserialize(json, device, location);
message = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(TeltonikaMessageV2));
Assert.IsInstanceOfType<TeltonikaMessageV2>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
//Temp
Assert.IsNotNull(message.GSM);
Assert.AreEqual(380, message.GSM.Temperature);
Assert.AreEqual(38.0, message.GSM.TempValue());
Assert.AreEqual("38℃", message.GSM.TempString());
message.GSM.Temperature = null;
Assert.IsNull(message.GSM.Temperature);
Assert.AreEqual(0, message.GSM.TempValue());
Assert.AreEqual("??℃", message.GSM.TempString());
//Uptime
//Assert.AreEqual(1698233689, message.Base.Time);
//TimeSpan uptime = TimeSpan.FromSeconds(1698233689);
//Assert.AreEqual(uptime, message.Base.UptimeValue());
//Assert.AreEqual("1 days 3 hours 58 min 0 sec", message.Base.UptimeString());
//Assert.AreEqual("1 days 3 hours 58 min 0 sec", message.Base.UptimeString(new DateTime(2023, 10, 9, 0, 0, 00)));
////ThisMonthRX
//Assert.AreEqual((UInt32)631408118, message.ThisMonthRX);
////ThisMonthTX
//Assert.AreEqual((UInt32)967449262, message.ThisMonthTX);
Assert.IsNotNull(message.Usage);
//ThisMonthRX
Assert.AreEqual((UInt64)30888399, message.Usage.Rx);
//ThisMonthTX
Assert.AreEqual((UInt64)4918720, message.Usage.Tx);
////LastMonthRX
//Assert.AreEqual((UInt32)63108118, message.LastMonthRX);
////LastMonthTX
@@ -112,7 +179,238 @@ namespace UCS_Status_Monitor.UnitTest
Assert.AreEqual(-72, message.GSM.RSSI);
//WanIp
Assert.IsNotNull(message.GSM.IpV4);
Assert.AreEqual("100.65.5.230", message.GSM.IpV4[0]);
}
[TestMethod]
[DeploymentItem(@"TeltonikaV2-7_06_19.json")]
public void Parse_Teltonika_V2_Firmware_7_06_19_Json()
{
string device = "testdevice";
string location = "somewhere";
var myfile = "TeltonikaV2-7_06_19.json";
Assert.IsTrue(File.Exists(myfile), "Deployment failed: {0} did not get deployed.", myfile);
string json = File.ReadAllText(myfile);
Debug.WriteLine(json);
var message = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType<TeltonikaMessageV2>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
Assert.IsNotNull(message.Base);
Assert.AreEqual((uint)1755783197, message.Base.Time);
//Temp
Assert.IsNotNull(message.GSM);
Assert.AreEqual(390, message.GSM.Temperature);
Assert.AreEqual(39.0, message.GSM.TempValue());
Assert.AreEqual("39℃", message.GSM.TempString());
message.GSM.Temperature = null;
Assert.IsNull(message.GSM.Temperature);
Assert.AreEqual(0, message.GSM.TempValue());
Assert.AreEqual("??℃", message.GSM.TempString());
//Uptime
//Assert.AreEqual(1698233689, message.Base.Time);
//TimeSpan uptime = TimeSpan.FromSeconds(1698233689);
//Assert.AreEqual(uptime, message.Base.UptimeValue());
//Assert.AreEqual("1 days 3 hours 58 min 0 sec", message.Base.UptimeString(new DateTime(2023, 10, 9, 0, 0, 00)));
Assert.IsNotNull(message.Usage);
//ThisMonthRX
Assert.AreEqual((UInt64)24069, message.Usage.Rx);
//ThisMonthTX
Assert.AreEqual((UInt64)84, message.Usage.Tx);
////LastMonthRX
//Assert.AreEqual((UInt32)63108118, message.LastMonthRX);
////LastMonthTX
//Assert.AreEqual((UInt32)94926132, message.LastMonthTX);
//RSSI
Assert.AreEqual(-69, message.GSM.RSSI);
//WanIp
Assert.IsNotNull(message.GSM.IpV4);
Assert.AreEqual("178.225.75.54", message.GSM.IpV4[0]);
}
//[TestMethod]
//[DeploymentItem(@"TeltonikaV2.json")]
//public void Parse_Teltonika_V2_Json_2()
//{
// string json = "";
// string device = "testdevice";
// string location = "somewhere";
// var message = MQTTDevice.Deserialize<TeltonikaMessageV2>(json, device, location);
// Assert.IsNull(message);
// json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
// message = TeltonikaMessageV2.Deserialize(json, device, location);
// Assert.IsNull(message);
// var myfile = "TeltonikaV2.json";
// Assert.IsTrue(File.Exists(myfile), "Deployment failed: {0} did not get deployed.", myfile);
// json = File.ReadAllText(myfile);
// Debug.WriteLine(json);
// message = TeltonikaMessageV2.Deserialize(json, device, location);
// Assert.IsNotNull(message);
// Assert.IsInstanceOfType(message, typeof(TeltonikaMessageV2));
// Assert.AreEqual(device, message.Device);
// Assert.AreEqual(location, message.Location);
// //Temp
// Assert.AreEqual(380, message.GSM.Temperature);
// Assert.AreEqual(38.0, message.GSM.TempValue());
// Assert.AreEqual("38℃", message.GSM.TempString());
// message.GSM.Temperature = null;
// Assert.IsNull(message.GSM.Temperature);
// Assert.AreEqual(0, message.GSM.TempValue());
// Assert.AreEqual("??℃", message.GSM.TempString());
// //Uptime
// //Assert.AreEqual(1698233689, message.Base.Time);
// //TimeSpan uptime = TimeSpan.FromSeconds(1698233689);
// //Assert.AreEqual(uptime, message.Base.UptimeValue());
// //Assert.AreEqual("1 days 3 hours 58 min 0 sec", message.Base.UptimeString(new DateTime(2023, 10, 9, 0, 0, 00)));
// //ThisMonthRX
// Assert.AreEqual(30888399, message.Usage.Rx);
// //ThisMonthTX
// Assert.AreEqual(4918720, message.Usage.Tx);
// ////LastMonthRX
// //Assert.AreEqual((UInt32)63108118, message.LastMonthRX);
// ////LastMonthTX
// //Assert.AreEqual((UInt32)94926132, message.LastMonthTX);
// //RSSI
// Assert.AreEqual(-72, message.GSM.RSSI);
// //WanIp
// Assert.AreEqual("100.65.5.230", message.GSM.IpV4[0]);
//}
[TestMethod]
[DeploymentItem(@"TeltonikaV2.json")]
public void Parse_Teltonika_V2_Json_2()
{
string json = "";
string device = "testdevice";
string location = "somewhere";
TeltonikaMessageV2? message = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(json, device, location);
Assert.IsNull(message);
json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
message = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(json, device, location);
Assert.IsNull(message);
var myfile = "TeltonikaV2.json";
Assert.IsTrue(File.Exists(myfile), "Deployment failed: {0} did not get deployed.", myfile);
json = File.ReadAllText(myfile);
Debug.WriteLine(json);
message = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType<TeltonikaMessageV2>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
//Temp
Assert.IsNotNull(message.GSM);
Assert.AreEqual(380, message.GSM.Temperature);
Assert.AreEqual(38.0, message.GSM.TempValue());
Assert.AreEqual("38℃", message.GSM.TempString());
message.GSM.Temperature = null;
Assert.IsNull(message.GSM.Temperature);
Assert.AreEqual(0, message.GSM.TempValue());
Assert.AreEqual("??℃", message.GSM.TempString());
//Uptime
Assert.IsNotNull(message.Base);
Assert.AreEqual((uint)1698233689, message.Base.Time);
Assert.AreEqual("2023-10-25 13:34:49", message.Base.LocalTime);
//TimeSpan uptime = TimeSpan.FromSeconds(1698233689);
//Assert.AreEqual(uptime, message.Base.UptimeValue());
//Assert.AreEqual("1 days 3 hours 58 min 0 sec", message.Base.UptimeString(new DateTime(2023, 10, 9, 0, 0, 00)));
Assert.IsNotNull(message.Usage);
//ThisMonthRX
Assert.AreEqual((UInt64)30888399, message.Usage.Rx);
//ThisMonthTX
Assert.AreEqual((UInt64)4918720, message.Usage.Tx);
////LastMonthRX
//Assert.AreEqual((UInt32)63108118, message.LastMonthRX);
////LastMonthTX
//Assert.AreEqual((UInt32)94926132, message.LastMonthTX);
//RSSI
Assert.AreEqual(-72, message.GSM.RSSI);
//WanIp
Assert.IsNotNull(message.GSM.IpV4);
Assert.AreEqual("100.65.5.230", message.GSM.IpV4[0]);
}
[TestMethod]
[DeploymentItem(@"TeltonikaV2Error.json")]
public void Parse_Teltonika_Error()
{
string device = "testdevice";
string location = "somewhere";
var myfile = "TeltonikaV2Error.json";
Assert.IsTrue(File.Exists(myfile), "Deployment failed: {0} did not get deployed.", myfile);
string json = File.ReadAllText(myfile);
Debug.WriteLine(json);
TeltonikaMessageV2? message = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(json, device, location);
Assert.IsNotNull(message);
Assert.IsInstanceOfType<TeltonikaMessageV2>(message);
Assert.AreEqual(device, message.Device);
Assert.AreEqual(location, message.Location);
//Temp
Assert.IsNotNull(message.GSM);
Assert.AreEqual(470, message.GSM.Temperature);
Assert.AreEqual(47.0, message.GSM.TempValue());
Assert.AreEqual("47℃", message.GSM.TempString());
message.GSM.Temperature = null;
Assert.IsNull(message.GSM.Temperature);
Assert.AreEqual(0, message.GSM.TempValue());
Assert.AreEqual("??℃", message.GSM.TempString());
//Time
Assert.IsNotNull(message.Base);
Assert.AreEqual((uint)1748264319, message.Base.Time);
Assert.AreEqual("2025-05-26 14:58:39", message.Base.LocalTime);
//Usage
Assert.IsNotNull(message.Usage);
Assert.AreEqual((UInt64)1450717947, message.Usage.Rx);
Assert.AreEqual((UInt64)2629954194, message.Usage.Tx);
//RSSI
Assert.AreEqual(0, message.GSM.RSSI);
//WanIp
Assert.IsNotNull(message.GSM.IpV4);
Assert.AreEqual("178.225.152.54", message.GSM.IpV4[0]);
}
}
}

View File

@@ -1,32 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<TargetFramework>net10.0-windows7.0</TargetFramework>
<IsPackable>false</IsPackable>
<Platforms>AnyCPU;x64</Platforms>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Remove="TeltonikaV2-7_06_19.json" />
<None Remove="TeltonikaV2.json" />
<None Remove="TeltonikaV2Error.json" />
</ItemGroup>
<ItemGroup>
<Content Include="TeltonikaV2-7_06_19.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="TeltonikaV2.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="TeltonikaV2Error.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="MSTest.TestAdapter" Version="3.5.0" />
<PackageReference Include="MSTest.TestFramework" Version="3.5.0" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="MQTTnet" Version="5.1.0.1559" />
<PackageReference Include="MSTest.TestAdapter" Version="4.1.0" />
<PackageReference Include="MSTest.TestFramework" Version="4.1.0" />
<PackageReference Include="coverlet.collector" Version="8.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Telegram.Bot" Version="22.9.5.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -12,20 +12,40 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UCS_Status_Monitor.EventLogCreator", "UCS_Status_Monitor.EventLogCreator\UCS_Status_Monitor.EventLogCreator.csproj", "{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D02A2712-C76C-4609-A575-E716BA86EE77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D02A2712-C76C-4609-A575-E716BA86EE77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D02A2712-C76C-4609-A575-E716BA86EE77}.Debug|x64.ActiveCfg = Debug|x64
{D02A2712-C76C-4609-A575-E716BA86EE77}.Debug|x64.Build.0 = Debug|x64
{D02A2712-C76C-4609-A575-E716BA86EE77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D02A2712-C76C-4609-A575-E716BA86EE77}.Release|Any CPU.Build.0 = Release|Any CPU
{D02A2712-C76C-4609-A575-E716BA86EE77}.Release|x64.ActiveCfg = Release|x64
{D02A2712-C76C-4609-A575-E716BA86EE77}.Release|x64.Build.0 = Release|x64
{DDD0A971-1756-4866-9945-B9AB5726EBFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDD0A971-1756-4866-9945-B9AB5726EBFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDD0A971-1756-4866-9945-B9AB5726EBFF}.Debug|x64.ActiveCfg = Debug|x64
{DDD0A971-1756-4866-9945-B9AB5726EBFF}.Debug|x64.Build.0 = Debug|x64
{DDD0A971-1756-4866-9945-B9AB5726EBFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDD0A971-1756-4866-9945-B9AB5726EBFF}.Release|Any CPU.Build.0 = Release|Any CPU
{DDD0A971-1756-4866-9945-B9AB5726EBFF}.Release|x64.ActiveCfg = Release|x64
{DDD0A971-1756-4866-9945-B9AB5726EBFF}.Release|x64.Build.0 = Release|x64
{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}.Debug|Any CPU.Build.0 = Debug|Any CPU
{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}.Debug|x64.ActiveCfg = Debug|Any CPU
{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}.Debug|x64.Build.0 = Debug|Any CPU
{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}.Release|Any CPU.ActiveCfg = Release|Any CPU
{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}.Release|Any CPU.Build.0 = Release|Any CPU
{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}.Release|x64.ActiveCfg = Release|Any CPU
{296EE0CF-0AB5-4C04-8DB4-D0CB53389115}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -0,0 +1,55 @@
@implements IDisposable
@inject IDbContextFactory<MonitorDbContext> _contextFactory
@inject MonitorHandler _monitorHandler
<div class="row">
@foreach (var cam in camsList)
{
<div class="col mb-4">
<div class="card border-@cam.Connected.BootstrapColor() rounded" style="width: 18rem;">
<div class="card-body py-1 h-auto text-bg-@cam.Connected.BootstrapColor()">
<h5 class="card-title text-center my-1">@cam.Device</h5>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item py-2">@cam.Location</li>
<li class="list-group-item py-2">Connected: @cam.Connected</li>
<li class="list-group-item py-2">Ready: @cam.SystemReady</li>
<li class="list-group-item py-2">Temperature: @cam.Temperature</li>
<li class="list-group-item py-2">Timestamp: @cam.Timestamp.FormatDateTime()</li>
<li class="list-group-item py-2">
<a href="Home/CameraLogging?id=@cam.Id">
<i class="bi-calendar-check" style="color: white;"></i>
</a>
</li>
</ul>
</div>
</div>
}
</div>
@code
{
private List<Models.Database.AxisCam> camsList = [];
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await UpdateTable();
_monitorHandler.DeviceChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
}
await base.OnAfterRenderAsync(firstRender);
}
public void Dispose()
{
_monitorHandler.DeviceChanged -= async (s, e) => await InvokeAsync(() => UpdateTable());
}
private async Task UpdateTable()
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
camsList = await db.AxisCams.OrderBy(o => o.Device).ToListAsync();
this.StateHasChanged();
}
}

View File

@@ -0,0 +1,181 @@
@using Microsoft.Extensions.DependencyInjection
@using Microsoft.Extensions.Hosting
@using UCS_Status_Monitor.MQTT
@implements IDisposable
@inject IDbContextFactory<MonitorDbContext> _contextFactory
@inject MonitorHandler _monitorHandler
@inject Telegram.ITelegramBotMessageChannel _telegramBotMessageChannel
@inject IServiceProvider _serviceProvider
<table class="table table-hover table-responsive">
<thead>
<tr>
<th>
<DisplayName For="@(() => camerasList[0].Id)" />
</th>
<th>
<DisplayName For="@(() => camerasList[0].Location)" />
<a @onclick="@(() => SetSortOrder("location_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("location_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => camerasList[0].Device)" />
<a @onclick="@(() => SetSortOrder("device_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("device_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => camerasList[0].SerialNumber)" />
<a @onclick="@(() => SetSortOrder("serial_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("serial_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => camerasList[0].Connected)" />
<a @onclick="@(() => SetSortOrder("conn_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("conn_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => camerasList[0].Description)" />
<a @onclick="@(() => SetSortOrder("desc_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("desc_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => camerasList[0].SystemReady)" />
<a @onclick="@(() => SetSortOrder("ready_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("ready_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => camerasList[0].Temperature)" />
<a @onclick="@(() => SetSortOrder("temp_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("temp_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => camerasList[0].Timestamp)" />
<a @onclick="@(() => SetSortOrder("timestamp_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("timestamp_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => camerasList[0].MonitorDevice!.LastData)" />
<a @onclick="@(() => SetSortOrder("lastdata_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("lastdata_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var cam in camerasList)
{
<tr class="table-@cam.Connected.BootstrapColor()">
<td>@cam.Id</td>
<td>@cam.Location</td>
<td>@cam.Device</td>
<td>@cam.SerialNumber</td>
<td>@cam.Connected</td>
<td>@cam.Description</td>
<td>@cam.SystemReady</td>
<td>@cam.Temperature</td>
<td>@cam.Timestamp.FormatDateTime()</td>
<td>@cam.MonitorDevice?.LastData.FormatDateTime()</td>
<td>
<a @onclick="() => DeleteCamera(cam.Device)" @onclick:preventDefault href="#">
<i class="bi-trash" style="color: black;"></i>
</a>
</td>
</tr>
}
</tbody>
</table>
@code
{
private List<Models.Database.AxisCam> camerasList = [];
private string? sortOrder;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
//Debug.WriteLine($"OnAfterRenderAsync first:{firstRender}");
if (firstRender)
{
await UpdateTable();
_monitorHandler.DeviceChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
}
await base.OnAfterRenderAsync(firstRender);
}
public void Dispose()
{
_monitorHandler.DeviceChanged -= async (s, e) => await InvokeAsync(() => UpdateTable());
}
private async Task UpdateTable()
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
camerasList = (await db.AxisCams.OrderBy(o => o.Location).ToListAsync()).AddMonitorDevice(_monitorHandler).SortTable(sortOrder);
this.StateHasChanged();
}
private async Task DeleteCamera(string device)
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
var camera = db.AxisCams.Where(cam => cam.Device == device).FirstOrDefault();
if (camera != null)
{
var logs = db.Loggings.Where(l => l.AxisCam == camera);
db.Loggings.RemoveRange(logs);
db.AxisCams.Remove(camera);
await _telegramBotMessageChannel.Send($"🚮 <b>{camera.Location} - {camera.Device}</b>{Environment.NewLine} Removed from SDN monitor", default);
string topic = $"{camera.Location}/{camera.Device}";
MQTTService? mqttService = _serviceProvider.GetServices<IHostedService>().OfType<MQTTService>().Single();
await mqttService.RemoveLastWillClient(topic);
}
db.SaveChanges();
_monitorHandler.RemoveDevice(device);
await UpdateTable();
}
private async Task SetSortOrder(string order)
{
sortOrder = order;
await UpdateTable();
}
}

View File

@@ -0,0 +1,20 @@
@using System.Reflection
@using System.ComponentModel
@using System.Linq.Expressions;
@typeparam T
<label >@label</label>
@code {
[Parameter]
public Expression<Func<T>> For { get; set; }
private string label => GetDisplayName();
private string GetDisplayName()
{
var expression = (MemberExpression)For.Body;
var value = expression.Member.GetCustomAttribute(typeof(DisplayNameAttribute)) as DisplayNameAttribute;
return value?.DisplayName ?? expression.Member.Name ?? "";
}
}

View File

@@ -0,0 +1,56 @@
@implements IDisposable
@inject IDbContextFactory<MonitorDbContext> _contextFactory
@inject MonitorHandler _monitorHandler
<div class="row">
@foreach (var rout in routersList)
{
<div class="col mb-4">
<div class="card border-@rout.Connected.BootstrapColor() rounded" style="width: 18rem;">
<div class="card-body py-1 h-auto text-bg-@rout.Connected.BootstrapColor()">
<h5 class="card-title text-center my-1">@rout.Device</h5>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item py-2">@rout.Location</li>
<li class="list-group-item py-2">Connected: @rout.Connected</li>
<li class="list-group-item py-2">Temperature: @rout.GetTemperature()</li>
<li class="list-group-item py-2">RSSI: @rout.GetRSSI()</li>
<li class="list-group-item py-2">Timestamp: @rout.Timestamp.FormatDateTime()</li>
<li class="list-group-item py-2">
<a href="Home/RouterLogging?id=@rout.Id">
<i class="bi-calendar-check" style="color: white;"></i>
</a>
</li>
</ul>
</div>
</div>
}
</div>
@code
{
private List<Models.Database.Router> routersList = [];
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(firstRender)
{
_monitorHandler.DeviceChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
await UpdateTable();
}
await base.OnAfterRenderAsync(firstRender);
}
public void Dispose()
{
_monitorHandler.DeviceChanged -= async (s, e) => await InvokeAsync(() => UpdateTable());
}
private async Task UpdateTable()
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
routersList = await db.Routers.OrderBy(o => o.Device).ToListAsync();
this.StateHasChanged();
}
}

View File

@@ -0,0 +1,183 @@
@implements IDisposable
@inject IDbContextFactory<MonitorDbContext> _contextFactory
@inject MonitorHandler _monitorHandler
@inject Telegram.ITelegramBotMessageChannel _telegramBotMessageChannel
<table class="table table-hover table-responsive">
<thead>
<tr>
<th>
<DisplayName For="@(() => routersList[0].Id)" />
</th>
<th>
<DisplayName For="@(() => routersList[0].Location)" />
<a @onclick="@(() => SetSortOrder("location_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("location_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => routersList[0].Device)" />
<a @onclick="@(() => SetSortOrder("device_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("device_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => routersList[0].Temperature)" />
<a @onclick="@(() => SetSortOrder("temp_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("temp_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => routersList[0].ThisMonthRX)" />
<a @onclick="@(() => SetSortOrder("thisrx_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("thisrx_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => routersList[0].ThisMonthTX)" />
<a @onclick="@(() => SetSortOrder("thistx_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("thistx_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => routersList[0].RSSI)" />
<a @onclick="@(() => SetSortOrder("rssi_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("rssi_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => routersList[0].WanIp)" />
<a @onclick="@(() => SetSortOrder("wanip_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("wanip_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => routersList[0].FirmwareVersion)" />
<a @onclick="@(() => SetSortOrder("firmware_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("firmware_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => routersList[0].Timestamp)" />
<a @onclick="@(() => SetSortOrder("timestamp_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("timestamp_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
Timeout(sec)
<a @onclick="@(() => SetSortOrder("timeout_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("timeout_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var router in routersList)
{
<tr class="table-@router.Connected.BootstrapColor()">
<td>@router.Id</td>
<td>@router.Location</td>
<td>@router.Device</td>
<td>@router.GetTemperature()</td>
<td>@router.GetThisMonthRX()</td>
<td>@router.GetThisMonthTX()</td>
<td>@router.GetRSSI()</td>
<td>@router.WanIp</td>
<td>@router.FirmwareVersion</td>
<td>@router.Timestamp.FormatDateTime()</td>
<td>@router.MonitorDevice?.SecondsToTimeout()</td>
<td>
<a @onclick="() => DeleteRouter(router.Device)" @onclick:preventDefault href="#">
<i class="bi-trash" style="color: black;"></i>
</a>
</td>
</tr>
}
</tbody>
</table>
@code
{
private List<Models.Database.Router> routersList = [];
private string? sortOrder;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
//Debug.WriteLine($"OnAfterRenderAsync first:{firstRender}");
if (firstRender)
{
_monitorHandler.DeviceChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
await UpdateTable();
}
await base.OnAfterRenderAsync(firstRender);
}
public void Dispose()
{
_monitorHandler.DeviceChanged -= async (s, e) => await InvokeAsync(() => UpdateTable());
}
private async Task UpdateTable()
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
routersList = (await db.Routers.OrderBy(o => o.Device).ToListAsync()).AddMonitorDevice(_monitorHandler).SortTable(sortOrder);
this.StateHasChanged();
}
private async Task DeleteRouter(string device)
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
var router = db.Routers.Where(rout => rout.Device == device).FirstOrDefault();
if (router != null)
{
var logs = db.Loggings.Where(l => l.Router == router);
db.Loggings.RemoveRange(logs);
db.Routers.Remove(router);
await _telegramBotMessageChannel.Send($"🚮 <b>{router.Location} - {router.Device}</b>{Environment.NewLine} Removed from SDN monitor", default);
}
db.SaveChanges();
_monitorHandler.RemoveDevice(device);
await UpdateTable();
}
private async Task SetSortOrder(string order)
{
sortOrder = order;
await UpdateTable();
}
}

View File

@@ -0,0 +1,116 @@
@implements IDisposable
@inject IDbContextFactory<MonitorDbContext> _contextFactory
@inject MonitorHandler _monitorHandler
<div class="container">
<h2>@system.ComputerName</h2>
</div>
<div class="container">
<table class="table table-hover table-bordered">
<thead>
<tr>
<th>
<DisplayName For="@(() => system.Devices.First().BoxID)" />
<a @onclick="@(() => SetSortOrder("boxid_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("boxid_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => system.Devices.First().Name)" />
<a @onclick="@(() => SetSortOrder("name_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("name_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
@if (hasMessages)
{
<th>
<DisplayName For="@(() => system.Devices.First().Message)" />
<a @onclick="@(() => SetSortOrder("message_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("message_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
}
<th>
<DisplayName For="@(() => system.Devices.First().LastStateChange)" />
<a @onclick="@(() => SetSortOrder("changed_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("changed_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
</tr>
</thead>
<tbody>
@if (system != null)
{
@foreach (var device in system.Devices)
{
<tr class="@(device.State == true ? "table-success" : "table-danger") ">
<td>@device.BoxID</td>
<td>@device.Name</td>
@if (hasMessages)
{
<td>@device.Message</td>
}
<td>@device.LastStateChange.FormatDateTime()</td>
</tr>
}
}
</tbody>
</table>
</div>
@code
{
[Parameter]
public int? Id { get; set; }
private UCSSystem system = new UCSSystem();
private string? sortOrder;
private bool hasMessages = false;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await UpdateTable();
_monitorHandler.DeviceChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
}
await base.OnAfterRenderAsync(firstRender);
}
public void Dispose()
{
_monitorHandler.DeviceChanged -= async (s, e) => await InvokeAsync(() => UpdateTable());
}
private async Task SetSortOrder(string order)
{
sortOrder = order;
await UpdateTable();
}
private async Task UpdateTable()
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
system = await db.UCSSystems.Where(i => i.UCSSystemId == Id).Include(d => d.Devices).SingleOrDefaultAsync() ?? new UCSSystem();
system.Devices = system.Devices.SortTable(sortOrder).ToList();
hasMessages = system.Devices.Where(m => m.Message != string.Empty).Any();
this.StateHasChanged();
}
}

View File

@@ -0,0 +1,65 @@
@implements IDisposable
@inject IDbContextFactory<MonitorDbContext> _contextFactory
@inject MonitorHandler _monitorHandler
<div class="row">
@foreach (var system in ucssystemsList)
{
<div class="col mb-4">
<div class="card border-@system.BootstrapColor() rounded" style="width: 18rem;">
<div class="card-body py-1 h-auto text-bg-@system.BootstrapColor()">
<h5 class="card-title text-center my-1">@system.ComputerNameWithError()</h5>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item py-2">@system.ConfigFileName</li>
<li class="list-group-item py-2">Uptime: @system.Uptime</li>
<li class="list-group-item py-2">Last: @system.LastMessageTime.FormatDateTime()</li>
<li class="list-group-item py-2">
@if (system.Devices.Any())
{
<a href="UCSSystems/Devices?id=@system.UCSSystemId">
<i class="bi-building p-1" style="color: white;"></i>
</a>
}
<a href="UCSSystems/Logging?id=@system.UCSSystemId">
<i class="bi-calendar-check p-1" style="color: white;"></i>
</a>
<a href="UCSSystems/Errors?id=@system.UCSSystemId">
<i class="bi-bug p-1" style="color: white;"></i>
</a>
<a href="UCSSystems/Details?id=@system.UCSSystemId">
<i class="bi-info p-1" style="color: white;"></i>
</a>
</li>
</ul>
</div>
</div>
}
</div>
@code
{
private List<Models.Database.UCSSystem> ucssystemsList = [];
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(firstRender)
{
await UpdateTable();
_monitorHandler.DeviceChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
}
await base.OnAfterRenderAsync(firstRender);
}
public void Dispose()
{
_monitorHandler.DeviceChanged -= async (s, e) => await InvokeAsync(() => UpdateTable());
}
private async Task UpdateTable()
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
ucssystemsList = await db.UCSSystems.Include(d => d.Devices).OrderBy(o => o.ComputerName).ToListAsync();
this.StateHasChanged();
}
}

View File

@@ -0,0 +1,255 @@
@implements IDisposable
@inject IDbContextFactory<MonitorDbContext> _contextFactory
@inject MonitorHandler _monitorHandler
<table class="table table-hover table-responsive">
<thead>
<tr>
<th></th>
<th>
<DisplayName For="@(() => ucssystemsList[0].ComputerName)" />
<a @onclick="@(() => SetSortOrder("system_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("system_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].ConfigFileName)" />
<a @onclick="@(() => SetSortOrder("configfile_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("configfile_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].Uptime)" />
<a @onclick="@(() => SetSortOrder("uptime_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("uptime_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].SystemUptime)" />
<a @onclick="@(() => SetSortOrder("systemuptime_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("systemuptime_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].UCSVersion)" />
<a @onclick="@(() => SetSortOrder("ucsversion_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("ucsversion_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].OSCaption)" />
<a @onclick="@(() => SetSortOrder("oscaption_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("oscaption_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].OSVersion)" />
<a @onclick="@(() => SetSortOrder("osversion_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("osversion_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].DotNetVersion)" />
<a @onclick="@(() => SetSortOrder("dotnetversion_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("dotnetversion_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].AxisVersion)" />
<a @onclick="@(() => SetSortOrder("axisversion_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("axisversion_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].BoschVersion)" />
<a @onclick="@(() => SetSortOrder("boschversion_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("boschversion_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].ComputerModel)" />
<a @onclick="@(() => SetSortOrder("computermodel_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("computermodel_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].BIOSVersion)" />
<a @onclick="@(() => SetSortOrder("biosversion_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("biosversion_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].ProcessorName)" />
<a @onclick="@(() => SetSortOrder("processorname_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("processorname_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].PhysicalMemory)" />
<a @onclick="@(() => SetSortOrder("physicalmemory_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("physicalmemory_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].VideoController)" />
<a @onclick="@(() => SetSortOrder("videocontroller_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("videocontroller_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].Monitors)" />
<a @onclick="@(() => SetSortOrder("monitors_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("monitors_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].USBDisks)" />
<a @onclick="@(() => SetSortOrder("usbdisks_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("usbdisks_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th>
<DisplayName For="@(() => ucssystemsList[0].LastMessageTime)" />
<a @onclick="@(() => SetSortOrder("lastmessage_desc"))" @onclick:preventDefault href="#">
<i class="bi-sort-up"></i>
</a>
<a @onclick="@(() => SetSortOrder("lastmessage_asc"))" @onclick:preventDefault href="#">
<i class="bi-sort-down-alt"></i>
</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var system in ucssystemsList)
{
<tr class="table-@system.BootstrapColor()">
<td>
@if (system.Devices.Any())
{
<a href="UCSSystems/Devices?id=@system.UCSSystemId">
<i class="bi-building" style="color: black;"></i>
</a>
}
<a href="UCSSystems/Logging?id=@system.UCSSystemId">
<i class="bi-calendar-check" style="color: black;"></i>
</a>
<a href="UCSSystems/Errors?id=@system.UCSSystemId">
<i class="bi-bug" style="color: black;"></i>
</a>
<a href="UCSSystems/Details?id=@system.UCSSystemId">
<i class="bi-info" style="color: black;"></i>
</a>
</td>
<td>@system.ComputerName</td>
<td>@system.ConfigFileName</td>
<td>@system.Uptime</td>
<td>@system.SystemUptime</td>
<td>@system.UCSVersion</td>
<td>@system.OSCaption</td>
<td>@system.OSVersion</td>
<td>@system.DotNetVersion</td>
<td>@system.AxisVersion</td>
<td>@system.BoschVersion</td>
<td>@system.ComputerModel</td>
<td>@system.BIOSVersion</td>
<td>@system.ProcessorName</td>
<td>@system.PhysicalMemory</td>
<td>@system.VideoController</td>
<td>@system.Monitors</td>
<td>@system.USBDisks</td>
<td>@system.LastMessageTime.FormatDateTime()</td>
<td>
<a href="UCSSystems/Delete?id=@system.UCSSystemId">
<i class="bi-trash" style="color: black;"></i>
</a>
</td>
</tr>
}
</tbody>
</table>
@code
{
private List<Models.Database.UCSSystem> ucssystemsList = [];
private string? sortOrder;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await UpdateTable();
_monitorHandler.DeviceChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
}
await base.OnAfterRenderAsync(firstRender);
}
public void Dispose()
{
_monitorHandler.DeviceChanged -= async (s, e) => await InvokeAsync(() => UpdateTable());
}
private async Task UpdateTable()
{
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
ucssystemsList = (await db.UCSSystems.Include(d => d.Devices).ToListAsync()).SortTable(sortOrder);
this.StateHasChanged();
}
private async Task SetSortOrder(string order)
{
sortOrder = order;
await UpdateTable();
}
}

View File

@@ -1,33 +1,74 @@
using UCS_Status_Monitor.LDAP;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading.Tasks;
using UCS_Status_Monitor.LDAP;
using UCS_Status_Monitor.Models;
using Microsoft.Extensions.Configuration;
using System.Threading;
namespace UCS_Status_Monitor.Controllers
{
public class AccountController : Controller
public class AccountController(LDAPService ldapService) : Controller
{
private readonly LDAPService _ldapService;
private readonly string? _cookieName;
private readonly LDAPService _ldapService = ldapService;
public AccountController(LDAPService ldapService, IConfiguration configuration)
private async Task SignIn(string username, bool persistent)
{
_ldapService = ldapService;
_cookieName = configuration.GetValue<string>("CookieName", "Default");
//Debug.WriteLine($"username = {username}");
//Debug.WriteLine(_ldapService.GetUserFullName(username));
//Debug.WriteLine($"fullname = {_ldapService.GetUserFullName(username)}");
List<Claim> claims =
[
new(ClaimTypes.Name, username),
new("Username", _ldapService.GetUserFullName(username))
];
ClaimsIdentity claimsIdentity = new(claims, CookieAuthenticationDefaults.AuthenticationScheme);
AuthenticationProperties authProperties = new()
{
IsPersistent = persistent,
AllowRefresh = true,
IssuedUtc = DateTime.UtcNow,
ExpiresUtc = DateTime.UtcNow.AddDays(30),
};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
}
// GET: /Account/Login
[HttpGet]
[AllowAnonymous]
public ActionResult Login()
public async Task<ActionResult> Login()
{
//WindowsIdentity identity = WindowsIdentity.GetAnonymous();
//WindowsIdentity identity = WindowsIdentity.GetCurrent();
//Debug.WriteLine($"Authenticated User: {identity.Name}");
//Debug.WriteLine($"Authenticated SID: {identity.User?.Value}");
//if (identity.IsAuthenticated)
//{
// Debug.WriteLine("IsAuthenticated");
// string samAccountName = identity.Name.Split('\\')[1];
// Debug.WriteLine(samAccountName);
// //string username = _ldapService.GetUserFromSID(identity.User.AccountDomainSid.Value);
// //Debug.WriteLine(username);
// if (_ldapService.ValidateUserGroup(samAccountName))
// {
// Debug.WriteLine("ValidateUserGroup = true");
// //await SignIn(samAccountName, true);
// //return Redirect("/");
// }
//}
return View(new LoginViewModel());
}
@@ -46,14 +87,7 @@ namespace UCS_Status_Monitor.Controllers
if (_ldapService.ValidateUser(model.UserName, model.Password) && _ldapService.ValidateUserGroup(model.UserName))
{
var claims = new List<Claim> { new(ClaimTypes.Name, model.UserName), new("Username", _ldapService.GetUserFullName(model.UserName)) };
var claimsIdentity = new ClaimsIdentity(claims, _cookieName);
var authProperties = new AuthenticationProperties
{
IsPersistent = model.RememberMe,
AllowRefresh = true
};
await HttpContext.SignInAsync(_cookieName, new ClaimsPrincipal(claimsIdentity), authProperties);
await SignIn(model.UserName, model.RememberMe);
return Redirect("/");
}
else
@@ -66,11 +100,16 @@ namespace UCS_Status_Monitor.Controllers
return View(model);
}
[HttpGet]
[Authorize]
public new async Task<IActionResult> SignOut()
{
//Debug.WriteLine($"SignOut called - {_signInManager.Context.User.Identity.Name}");
await HttpContext.SignOutAsync(_cookieName);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Redirect("/");
}
}

View File

@@ -1,501 +1,29 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Extensions;
using UCS_Status_Monitor.Models;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.Telegram;
namespace UCS_Status_Monitor.Controllers
{
public class HomeController : Controller
public class HomeController(IDbContextFactory<MonitorDbContext> contextFactory, ITelegramBotService telegramBot) : Controller
{
private readonly ITelegramBotService _telegramBot;
private readonly IDbContextFactory<MonitorDbContext> _contextFactory;
private readonly MonitorHandler _monitorHandler;
public HomeController(ITelegramBotService telegramBot, IDbContextFactory<MonitorDbContext> contextFactory, MonitorHandler monitorHandler)
{
_telegramBot = telegramBot;
_contextFactory = contextFactory;
_monitorHandler = monitorHandler;
}
private readonly IDbContextFactory<MonitorDbContext> _contextFactory = contextFactory;
private readonly ITelegramBotService _telegramBot = telegramBot;
[HttpGet]
[Authorize]
public ActionResult Index()
public IActionResult Index()
{
return View();
}
[HttpGet]
[Authorize]
public async Task<JsonResult> GetIndexTable(CancellationToken token)
{
using var db = await _contextFactory.CreateDbContextAsync(token);
List<HomeTableModel> systems = await db.UCSSystems
.Include(d => d.Devices)
.OrderByDescending(o => o.ComputerName)
.Select(a => new HomeTableModel
{
ComputerName = a.ComputerNameWithError(),
ConfigFileName = a.ConfigFileName,
Uptime = a.Uptime,
LastMessageTime = a.LastMessageTime.FormatDateTime(),
TableColor = a.TableColor(),
}).ToListAsync(token);
return Json(systems);
}
[HttpGet]
[Authorize]
public IActionResult Overview()
{
return View(new UCSSystem());
}
[HttpGet]
[Authorize]
public async Task<JsonResult> GetOverviewTable(string sortOrder, CancellationToken token)
{
using var db = await _contextFactory.CreateDbContextAsync(token);
IQueryable<UCSSystem> systems = db.UCSSystems.Include(d => d.Devices).OrderByDescending(o => o.ComputerName);
if (sortOrder != null)
{
switch (sortOrder)
{
case "system_asc":
systems = systems.OrderBy(s => s.ComputerName);
break;
case "system_desc":
systems = systems.OrderByDescending(s => s.ComputerName);
break;
case "configfile_asc":
systems = systems.OrderBy(s => s.ConfigFileName);
break;
case "configfile_desc":
systems = systems.OrderByDescending(s => s.ConfigFileName);
break;
case "uptime_asc":
systems = systems.OrderBy(s => s.Uptime);
break;
case "uptime_desc":
systems = systems.OrderByDescending(s => s.Uptime);
break;
case "systemuptime_asc":
systems = systems.OrderBy(s => s.SystemUptime);
break;
case "systemuptime_desc":
systems = systems.OrderByDescending(s => s.SystemUptime);
break;
case "ucsversion_asc":
systems = systems.OrderBy(s => s.UCSVersion);
break;
case "ucsversion_desc":
systems = systems.OrderByDescending(s => s.UCSVersion);
break;
case "oscaption_asc":
systems = systems.OrderBy(s => s.OSCaption);
break;
case "oscaption_desc":
systems = systems.OrderByDescending(s => s.OSCaption);
break;
case "osversion_asc":
systems = systems.OrderBy(s => s.OSVersion);
break;
case "osversion_desc":
systems = systems.OrderByDescending(s => s.OSVersion);
break;
case "dotnetversion_asc":
systems = systems.OrderBy(s => s.DotNetVersion);
break;
case "dotnetversion_desc":
systems = systems.OrderByDescending(s => s.DotNetVersion);
break;
case "axisversion_asc":
systems = systems.OrderBy(s => s.AxisVersion);
break;
case "axisversion_desc":
systems = systems.OrderByDescending(s => s.AxisVersion);
break;
case "boschversion_asc":
systems = systems.OrderBy(s => s.BoschVersion);
break;
case "boschversion_desc":
systems = systems.OrderByDescending(s => s.BoschVersion);
break;
case "computermodel_asc":
systems = systems.OrderBy(s => s.ComputerModel);
break;
case "computermodel_desc":
systems = systems.OrderByDescending(s => s.ComputerModel);
break;
case "biosversion_asc":
systems = systems.OrderBy(s => s.BIOSVersion);
break;
case "biosversion_desc":
systems = systems.OrderByDescending(s => s.BIOSVersion);
break;
case "processorname_asc":
systems = systems.OrderBy(s => s.ProcessorName);
break;
case "processorname_desc":
systems = systems.OrderByDescending(s => s.ProcessorName);
break;
case "physicalmemory_asc":
systems = systems.OrderBy(s => s.PhysicalMemory);
break;
case "physicalmemory_desc":
systems = systems.OrderByDescending(s => s.PhysicalMemory);
break;
case "videocontroller_asc":
systems = systems.OrderBy(s => s.VideoController);
break;
case "videocontroller_desc":
systems = systems.OrderByDescending(s => s.VideoController);
break;
case "monitors_asc":
systems = systems.OrderBy(s => s.Monitors);
break;
case "monitors_desc":
systems = systems.OrderByDescending(s => s.Monitors);
break;
case "usbdisks_desc":
systems = systems.OrderBy(s => s.USBDisks);
break;
case "usbdisks_asc":
systems = systems.OrderByDescending(s => s.USBDisks);
break;
case "lastmessage_asc":
systems = systems.OrderBy(s => s.LastMessageTime);
break;
case "lastmessage_desc":
systems = systems.OrderByDescending(s => s.LastMessageTime);
break;
default:
systems = systems.OrderBy(s => s.ComputerName);
break;
}
}
else
{
sortOrder = "default";
}
List<OverviewTableModel> systemsList = await systems
.Select(a => new OverviewTableModel
{
UCSSystemId = a.UCSSystemId,
ComputerName = a.ComputerNameWithError(),
LastMessageTime = a.LastMessageTime.FormatDateTime(),
Uptime = a.Uptime,
SystemUptime = a.SystemUptime,
ComputerModel = a.ComputerModel,
ProcessorName = a.ProcessorName,
PhysicalMemory = a.PhysicalMemory,
VideoController = a.VideoController,
Monitors = a.Monitors,
ConfigFileName = a.ConfigFileName,
UCSVersion = a.UCSVersion,
AxisVersion = a.AxisVersion,
BoschVersion = a.BoschVersion,
OSVersion = a.OSVersion,
OSCaption = a.OSCaption,
DotNetVersion = a.DotNetVersion,
BiosVersion = a.BIOSVersion,
USBDisks = a.USBDisks,
TableColor = a.TableColor(),
}).ToListAsync(token);
Response.Cookies.Append("OverviewSortOrder", sortOrder);
return Json(systemsList);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> SystemDetails(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id");
}
using var db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.Where(i => i.UCSSystemId == id)
.Include(d => d.Devices)
.Include(d => d.Errors.OrderByDescending(o => o.TimeGenerated))
.SingleOrDefaultAsync(token);
if (system == null)
{
return BadRequest("Not found in the database");
}
return View(system);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> OverviewDevice(int? id, string sortOrder, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id to display");
}
using var db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.Where(i => i.UCSSystemId == id)
.Include(d => d.Devices)
.SingleOrDefaultAsync(token);
if (system == null)
{
return BadRequest("Not found in the database");
}
if (sortOrder != null)
{
switch (sortOrder)
{
case "boxid_asc":
system.Devices = system.Devices.OrderBy(s => s.BoxID).ToList();
break;
case "boxid_desc":
system.Devices = system.Devices.OrderByDescending(s => s.BoxID).ToList();
break;
case "name_asc":
system.Devices = system.Devices.OrderBy(s => s.Name).ToList();
break;
case "name_desc":
system.Devices = system.Devices.OrderByDescending(s => s.Name).ToList();
break;
case "changed_asc":
system.Devices = system.Devices.OrderBy(s => s.LastStateChange).ToList();
break;
case "changed_desc":
system.Devices = system.Devices.OrderByDescending(s => s.LastStateChange).ToList();
break;
default:
system.Devices = system.Devices.OrderBy(s => s.Id).ToList();
break;
}
}
else
{
sortOrder = "default";
}
Response.Cookies.Append("OverviewDeviceSortOrder", sortOrder);
return View(system);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> Delete(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id to delete");
}
using var db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.Where(i => i.UCSSystemId == id)
.Include(d => d.Devices)
.Include(d => d.Loggings)
.Include(d => d.Errors)
.SingleOrDefaultAsync(token);
if (system == null)
{
return BadRequest("Not found in the database");
}
if (system.Devices.Count != 0)
db.UCSDevices.RemoveRange(system.Devices);
if (system.Loggings.Count != 0)
db.Loggings.RemoveRange(system.Loggings);
if (system.Errors.Count != 0)
db.Errors.RemoveRange(system.Errors);
db.UCSSystems.Remove(system);
await db.SaveChangesAsync(token);
await _telegramBot.Send($"🚮 <b>{system.ComputerName} - {system.ConfigFileName}</b>{Environment.NewLine} Removed from UCS monitor", token);
return RedirectToAction("Overview", "Home");
}
[HttpGet]
[Authorize]
public async Task<IActionResult> Logging(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id");
}
using var db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.FindAsync([id], token);
if (system == null)
{
return BadRequest("Not found in the database");
}
LoggingViewModel loggingView = new()
{
UCSSystem = system,
Loggings = await db.Loggings.Where(i => i.UCSSystem.UCSSystemId == id).OrderByDescending(d => d.Date).Take(10).ToListAsync(token)
};
if (loggingView.Loggings.Any())
{
//add current data
loggingView.LoggingChart.Data.Add(Convert.ToInt32(loggingView.Loggings.First().State));
loggingView.LoggingChart.Labels.Add(DateTime.Now);
//last 10 logs
foreach (var log in loggingView.Loggings)
{
loggingView.LoggingChart.Data.Add(Convert.ToInt32(log.State));
loggingView.LoggingChart.Labels.Add(log.Date);
}
}
return View(loggingView);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> LogErrors(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id");
}
using var db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.Where(i => i.UCSSystemId == id)
.Include(d => d.Errors.OrderByDescending(o => o.TimeGenerated))
.SingleOrDefaultAsync(token);
if (system == null)
{
return BadRequest("Not found in the database");
}
return View(system);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> Sensors(string sortOrder, CancellationToken token)
{
using var db = await _contextFactory.CreateDbContextAsync(token);
IQueryable<Sensor> sensors = db.Sensors.OrderByDescending(x => x.Date).Take(25);
if (sortOrder != null)
{
switch (sortOrder)
{
case "date_asc":
sensors = sensors.OrderBy(s => s.Date);
break;
case "date_desc":
sensors = sensors.OrderByDescending(s => s.Date);
break;
case "computername_asc":
sensors = sensors.OrderBy(s => s.ComputerName);
break;
case "computername_desc":
sensors = sensors.OrderByDescending(s => s.ComputerName);
break;
case "configfile_asc":
sensors = sensors.OrderBy(s => s.Configfile);
break;
case "configfile_desc":
sensors = sensors.OrderByDescending(s => s.Configfile);
break;
case "ucsid_asc":
sensors = sensors.OrderBy(s => s.UCSId);
break;
case "ucsid_desc":
sensors = sensors.OrderByDescending(s => s.UCSId);
break;
case "txstring_asc":
sensors = sensors.OrderBy(s => s.TxString);
break;
case "txstring_desc":
sensors = sensors.OrderByDescending(s => s.TxString);
break;
case "txdata_asc":
sensors = sensors.OrderBy(s => s.TxData);
break;
case "txdata_desc":
sensors = sensors.OrderByDescending(s => s.TxData);
break;
case "count_asc":
sensors = sensors.OrderBy(s => s.Count);
break;
case "count_desc":
sensors = sensors.OrderByDescending(s => s.Count);
break;
default:
sensors = sensors.OrderByDescending(s => s.Date);
break;
}
}
else
{
sortOrder = "default";
}
Response.Cookies.Append("SensorsSortOrder", sortOrder);
return View(await sensors.ToListAsync(token));
}
[HttpGet]
[Authorize]
public ActionResult Cameras()
@@ -505,27 +33,42 @@ namespace UCS_Status_Monitor.Controllers
[HttpGet]
[Authorize]
public async Task<JsonResult> GetCamerasTable(CancellationToken token)
public IActionResult CamerasOverview()
{
using var db = await _contextFactory.CreateDbContextAsync(token);
return View();
}
List<CameraTableModel> camsList = await db.AxisCams
.OrderByDescending(o => o.Device)
.Select(a => new CameraTableModel
[HttpGet]
[Authorize]
public async Task<IActionResult> CameraLogging(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id");
}
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync(token);
AxisCam? cam = await db.AxisCams.Where(i => i.Id == id).Include(l => l.Loggings.OrderByDescending(d => d.Date)).SingleOrDefaultAsync(token);
if (cam == null)
{
return BadRequest("Not found in the database");
}
LoggingViewModel loggingView = new()
{
AxisCam = cam,
Loggings = cam.Loggings.OrderByDescending(d => d.Date).Take(10)
};
if (loggingView.Loggings.Any())
{
//last 10 logs
foreach (var log in loggingView.Loggings.Reverse())
{
//LastMessageTime = Helpers.Html.FormatDateTime(a.LastMessageTime),
TableColor = a.TableColor(),
Device = a.Device,
Location = a.Location,
SerialNumber = a.SerialNumber,
Timestamp = a.Timestamp.FormatDateTime(),
Connected = a.Connected,
Description = a.Description,
SystemReady = a.SystemReady,
Temperature = a.Temperature,
}).ToListAsync(token);
return Json(camsList);
loggingView.LoggingChart.Data.Add(Convert.ToInt32(log.State));
loggingView.LoggingChart.Labels.Add(log.Date);
}
}
return View(loggingView);
}
[HttpGet]
@@ -537,117 +80,49 @@ namespace UCS_Status_Monitor.Controllers
[HttpGet]
[Authorize]
public async Task<JsonResult> GetRoutersTable(CancellationToken token)
public async Task<IActionResult> RouterLogging(int? id, CancellationToken token)
{
using var db = await _contextFactory.CreateDbContextAsync(token);
List<RouterTableModel> camsList = await db.Routers
.OrderByDescending(o => o.Device)
.Select(a => new RouterTableModel
{
TableColor = a.TableColor(),
Device = a.Device,
Location = a.Location,
Timestamp = a.Timestamp.FormatDateTime(),
Connected = a.Connected,
Temperature = a.GetTemperature(),
}).ToListAsync(token);
return Json(camsList);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> RoutersOverview(CancellationToken token)
{
using var db = await _contextFactory.CreateDbContextAsync(token);
List<Router> routersList = await db.Routers
.GroupBy(rout => rout.Device)
.Select(x => x.OrderBy(t => t.Timestamp).Last())
.ToListAsync(token);
return View(routersList);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> RouterLog(string device, CancellationToken token)
{
if (string.IsNullOrEmpty(device))
if (id == null)
{
return BadRequest("No id");
}
using var db = await _contextFactory.CreateDbContextAsync(token);
//RouterLogViewModel routerLog = new();
//var routerLogtasks = new Task[]
// {
// Task.Run(async () => routerLog.Router = await dbContext.Routers.Where(x => x.Device == device).OrderBy(t => t.Timestamp).LastAsync()),
// Task.Run(async () => routerLog.Loggings = await dbContext.Routers.Where(x => x.Device == device).Where(d => d.Timestamp >= DateTime.Now.AddDays(-30)).OrderBy(t => t.Timestamp).ToListAsync()),
// };
//await Task.WhenAll(routerLogtasks);
RouterLogViewModel routerLog = new()
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync(token);
Router? router = await db.Routers.Where(i => i.Id == id).Include(l => l.Loggings).SingleOrDefaultAsync(token);
if (router == null)
{
Router = await db.Routers.Where(x => x.Device == device).OrderBy(t => t.Timestamp).LastAsync(token),
Loggings = await db.Routers.Where(x => x.Device == device).Where(d => d.Timestamp >= DateTime.Now.AddDays(-30)).OrderBy(t => t.Timestamp).ToListAsync(token)
return BadRequest("Not found in the database");
}
LoggingViewModel loggingView = new()
{
Router = router,
Loggings = router.Loggings.OrderByDescending(d => d.Date).Take(10)
};
if (routerLog.Loggings.Any())
if (loggingView.Loggings.Any())
{
foreach (var log in routerLog.Loggings)
//last 10 logs
foreach (var log in loggingView.Loggings.Reverse())
{
routerLog.RSSIChart.Data.Add(log.RSSI);
routerLog.RSSIChart.Labels.Add(log.Timestamp);
routerLog.TemperatureChart.Data.Add(Convert.ToInt32(log.Temperature));
routerLog.TemperatureChart.Labels.Add(log.Timestamp);
//routerLog.ThisMontRXChart.Data.Add(Convert.ToInt32(log.ThisMonthRX / 1000000));
routerLog.ThisMontRXChart.Data.Add(Convert.ToInt32(log.ThisMonthRX));
routerLog.ThisMontRXChart.Labels.Add(log.Timestamp);
//routerLog.ThisMontTXChart.Data.Add(Convert.ToInt32(log.ThisMonthTX / 1000000));
routerLog.ThisMontTXChart.Data.Add(Convert.ToInt32(log.ThisMonthTX));
routerLog.ThisMontTXChart.Labels.Add(log.Timestamp);
loggingView.LoggingChart.Data.Add(Convert.ToInt32(log.State));
loggingView.LoggingChart.Labels.Add(log.Date);
}
}
return View(routerLog);
return View(loggingView);
}
[HttpGet]
[Authorize]
public IActionResult ServerStatus()
{
return View(new ServerStatusModel());
}
[HttpGet]
[Authorize]
public ActionResult Prtgs()
public IActionResult RoutersOverview()
{
return View();
}
[HttpGet]
[Authorize]
public async Task<JsonResult> GetPrtgsTable(CancellationToken token)
public IActionResult ServerStatus()
{
var prtglist = _monitorHandler.GetPRTGDevices()
.Select(a => new PrtgTableModel
{
TableColor = a.TableColor(),
DeviceName = a.DeviceName,
Timestamp = a.LastData.FormatDateTime()
}).ToList();
return Json(prtglist);
return View(new ServerStatusModel(_telegramBot.TelegrambotInfoModel));
}
}
}

View File

@@ -1,69 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Threading;
using UCS_Status_Monitor.Sensors;
namespace UCS_Status_Monitor.Controllers
{
[Route("[controller]")]
[ApiController]
public class SensorController : Controller
{
//http://localhost:2115/sensor
//http://192.168.0.141:12345/sensor
private readonly ILogger<SensorController> _logger;
private readonly ISensorService _sensorHandler;
public SensorController(ILogger<SensorController> logger, ISensorService sensorService)
{
_logger = logger;
_sensorHandler = sensorService;
}
[HttpGet]
public JsonResult Get()
{
return new JsonResult("Kifflom");
}
//{"Date":"2021-11-18T11:43:55.3638576+01:00",
//"ComputerName":"S01-PCD04",
//"Configfile":"Remote ID List Test - DEBUG BUILD",
//"UCSId":"C1",
//"TxString":"Rust",
//"TxData":"K.03 - geen lekkage",
//"Count":3}
[HttpPost]
public JsonResult Post(SensorPacket sensor, CancellationToken token)
{
//Stopwatch stopWatch = new();
//stopWatch.Start();
if (!ModelState.IsValid)
{
_logger.LogInformation("sensor Modelstate is invalid");
return new JsonResult("Failed");
}
if (sensor == null)
{
_logger.LogInformation("sensor == null");
return new JsonResult("Failed");
}
//Debug.WriteLine($"Sensor Post - {sensor.UCSId} - {sensor.TxData} - {sensor.TxString}");
//_sensorService.EnqueuePacket(sensor);
_sensorHandler.ProcessPacket(sensor, token);
//stopWatch.Stop();
//TimeSpan ts = stopWatch.Elapsed;
//Debug.WriteLine($"Sensor Post Time sec={ts.TotalSeconds}");
return new JsonResult("OK");
}
}
}

View File

@@ -1,69 +1,67 @@
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Telemetry;
using System.Threading;
using UCS_Status_Monitor.Monitor;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using UCS_Status_Monitor.Telegram;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Log;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.Telemetry;
namespace UCS_Status_Monitor.Controllers
{
[Route("[controller]")]
[ApiController]
public class TelemetryController : ControllerBase
public class TelemetryController(
//IServiceProvider serviceProvider,
ILogger<TelemetryController> logger,
MonitorHandler monitorHandler,
IDbContextFactory<MonitorDbContext> dbContextFactory) : ControllerBase
{
//http://localhost:2115/telemetry
private readonly ILogger<TelemetryController> _logger;
private readonly MonitorHandler _monitorHandler;
private readonly IDbContextFactory<MonitorDbContext> _contextFactory;
private readonly ITelegramBotService _telegramBot;
private readonly IConfiguration _configuration;
public TelemetryController(ILogger<TelemetryController> logger, IConfiguration configuration, MonitorHandler monitorHandler, IDbContextFactory<MonitorDbContext> dbContextFactory, ITelegramBotService telegramBot)
{
_logger = logger;
_configuration = configuration;
_monitorHandler = monitorHandler;
_contextFactory = dbContextFactory;
_telegramBot = telegramBot;
}
//private readonly IServiceProvider _serviceProvider = serviceProvider;
private readonly ILogger<TelemetryController> _logger = logger;
private readonly MonitorHandler _monitorHandler = monitorHandler;
private readonly IDbContextFactory<MonitorDbContext> _contextFactory = dbContextFactory;
[HttpGet]
[AllowAnonymous]
public JsonResult Get()
{
return new JsonResult("Kifflom");
}
[HttpPost]
[AllowAnonymous]
public async Task<JsonResult> Post(TelemetryPacket telemetry, CancellationToken token)
{
if (!ModelState.IsValid)
{
_logger.LogInformation("Modelstate is invalid");
Logger.LogInformation(_logger, "Modelstate is invalid");
return new JsonResult("Failed");
}
if (telemetry == null)
{
_logger.LogInformation("telemetry == null");
Logger.LogInformation(_logger, "telemetry == null");
return new JsonResult("Failed");
}
if (telemetry.ComputerName == null)
{
Logger.LogInformation(_logger, "telemetry.ComputerName == null");
return new JsonResult("Failed");
}
IUCSSystemMonitorDevice ucsDevice = _monitorHandler.GetDevice<IUCSSystemMonitorDevice>(telemetry.ComputerName);
if (!_monitorHandler.TryGetDevice(telemetry.ComputerName, out IMonitorObject ucsDevice))
{
//Debug.WriteLine($"{telemetry.ComputerName} Not found in list");
ucsDevice = new UCSSystemMonitorDevice(_configuration.GetSection("MonitorWorker").GetValue<int>("UCSTimeOutMinutes"), _contextFactory, _telegramBot);
_monitorHandler.AddDevice(telemetry.ComputerName, ucsDevice);
}
await ucsDevice.Update(telemetry, token);
await ucsDevice.SetConnectionState(true, token);
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync(token);
await ucsDevice.Update(telemetry, db, token);
await ucsDevice.SetConnectionState(true, db, token);
await db.SaveChangesAsync(token);
((IBaseMonitorDevice)ucsDevice).DeviceChangedEvent();
return new JsonResult("OK");
}

View File

@@ -0,0 +1,159 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Models;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.Telegram;
namespace UCS_Status_Monitor.Controllers
{
public class UCSSystemsController(ITelegramBotMessageChannel telegramBot, IDbContextFactory<MonitorDbContext> contextFactory) : Controller
{
private readonly ITelegramBotMessageChannel _telegramBot = telegramBot;
private readonly IDbContextFactory<MonitorDbContext> _contextFactory = contextFactory;
[HttpGet]
[Authorize]
public IActionResult Grid()
{
return View();
}
[HttpGet]
[Authorize]
public IActionResult List()
{
return View();
}
[HttpGet]
[Authorize]
public async Task<IActionResult> Details(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id");
}
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.Where(i => i.UCSSystemId == id)
.Include(d => d.Devices)
.Include(d => d.Errors.OrderByDescending(o => o.TimeGenerated))
.SingleOrDefaultAsync(token);
if (system == null)
{
return BadRequest("Not found in the database");
}
return View(system);
}
[HttpGet]
[Authorize]
public IActionResult Devices(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id to display");
}
return View(id);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> Delete(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id to delete");
}
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.Where(i => i.UCSSystemId == id)
.Include(d => d.Devices)
.Include(d => d.Loggings)
.Include(d => d.Errors)
.SingleOrDefaultAsync(token);
if (system == null)
{
return BadRequest("Not found in the database");
}
if (system.Devices.Count != 0)
db.UCSDevices.RemoveRange(system.Devices);
if (system.Loggings.Count != 0)
db.Loggings.RemoveRange(system.Loggings);
if (system.Errors.Count != 0)
db.Errors.RemoveRange(system.Errors);
db.UCSSystems.Remove(system);
await db.SaveChangesAsync(token);
await _telegramBot.Send($"🚮 <b>{system.ComputerName} - {system.ConfigFileName}</b>{Environment.NewLine} Removed from SDN monitor", token);
return RedirectToAction("Overview", "Home");
}
[HttpGet]
[Authorize]
public async Task<IActionResult> Logging(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id");
}
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.Where(i => i.UCSSystemId == id).Include(l => l.Loggings).SingleOrDefaultAsync(token);
if (system == null)
{
return BadRequest("Not found in the database");
}
LoggingViewModel loggingView = new()
{
UCSSystem = system,
Loggings = system.Loggings.OrderByDescending(d => d.Date).Take(10)
};
if (loggingView.Loggings.Any())
{
//last 10 logs
foreach (var log in loggingView.Loggings.Reverse())
{
loggingView.LoggingChart.Data.Add(Convert.ToInt32(log.State));
loggingView.LoggingChart.Labels.Add(log.Date);
}
}
return View(loggingView);
}
[HttpGet]
[Authorize]
public async Task<IActionResult> Errors(int? id, CancellationToken token)
{
if (id == null)
{
return BadRequest("No id");
}
using MonitorDbContext db = await _contextFactory.CreateDbContextAsync(token);
UCSSystem? system = await db.UCSSystems.Where(i => i.UCSSystemId == id)
.Include(d => d.Errors.OrderByDescending(o => o.TimeGenerated))
.SingleOrDefaultAsync(token);
if (system == null)
{
return BadRequest("Not found in the database");
}
return View(system);
}
}
}

View File

@@ -1,41 +1,42 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Telegram.Bot.Types;
using UCS_Status_Monitor.Telegram;
//using Microsoft.AspNetCore.Mvc;
//using System.IO;
//using System.Text;
//using System.Text.Json;
//using System.Threading;
//using System.Threading.Tasks;
//using Telegram.Bot.Types;
//using UCS_Status_Monitor.Telegram;
namespace UCS_Status_Monitor.Controllers
{
public class WebhookController : ControllerBase
{
private readonly ITelegramBotService _telegramBot;
//namespace UCS_Status_Monitor.Controllers
//{
// public class WebhookController : ControllerBase
// {
// private readonly ITelegramBotService _telegramBot;
public WebhookController(ITelegramBotService telegramBot)
{
_telegramBot = telegramBot;
}
// public WebhookController(ITelegramBotService telegramBot)
// {
// _telegramBot = telegramBot;
// }
[HttpPost]
public async Task<IActionResult> Post(CancellationToken token)
{
using (StreamReader reader = new(Request.Body, Encoding.UTF8))
{
//newtonsoft json
string json = await reader.ReadToEndAsync(token);
Update update = JsonConvert.DeserializeObject<Update>(json);
// [HttpPost]
// public async Task<IActionResult> Post(CancellationToken token)
// {
// using (StreamReader reader = new(Request.Body, Encoding.UTF8))
// {
// //newtonsoft json
// string json = await reader.ReadToEndAsync(token);
// //Update update = JsonConvert.DeserializeObject<Update>(json);
// Update? update = JsonSerializer.Deserialize<Update>(json);
//system.text.json
//var data = System.Text.Json.JsonSerializer.Deserialize<Update>(json);
//Debug.WriteLine($"Webhook post type={update.Type} message={update.Message}");
await _telegramBot.HandleUpdateAsync(update, token);
}
return Ok();
}
}
}
// //system.text.json
// //var data = System.Text.Json.JsonSerializer.Deserialize<Update>(json);
// //Debug.WriteLine($"Webhook post type={update.Type} message={update.Message}");
// if (update != null)
// {
// await _telegramBot.HandleUpdateAsync(update, token);
// }
// }
// return Ok();
// }
// }
//}

View File

@@ -1,97 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using System.Threading;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.Telegram;
using UCS_Status_Monitor.Telemetry;
using System.Diagnostics;
namespace UCS_Status_Monitor.Controllers
{
public class WsenController : ControllerBase
{
//http://localhost:2115/wsen
private readonly ILogger<TelemetryController> _logger;
private readonly MonitorHandler _monitorHandler;
private readonly IDbContextFactory<MonitorDbContext> _contextFactory;
private readonly ITelegramBotService _telegramBot;
private readonly IConfiguration _configuration;
public WsenController(ILogger<TelemetryController> logger, IConfiguration configuration, MonitorHandler monitorHandler, IDbContextFactory<MonitorDbContext> dbContextFactory, ITelegramBotService telegramBot)
{
_logger = logger;
_configuration = configuration;
_monitorHandler = monitorHandler;
_contextFactory = dbContextFactory;
_telegramBot = telegramBot;
}
//GET /CAM0012?content=%3Cprtg%3E%3Cresult%3E%3Cchannel%3ETamper%3C%2Fchannel%3E%3Cvalue%3E0%3C%2Fvalue%3E%3C%2Fresult%3E%3C%2Fprtg%3E HTTP/1.1
//Host: prtg.sdnsupport.nl:5051
//Accept: */*
//GET /CAM0013?content=%3Cprtg%3E%3Cresult%3E%3Cchannel%3EStorage%3C%2Fchannel%3E%3Cvalue%3E1%3C%2Fvalue%3E%3C%2Fresult%3E%3C%2Fprtg%3E HTTP/1.1
//Host: prtg.sdnsupport.nl:5051
//Accept: */*
//GET /B05WSEN01?content=<prtg><result><channel>Breekruit</channel><value>0</value></result></prtg> HTTP/1.1
//Host:prtg.sdnsupport.nl
//Connection:close
[HttpGet]
public async Task<JsonResult> Get(string devid, string content, CancellationToken token)
{
Debug.WriteLine($"WSEN get {devid}");
Debug.WriteLine($"Content {content}");
if (!_monitorHandler.TryGetDevice(devid, out IMonitorObject prtgDevice))
{
//Debug.WriteLine($"{telemetry.ComputerName} Not found in list");
prtgDevice = new PRTGMonitorDevice(_configuration.GetSection("MonitorWorker").GetValue<int>("PRTGTimeOutMinutes"), _contextFactory, _telegramBot);
_monitorHandler.AddDevice(devid, prtgDevice);
}
await prtgDevice.Update(devid, token);
await prtgDevice.SetConnectionState(true, token);
return new JsonResult("OK");
}
//[HttpPost]
//public async Task<JsonResult> Post(TelemetryPacket telemetry, CancellationToken token)
//{
// //if (!ModelState.IsValid)
// //{
// // _logger.LogInformation("Modelstate is invalid");
// // return new JsonResult("Failed");
// //}
// //if (telemetry == null)
// //{
// // _logger.LogInformation("telemetry == null");
// // return new JsonResult("Failed");
// //}
// ////await _telemetryWorker.EnqueuePacket(telemetry, token);
// //if (!_monitorHandler.TryGetDevice(telemetry.ComputerName, out IMonitorObject ucsDevice))
// //{
// // //Debug.WriteLine($"{telemetry.ComputerName} Not found in list");
// // ucsDevice = new UCSSystemMonitorDevice(_configuration.GetSection("MonitorWorker").GetValue<int>("UCSTimeOutMinutes"), _contextFactory, _telegramBot);
// // _monitorHandler.AddDevice(telemetry.ComputerName, ucsDevice);
// //}
// //await ucsDevice.Update(telemetry, token);
// //await ucsDevice.SetConnectionState(true, token);
// return new JsonResult("OK");
//}
}
}

View File

@@ -39,9 +39,9 @@ namespace UCS_Status_Monitor.Database
{
//Debug.WriteLine("OfflineAllDevices");
dbContext.UCSSystems.ExecuteUpdate(s => s.SetProperty(e => e.ConnectionState, false));
dbContext.AxisCams.ExecuteUpdate(s => s.SetProperty(e => e.Connected, false));
dbContext.Routers.ExecuteUpdate(s => s.SetProperty(e => e.Connected, false));
dbContext?.UCSSystems.ExecuteUpdate(s => s.SetProperty(e => e.ConnectionState, false));
dbContext?.AxisCams.ExecuteUpdate(s => s.SetProperty(e => e.Connected, false));
dbContext?.Routers.ExecuteUpdate(s => s.SetProperty(e => e.Connected, false));
}
}
}

View File

@@ -1,10 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using UCS_Status_Monitor.Models.Database;
namespace UCS_Status_Monitor.Database
@@ -24,6 +20,8 @@ namespace UCS_Status_Monitor.Database
public DbSet<UCSDevice> UCSDevices { get; set; }
public DbSet<Logging> Loggings { get; set; }
public DbSet<EventLogError> Errors { get; set; }
[Obsolete("Old UCS sensors")]
public DbSet<Sensor> Sensors { get; set; }
public DbSet<Router> Routers { get; set; }
public DbSet<AxisCam> AxisCams { get; set; }

View File

@@ -1,16 +1,16 @@
using UCS_Status_Monitor.Models.Database;
//using UCS_Status_Monitor.Models.Database;
namespace UCS_Status_Monitor.Extensions
{
public static class AxisCamExtensions
{
public static string TableColor(this AxisCam cam)
{
if (cam.Connected == true)
{
return "table-success";
}
return "table-danger";
}
}
}
//namespace UCS_Status_Monitor.Extensions
//{
// public static class AxisCamExtensions
// {
// //public static string TableColor(this AxisCam cam)
// //{
// // if (cam.Connected == true)
// // {
// // return "border-success";
// // }
// // return "border-danger";
// //}
// }
//}

View File

@@ -1,16 +1,18 @@
using UCS_Status_Monitor.Monitor;
//using System;
//using UCS_Status_Monitor.Monitor;
namespace UCS_Status_Monitor.Extensions
{
public static class BaseMonitorExtension
{
public static string TableColor(this BaseMonitorDevice dev)
{
if (dev.IsConnected == true)
{
return "table-success";
}
return "table-danger";
}
}
}
//namespace UCS_Status_Monitor.Extensions
//{
// public static class BaseMonitorExtension
// {
// //public static string TableColor(this BaseMonitorDevice dev)
// //{
// // ArgumentNullException.ThrowIfNull(dev);
// // if (dev.IsConnected == true)
// // {
// // return "table-success";
// // }
// // return "table-danger";
// //}
// }
//}

View File

@@ -1,4 +1,7 @@
namespace UCS_Status_Monitor.Extensions
using System;
using UCS_Status_Monitor.Models.Database;
namespace UCS_Status_Monitor.Extensions
{
public static class BooleanExtensions
{
@@ -13,5 +16,14 @@
return "Offline";
}
}
public static string BootstrapColor(this bool state)
{
if (state == true)
{
return "success";
}
return "danger";
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using System.Diagnostics;
using System.Globalization;
namespace UCS_Status_Monitor.Extensions
{
public static class DateTimeExtensions
{
public static string TimeAgo(this DateTime dateTime)
{
TimeSpan timeSpan = DateTime.Now.Subtract(dateTime);
if (timeSpan.TotalSeconds < 60)
{
return $"{timeSpan.Seconds} seconds ago";
}
if (timeSpan.TotalMinutes < 60)
{
return $"{timeSpan.Minutes} minutes ago";
}
if (timeSpan.TotalHours < 24)
{
return $"{timeSpan.Hours} hours ago";
}
if (timeSpan.TotalDays < 30)
{
return $"{timeSpan.Days} days ago";
}
if (timeSpan.TotalDays < 365)
{
return $"{(int)(timeSpan.TotalDays / 30)} months ago";
}
return $"{(int)(timeSpan.TotalDays / 365)} years ago";
}
public static string FormatDateTime(this DateTime dt)
{
if (dt == DateTime.MinValue)
{
return "??";
}
if (dt.Kind == DateTimeKind.Utc)
{
return dt.ToLocalTime().ToString("dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
return dt.ToString("dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
public static DateTime ParseDeviceTime(this string? deviceTime)
{
if (DateTime.TryParseExact(deviceTime, "dd-MM-yyyy HH:mm:ss", null, DateTimeStyles.None, out DateTime laststate))
{
return laststate;
}
else
{
Debug.WriteLine($"Failed to parse LastStateChange");
return DateTime.MinValue;
}
}
}
}

View File

@@ -1,16 +1,59 @@
using UCS_Status_Monitor.Models.Database;
using System;
using UCS_Status_Monitor.Models.Database;
namespace UCS_Status_Monitor.Extensions
{
public static class RouterExtensions
{
public static string TableColor(this Router router)
public static string GetTemperature(this Router router)
{
if (router.Connected == true)
{
return "table-success";
}
return "table-danger";
ArgumentNullException.ThrowIfNull(router);
return $"{router.Temperature}℃";
}
public static string GetThisMonthRX(this Router router)
{
ArgumentNullException.ThrowIfNull(router);
//return $"{ThisMonthRX / 1000000} MB";
return $"{router.ThisMonthRX / 1048576} MB";
}
public static string GetThisMonthTX(this Router router)
{
ArgumentNullException.ThrowIfNull(router);
//return $"{ThisMonthTX / 1000000} MB";
return $"{router.ThisMonthTX / 1048576} MB";
}
public static string ThisMonthTotal(this Router router)
{
ArgumentNullException.ThrowIfNull(router);
//return $"{(ThisMonthTX + ThisMonthRX) / 1000000} MB";
return $"{(router.ThisMonthTX + router.ThisMonthRX) / 1048576} MB";
}
public static string GetRSSI(this Router router)
{
ArgumentNullException.ThrowIfNull(router);
return $"{router.RSSI} dBm";
}
//public static string GetLastMonthRX(this Router router)
//{
// //return $"{LastMonthRX / 1000000} MB";
// return $"{router.LastMonthRX / 1048576} MB";
//}
//public static string GetLastMonthTX(this Router router)
//{
// //return $"{LastMonthTX / 1000000} MB";
// return $"{router.LastMonthTX / 1048576} MB";
//}
//public static string LastMonthTotal(this Router router)
//{
// //return $"{(LastMonthRX + LastMonthTX) / 1000000} MB";
// return $"{(router.LastMonthRX + router.LastMonthTX) / 1048576} MB";
//}
}
}

View File

@@ -1,24 +0,0 @@
using UCS_Status_Monitor.Models.Database;
namespace UCS_Status_Monitor.Extensions
{
public static class SensorExtensions
{
public static bool IsAlarm(this Sensor sensor)
{
if (string.IsNullOrEmpty(sensor.TxString))
{
return false;
}
if (sensor.TxString.ToLower() == "alarm")
{
return true;
}
if (sensor.TxString.ToLower() == "rust")
{
return false;
}
return false;
}
}
}

View File

@@ -0,0 +1,164 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.Monitor;
namespace UCS_Status_Monitor.Extensions
{
public static class SortExtensions
{
public static List<Router> SortTable(this List<Router> routers, string? sortOrder)
{
//Debug.WriteLine($"Sort Order = {sortOrder}");
if (sortOrder != null)
{
routers = sortOrder switch
{
"location_desc" => [.. routers.OrderBy(s => s.Location)],
"location_asc" => [.. routers.OrderByDescending(s => s.Location)],
"device_desc" => [.. routers.OrderBy(s => s.Device)],
"device_asc" => [.. routers.OrderByDescending(s => s.Device)],
"temp_desc" => [.. routers.OrderBy(s => s.Temperature)],
"temp_asc" => [.. routers.OrderByDescending(s => s.Temperature)],
"thisrx_desc" => [.. routers.OrderBy(s => s.ThisMonthRX)],
"thisrx_asc" => [.. routers.OrderByDescending(s => s.ThisMonthRX)],
"thistx_desc" => [.. routers.OrderBy(s => s.ThisMonthTX)],
"thistx_asc" => [.. routers.OrderByDescending(s => s.ThisMonthTX)],
"rssi_desc" => [.. routers.OrderBy(s => s.RSSI)],
"rssi_asc" => [.. routers.OrderByDescending(s => s.RSSI)],
"wanip_desc" => [.. routers.OrderBy(s => s.WanIp)],
"wanip_asc" => [.. routers.OrderByDescending(s => s.WanIp)],
"firmware_desc" => [.. routers.OrderBy(s => s.FirmwareVersion)],
"firmware_asc" => [.. routers.OrderByDescending(s => s.FirmwareVersion)],
"timestamp_desc" => [.. routers.OrderBy(s => s.Timestamp)],
"timestamp_asc" => [.. routers.OrderByDescending(s => s.Timestamp)],
"timeout_desc" => [.. routers.OrderBy(s => s.MonitorDevice?.SecondsToTimeout())],
"timeout_asc" => [.. routers.OrderByDescending(s => s.MonitorDevice?.SecondsToTimeout())],
_ => [.. routers.OrderBy(s => s.Location)],
};
}
return routers;
}
public static List<Router> AddMonitorDevice(this List<Router> routers, MonitorHandler monitorHandler)
{
//Debug.WriteLine($"Sort Order = {sortOrder}");
foreach (var router in routers)
{
router.MonitorDevice = monitorHandler?.GetDevice(router.Device) as RouterMonitorDevice;
}
return routers;
}
public static List<UCSSystem> SortTable(this List<UCSSystem> systems, string? sortOrder)
{
if (sortOrder != null)
{
systems = sortOrder switch
{
"system_asc" => [.. systems.OrderBy(s => s.ComputerName)],
"system_desc" => [.. systems.OrderByDescending(s => s.ComputerName)],
"configfile_asc" => [.. systems.OrderBy(s => s.ConfigFileName)],
"configfile_desc" => [.. systems.OrderByDescending(s => s.ConfigFileName)],
"uptime_asc" => [.. systems.OrderBy(s => s.Uptime.ToTimespan())],
"uptime_desc" => [.. systems.OrderByDescending(s => s.Uptime.ToTimespan())],
"systemuptime_asc" => [.. systems.OrderBy(s => s.SystemUptime.ToTimespan())],
"systemuptime_desc" => [.. systems.OrderByDescending(s => s.SystemUptime.ToTimespan())],
"ucsversion_asc" => [.. systems.OrderBy(s => s.UCSVersion)],
"ucsversion_desc" => [.. systems.OrderByDescending(s => s.UCSVersion)],
"oscaption_asc" => [.. systems.OrderBy(s => s.OSCaption)],
"oscaption_desc" => [.. systems.OrderByDescending(s => s.OSCaption)],
"osversion_asc" => [.. systems.OrderBy(s => s.OSVersion)],
"osversion_desc" => [.. systems.OrderByDescending(s => s.OSVersion)],
"dotnetversion_asc" => [.. systems.OrderBy(s => s.DotNetVersion)],
"dotnetversion_desc" => [.. systems.OrderByDescending(s => s.DotNetVersion)],
"axisversion_asc" => [.. systems.OrderBy(s => s.AxisVersion)],
"axisversion_desc" => [.. systems.OrderByDescending(s => s.AxisVersion)],
"boschversion_asc" => [.. systems.OrderBy(s => s.BoschVersion)],
"boschversion_desc" => [.. systems.OrderByDescending(s => s.BoschVersion)],
"computermodel_asc" => [.. systems.OrderBy(s => s.ComputerModel)],
"computermodel_desc" => [.. systems.OrderByDescending(s => s.ComputerModel)],
"biosversion_asc" => [.. systems.OrderBy(s => s.BIOSVersion)],
"biosversion_desc" => [.. systems.OrderByDescending(s => s.BIOSVersion)],
"processorname_asc" => [.. systems.OrderBy(s => s.ProcessorName)],
"processorname_desc" => [.. systems.OrderByDescending(s => s.ProcessorName)],
"physicalmemory_asc" => [.. systems.OrderBy(s => s.PhysicalMemory)],
"physicalmemory_desc" => [.. systems.OrderByDescending(s => s.PhysicalMemory)],
"videocontroller_asc" => [.. systems.OrderBy(s => s.VideoController)],
"videocontroller_desc" => [.. systems.OrderByDescending(s => s.VideoController)],
"monitors_asc" => [.. systems.OrderBy(s => s.Monitors)],
"monitors_desc" => [.. systems.OrderByDescending(s => s.Monitors)],
"usbdisks_desc" => [.. systems.OrderBy(s => s.USBDisks)],
"usbdisks_asc" => [.. systems.OrderByDescending(s => s.USBDisks)],
"lastmessage_asc" => [.. systems.OrderBy(s => s.LastMessageTime)],
"lastmessage_desc" => [.. systems.OrderByDescending(s => s.LastMessageTime)],
_ => [.. systems.OrderBy(s => s.ComputerName)],
};
}
return systems;
}
public static ICollection<UCSDevice> SortTable(this ICollection<UCSDevice> devices, string? sortOrder)
{
if (sortOrder != null)
{
devices = sortOrder switch
{
"boxid_asc" => devices.OrderBy(s => s.BoxID).ToList(),
"boxid_desc" => [.. devices.OrderByDescending(s => s.BoxID)],
"name_asc" => [.. devices.OrderBy(s => s.Name)],
"name_desc" => [.. devices.OrderByDescending(s => s.Name)],
"message_asc" => [.. devices.OrderBy(s => s.Message)],
"message_desc" => [.. devices.OrderByDescending(s => s.Message)],
"changed_asc" => [.. devices.OrderBy(s => s.LastStateChange)],
"changed_desc" => [.. devices.OrderByDescending(s => s.LastStateChange)],
_ => [.. devices.OrderBy(s => s.Id)],
};
}
return devices;
}
public static List<AxisCam> SortTable(this List<AxisCam> cams, string? sortOrder)
{
//Debug.WriteLine($"Sort Order = {sortOrder}");
if (sortOrder != null)
{
cams = sortOrder switch
{
"location_desc" => [.. cams.OrderBy(s => s.Location)],
"location_asc" => [.. cams.OrderByDescending(s => s.Location)],
"device_desc" => [.. cams.OrderBy(s => s.Device)],
"device_asc" => [.. cams.OrderByDescending(s => s.Device)],
"serial_desc" => [.. cams.OrderBy(s => s.SerialNumber)],
"serial_asc" => [.. cams.OrderByDescending(s => s.SerialNumber)],
"conn_desc" => [.. cams.OrderBy(s => s.Connected)],
"conn_asc" => [.. cams.OrderByDescending(s => s.Connected)],
"desc_desc" => [.. cams.OrderBy(s => s.Description)],
"desc_asc" => [.. cams.OrderByDescending(s => s.Description)],
"ready_desc" => [.. cams.OrderBy(s => s.SystemReady)],
"ready_asc" => [.. cams.OrderByDescending(s => s.SystemReady)],
"temp_desc" => [.. cams.OrderBy(s => s.Temperature)],
"temp_asc" => [.. cams.OrderByDescending(s => s.Temperature)],
"timestamp_desc" => [.. cams.OrderBy(s => s.Timestamp)],
"timestamp_asc" => [.. cams.OrderByDescending(s => s.Timestamp)],
"lastdata_desc" => [.. cams.OrderBy(s => s.MonitorDevice?.LastData)],
"lastdata_asc" => [.. cams.OrderByDescending(s => s.MonitorDevice?.LastData)],
_ => [.. cams.OrderBy(s => s.Location)],
};
}
return cams;
}
public static List<AxisCam> AddMonitorDevice(this List<AxisCam> cams, MonitorHandler monitorHandler)
{
//Debug.WriteLine($"Sort Order = {sortOrder}");
foreach (var cam in cams)
{
cam.MonitorDevice = monitorHandler?.GetDevice(cam.Device) as AxisCamMonitorDevice;
}
return cams;
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
namespace UCS_Status_Monitor.Extensions
@@ -8,30 +9,22 @@ namespace UCS_Status_Monitor.Extensions
{
public static string ListToString(this List<string> arr)
{
ArgumentNullException.ThrowIfNull(arr);
var str = "";
foreach (var item in arr)
for (int i = 0; i < arr.Count; i++)
{
str += $"{item}{Environment.NewLine}";
str += arr[i];
if (i != arr.Count - 1)
{
str += Environment.NewLine;
}
}
return str;
}
public static string FormatDateTime(this DateTime dt)
{
if (dt == DateTime.MinValue)
{
return "??";
}
if(dt.Kind == DateTimeKind.Utc)
{
return dt.ToLocalTime().ToString("dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
return dt.ToString("dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
public static string Truncate(this string input, int length)
{
ArgumentNullException.ThrowIfNull(input);
if (input.Length <= length)
{
return input;
@@ -41,5 +34,18 @@ namespace UCS_Status_Monitor.Extensions
return string.Concat(input.AsSpan(0, length), "...");
}
}
public static TimeSpan ToTimespan(this string input)
{
ArgumentNullException.ThrowIfNull(input);
//Debug.WriteLine(input);
string value = input.Replace(" days ", ":", StringComparison.Ordinal);
//Debug.WriteLine(value);
if (TimeSpan.TryParse(value, CultureInfo.InvariantCulture, out TimeSpan ts))
{
return ts;
}
return new TimeSpan();
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace UCS_Status_Monitor.Extensions
{
public static class TimeSpanExtensions
{
public static string GetUptime(this TimeSpan timespan)
{
return $"{timespan.Days} days {timespan.Hours} hours {timespan.Minutes} min {timespan.Seconds} sec";
}
}
}

View File

@@ -1,6 +1,10 @@
using System;
using Microsoft.AspNetCore.Components.Routing;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using UCS_Status_Monitor.Models.Database;
using static UCS_Status_Monitor.Monitor.UCSSystemMonitorDevice;
namespace UCS_Status_Monitor.Extensions
{
@@ -8,22 +12,41 @@ namespace UCS_Status_Monitor.Extensions
{
public static string TableColor(this UCSSystem system)
{
ArgumentNullException.ThrowIfNull(system);
if (system.ConnectionState == true)
{
if (system.Devices != null)
{
if (system.Devices.Any(s => s.State == false))
{
return "table-warning";
return "border-warning";
}
}
return "table-success";
return "border-success";
}
return "table-danger";
return "border-danger";
}
public static string BootstrapColor(this UCSSystem system)
{
ArgumentNullException.ThrowIfNull(system);
if (system.ConnectionState == true)
{
if (system.Devices != null)
{
if (system.Devices.Any(s => s.State == false))
{
return "warning";
}
}
return "success";
}
return "danger";
}
public static string ComputerNameWithError(this UCSSystem system)
{
ArgumentNullException.ThrowIfNull(system);
if (system.ComputerName == null)
{
return string.Empty;

View File

@@ -1,14 +1,10 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace UCS_Status_Monitor.Helpers
{
public class SystemInformationHelper
public static class SystemInformationHelper
{
//[SupportedOSPlatform("windows")]
public static string GetProcessorProperty(string property)
@@ -42,7 +38,6 @@ namespace UCS_Status_Monitor.Helpers
{
if (OperatingSystem.IsWindows())
{
try
{
UInt64 total = 0;

View File

@@ -2,9 +2,9 @@
{
public class LDAPConfig
{
public string ServerAddress { get; set; }
public string GroupName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string ServerAddress { get; set; } = string.Empty;
public string GroupName { get; set; } = string.Empty;
public string UserName { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}

View File

@@ -1,151 +1,225 @@
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using UCS_Status_Monitor.Log;
namespace UCS_Status_Monitor.LDAP
{
public class LDAPService
public class LDAPService(IOptions<LDAPConfig> config, ILogger<LDAPService> logger)
{
private readonly LDAPConfig _config;
private readonly LDAPConfig _config = config.Value;
private readonly ILogger<LDAPService> _logger = logger;
public LDAPService(IOptions<LDAPConfig> config)
public bool ValidateUser(string username, string password)
{
_config = config.Value;
}
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
return false;
}
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
private PrincipalContext GetConnection()
{
try
{
return new PrincipalContext(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
using PrincipalContext context = new(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
return context.ValidateCredentials(username, password);
}
catch (Exception ex)
{
Debug.WriteLine($"GetConnection exception = {ex.Message}");
throw;
//Debug.WriteLine($"GetConnection exception = {ex.Message}");
Logger.LogError(_logger, $"Failed to validate user {username}: {ex.Message}");
}
return false;
}
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public Boolean ValidateUser(string username, string password)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
return false;
return GetConnection().ValidateCredentials(username, password);
}
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public string GetUserFullName(string username)
{
if (string.IsNullOrEmpty(username))
{
return string.Empty;
}
try
{
UserPrincipal searchMaskDisplayname = new(GetConnection()) { SamAccountName = username };
PrincipalSearcher searcher = new(searchMaskDisplayname);
var principal = searcher.FindOne();
if (principal == null)
{
return String.Empty;
}
return principal.Name;
using var context = new PrincipalContext(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
using var user = UserPrincipal.FindByIdentity(context, username);
return user?.Name ?? string.Empty;
}
catch (Exception)
catch (Exception ex)
{
Logger.LogError(_logger, $"Failed to get user full name for {username}: {ex.Message}");
return string.Empty;
}
}
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public Boolean ValidateUserGroup(string username)
public string GetUserFromSID(string sid)
{
if (username == null)
return false;
if (string.IsNullOrEmpty(sid))
{
return string.Empty;
}
try
{
UserPrincipal searchMaskDisplayname = new(GetConnection()) { SamAccountName = username };
PrincipalSearcher searcher = new(searchMaskDisplayname);
var pricipal = searcher.FindOne();
if (pricipal == null)
using PrincipalContext context = new(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
using UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.Sid, sid);
return user?.SamAccountName ?? string.Empty;
}
catch (Exception ex)
{
Logger.LogError(_logger, $"Failed to get user from SID {sid}: {ex.Message}");
}
return string.Empty;
}
//public bool ValidateUserGroup(string username)
//{
// if (username == null)
// {
// return false;
// }
// try
// {
// using var context = new PrincipalContext(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
// using UserPrincipal searchMaskDisplayname = new(context) { SamAccountName = username };
// using PrincipalSearcher searcher = new(searchMaskDisplayname);
// //UserPrincipal searchMaskDisplayname = new(GetConnection()) { SamAccountName = username };
// //PrincipalSearcher searcher = new(searchMaskDisplayname);
// var principal = searcher.FindOne();
// if (principal == null)
// {
// return false;
// }
// PrincipalSearchResult<Principal> result = principal.GetGroups();
// return result.Where(n => n.Name == _config.GroupName).Any();
// }
// catch (Exception ex)
// {
// Logger.LogError(_logger, $"Failed to validate user group for user {username}: {ex.Message}");
// return false;
// }
//}
public bool ValidateUserGroup(string username)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(_config.GroupName))
{
return false;
}
try
{
using PrincipalContext context = new(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
// Find the user directly
UserPrincipal user = UserPrincipal.FindByIdentity(context, username);
if (user == null)
{
return false;
}
PrincipalSearchResult<Principal> result = pricipal.GetGroups();
return result.Where(n => n.Name == _config.GroupName).Any();
// Check if user belongs to the specified group
using GroupPrincipal group = new(context) { Name = _config.GroupName };
using PrincipalSearcher searcher = new(group);
Principal groupResult = searcher.FindOne();
if (groupResult == null)
{
return false;
}
// Check membership more directly
return user.IsMemberOf(groupResult as GroupPrincipal);
}
catch (Exception)
catch (Exception ex)
{
Logger.LogError(_logger, $"Failed to validate user group for user {username}: {ex.Message}");
return false;
}
}
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public List<Principal> GetAllUsers()
public List<string> GetAllUsers()
{
//Debug.WriteLine("LDAP GetAllUsers");
UserPrincipal up = new(GetConnection());
PrincipalSearcher searcher = new(up);
PrincipalSearchResult<Principal> result = searcher.FindAll();
//foreach (Principal item in result)
//{
// Debug.WriteLine(item.Name);
//}
return result.ToList();
}
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public List<Principal> GetAllUsersForGroup(string group)
{
List<Principal> userList = [];
var result = GetAllUsers();
foreach (Principal item in result)
try
{
//Debug.WriteLine(item.Name);
if(item.GetGroups().Where(x => x.Name == group).Any())
{
userList.Add(item);
}
using var context = new PrincipalContext(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
using UserPrincipal up = new(context) { Enabled = true };
using PrincipalSearcher searcher = new(up);
var result = searcher.FindAll().Select(n => n.Name).ToList();
return result;
}
catch (Exception ex)
{
Logger.LogError(_logger, ex.Message);
return [];
}
return userList;
}
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public List<Principal> GetAllGroups()
public List<string> GetAllUsersForGroup(string group)
{
//Debug.WriteLine("LDAP GetAllGroups");
try
{
using var context = new PrincipalContext(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
GroupPrincipal groupPrincipal = new(GetConnection());
PrincipalSearcher searcher = new(groupPrincipal);
PrincipalSearchResult<Principal> result = searcher.FindAll();
using UserPrincipal up = new(context) { Enabled = true };
using PrincipalSearcher searcher = new(up);
//foreach (Principal item in result)
//{
// Debug.WriteLine(item.Name);
//}
return result.ToList();
List<string> userList = [];
foreach (var user in searcher.FindAll())
{
if (user.GetGroups().Where(x => x.Name == group).Any())
{
userList.Add(user.Name);
}
}
return userList;
}
catch (Exception ex)
{
Logger.LogError(_logger, ex.Message);
return [];
}
}
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
public List<Principal> GetAllGroupsForUser(string username)
public List<string> GetAllGroups()
{
//Debug.WriteLine("LDAP GetAllGroupsForUser");
try
{
//Debug.WriteLine("LDAP GetAllGroups");
using var context = new PrincipalContext(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
using GroupPrincipal groupPrincipal = new(context);
using PrincipalSearcher searcher = new(groupPrincipal);
return searcher.FindAll().Select(n => n.Name).ToList();
}
catch (Exception ex)
{
Logger.LogError(_logger, ex.Message);
return [];
}
}
UserPrincipal searchMaskDisplayname = new(GetConnection()) { SamAccountName = username };
PrincipalSearcher searcher = new(searchMaskDisplayname);
PrincipalSearchResult<Principal> result = searcher.FindOne().GetGroups();
//foreach (Principal item in result)
//{
// Debug.WriteLine(item.Name);
//}
return result.ToList();
public List<string> GetAllGroupsForUser(string username)
{
try
{
//Debug.WriteLine("LDAP GetAllGroupsForUser");
using var context = new PrincipalContext(ContextType.Domain, _config.ServerAddress, _config.UserName, _config.Password);
using UserPrincipal searchMaskDisplayname = new(context) { SamAccountName = username };
using PrincipalSearcher searcher = new(searchMaskDisplayname);
return searcher.FindOne().GetGroups().Select(n => n.Name).ToList();
}
catch (Exception ex)
{
Logger.LogError(_logger, ex.Message);
return [];
}
}
}
}

View File

@@ -0,0 +1,34 @@
using Microsoft.Extensions.Logging;
using System;
namespace UCS_Status_Monitor.Log
{
public static partial class Logger
{
[LoggerMessage(Level = LogLevel.Error, EventId = 0, Message = "{message}")]
internal static partial void LogError(ILogger logger, string message);
[LoggerMessage(Level = LogLevel.Error, EventId = 1, Message = "{message} => Exception: {ex}")]
internal static partial void LogError(ILogger logger, string message, Exception ex);
[LoggerMessage(Level = LogLevel.Error, EventId = 2)]
internal static partial void LogError(ILogger logger, Exception ex);
[LoggerMessage(Level = LogLevel.Warning, EventId = 3, Message = "{message}")]
internal static partial void LogWarning(ILogger logger, string message);
[LoggerMessage(Level = LogLevel.Information, EventId = 4, Message = "{message}")]
internal static partial void LogInformation(ILogger logger, string message);
[LoggerMessage(Level = LogLevel.Debug, EventId = 5, Message = "{message}")]
internal static partial void LogDebug(ILogger logger, string message);
[LoggerMessage(Level = LogLevel.Trace, EventId = 6, Message = "{message}")]
internal static partial void LogTrace(ILogger logger, string message);
}
}

View File

@@ -0,0 +1,10 @@
{
"topic": "onvif:Device/axis:Status/Temperature/Above_or_below",
"timestamp": 1659948787950,
"serial": "B8A44F4A65CD",
"message": {
"source": {},
"key": {},
"data": { "sensor_level": "0" }
}
}

View File

@@ -1,63 +1,36 @@
using System;
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace UCS_Status_Monitor.MQTT.Axis
{
public class AxisCamConnectionMessage
public class AxisCamConnectionMessage : MQTTDeviceMessage
{
//online
//{
// "serialNumber": "B8A44F4A646C",
// "timestamp": "2022-07-26T08:33:59.336107Z",
// "connected": true,
// "description": "Connected"
//}
//offline
//{
// "serialNumber": "B8A44F9173E6",
// "timestamp": null,
// "connected": false,
// "description": "Connection Lost"
//}
public static AxisCamConnectionMessage? Deserialize(string json, string device, string location)
{
try
{
AxisCamConnectionMessage? message = JsonSerializer.Deserialize<AxisCamConnectionMessage>(json, new JsonSerializerOptions()
{
NumberHandling = JsonNumberHandling.AllowReadingFromString
});
if (message != null)
{
message.Device = device;
message.Location = location;
}
return message;
}
catch (Exception ex)
{
Debug.WriteLine($"AxisCamConnectionMessage: {ex.Message}");
return null;
}
}
[JsonIgnore]
public string Device { get; set; }
[JsonIgnore]
public string Location { get; set; }
[JsonPropertyName("serialNumber")]
public string SerialNumber { get; set; }
public string? SerialNumber { get; set; }
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; }
public DateTime? Timestamp { get; set; }
[JsonPropertyName("connected")]
public bool Connected { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
//public override string ToString()
//{
// return $"serialNumber: {SerialNumber}{Environment.NewLine}timestamp: {Timestamp}{Environment.NewLine}connected: {Connected}{Environment.NewLine}description: {Description}{Environment.NewLine}";
//}
public string? Description { get; set; }
}
}

View File

@@ -1,16 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace UCS_Status_Monitor.MQTT.Axis
{
public class AxisCamStatusMessage
{
#region exampleData
public class AxisCamStatusMessage : MQTTDeviceMessage
{
//{
// "topic":"onvif:Device/axis:Status/SystemReady",
// "timestamp":1659948819367,
@@ -54,42 +49,29 @@ namespace UCS_Status_Monitor.MQTT.Axis
// "data":{"active":"0"}
// }
//}
#endregion
public static AxisCamStatusMessage? Deserialize(string json, string device, string location)
{
try
{
AxisCamStatusMessage? message = JsonSerializer.Deserialize<AxisCamStatusMessage>(json, new JsonSerializerOptions()
{
NumberHandling = JsonNumberHandling.AllowReadingFromString
});
//{"topic":"onvif:Device/axis:Status/Temperature/Above",
//"timestamp":1720515011253,
//"message":{
// "source":{},
// "key":{},
// "data":{
// "sensor_level":"0"
//}}}
if (message != null)
{
message.Device = device;
message.Location = location;
}
return message;
}
catch (Exception ex)
{
Debug.WriteLine($"AxisCamStatusMessage: {ex.Message}");
return null;
}
}
//5623MT001/S13CAM03/event/tns:onvif/Device/tns:axis/Status/Temperature/Above
//{"topic":"onvif:Device/axis:Status/Temperature/Above","timestamp":1720515011253,"message":{"source":{},"key":{},"data":{"sensor_level":"0"}}}
//5623MT001/S13CAM03/event/tns:onvif/Device/tns:axis/Status/Temperature/Below
//{"topic":"onvif:Device/axis:Status/Temperature/Below","timestamp":1720515011254,"message":{"source":{},"key":{},"data":{"sensor_level":"0"}}}
//5623MT001/S13CAM03/event/tns:onvif/Device/tns:axis/Status/Temperature/Inside
//{"topic":"onvif:Device/axis:Status/Temperature/Inside","timestamp":1720515011254,"message":{"source":{},"key":{},"data":{"sensor_level":"1"}}}
[JsonIgnore]
public string Device { get; set; }
[JsonIgnore]
public string Location { get; set; }
[JsonPropertyName("topic")]
public string Topic { get; set; }
public string? Topic { get; set; }
[JsonPropertyName("serial")]
public string SerialNumber { get; set; }
public string? SerialNumber { get; set; }
[JsonPropertyName("timestamp")]
public ulong TimestampUnix { get; set; }

View File

@@ -0,0 +1,50 @@
//using System.Diagnostics;
//using System.Text.Json.Serialization;
//using System.Text.Json;
//using System;
//namespace UCS_Status_Monitor.MQTT.Axis
//{
// public class AxisCamTemperatureMessage
// {
// //{"topic":"onvif:Device/axis:Status/Temperature/Above",
// //"timestamp":1720515011253,
// //"message":{
// // "source":{},
// // "key":{},
// // "data":{
// // "sensor_level":"0"
// //}}}
// public static AxisCamTemperatureMessage? Deserialize(string json, string device, string location)
// {
// try
// {
// AxisCamTemperatureMessage? message = JsonSerializer.Deserialize<AxisCamTemperatureMessage>(json, new JsonSerializerOptions()
// {
// NumberHandling = JsonNumberHandling.AllowReadingFromString
// });
// if (message != null)
// {
// message.Device = device;
// message.Location = location;
// }
// return message;
// }
// catch (Exception ex)
// {
// Debug.WriteLine($"AxisCamStatusMessage: {ex.Message}");
// return null;
// }
// }
// [JsonIgnore]
// public string Device { get; set; } = string.Empty;
// [JsonIgnore]
// public string Location { get; set; } = string.Empty;
// }
//}

View File

@@ -0,0 +1,6 @@
{
"serialNumber": "B8A44F9173E6",
"timestamp": null,
"connected": false,
"description": "Connection Lost"
}

View File

@@ -0,0 +1,6 @@
{
"serialNumber": "B8A44F4A646C",
"timestamp": "2022-07-26T08:33:59.336107Z",
"connected": true,
"description": "Connected"
}

View File

@@ -0,0 +1,10 @@
{
"topic": "onvif:Device/axis:Status/SystemReady",
"timestamp": 1659948819367,
"serial": "B8A44F4A65CD",
"message": {
"source": {},
"key": {},
"data": { "ready": "1" }
}
}

View File

@@ -0,0 +1,9 @@
{
"topic": "onvif:Device/axis:Status/Temperature/Above",
"timestamp": 1720515011253,
"message": {
"source": {},
"key": {},
"data": { "sensor_level": "0" }
}
}

View File

@@ -0,0 +1,9 @@
{
"topic": "onvif:Device/axis:Status/Temperature/Below",
"timestamp": 1720515011254,
"message": {
"source": {},
"key": {},
"data": { "sensor_level": "0" }
}
}

View File

@@ -0,0 +1,9 @@
{
"topic": "onvif:Device/axis:Status/Temperature/Inside",
"timestamp": 1720515011254,
"message": {
"source": {},
"key": {},
"data": { "sensor_level": "1" }
}
}

View File

@@ -1,20 +1,15 @@
using MQTTnet.Client;
using MQTTnet;
using System.Security.Cryptography.X509Certificates;
namespace UCS_Status_Monitor.MQTT
{
public class ClientCertProvider : IMqttClientCertificatesProvider
public class ClientCertProvider(X509Certificate2 clientCert) : IMqttClientCertificatesProvider
{
public X509Certificate2 _clientCert { get; set; }
public ClientCertProvider(X509Certificate2 clientCert)
{
_clientCert = clientCert;
}
public X509Certificate2 ClientCert { get; set; } = clientCert;
public X509CertificateCollection GetCertificates()
{
return new X509Certificate2Collection(_clientCert);
return new X509Certificate2Collection(ClientCert);
}
}
}

View File

@@ -1,11 +1,17 @@
namespace UCS_Status_Monitor.Mqtt
using System.Security.Cryptography.X509Certificates;
namespace UCS_Status_Monitor.MQTT
{
public class MQTTConfig
{
public string ClientID { get; set; }
public string BrokerAddress { get; set; }
public string ClientID { get; set; } = string.Empty;
public string BrokerAddress { get; set; } = string.Empty;
public int BrokerPort { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string CaCert { get; set; } = string.Empty;
public string ClientCert { get; set; } = string.Empty;
public string ClientCertPassword { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,47 @@
using System.Diagnostics;
using System;
using System.Text.Json.Serialization;
using System.Text.Json;
namespace UCS_Status_Monitor.MQTT
{
public class MQTTDeviceMessage
{
[JsonIgnore]
public string? Device { get; set; }
[JsonIgnore]
public string? Location { get; set; }
private static readonly JsonSerializerOptions _serializerOptions = new()
{
NumberHandling = JsonNumberHandling.AllowReadingFromString,
PropertyNameCaseInsensitive = false,
};
public static T? Deserialize<T>(string json, string device, string location)
{
//Debug.WriteLine($"{device} - {location} - {json}");
try
{
T? message = JsonSerializer.Deserialize<T>(json, _serializerOptions);
if (message != null)
{
if(message is MQTTDeviceMessage devicemessage)
{
devicemessage.Device = device;
devicemessage.Location = location;
}
}
return message;
}
catch (Exception ex)
{
Debug.WriteLine($"MQTT Deserialize: {ex.Message}");
return default;
}
}
}
}

View File

@@ -1,80 +1,56 @@
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Protocol;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
using UCS_Status_Monitor.Models.Database;
using UCS_Status_Monitor.MQTT;
using UCS_Status_Monitor.Log;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.MQTT.Axis;
using UCS_Status_Monitor.MQTT.Teltonika;
using UCS_Status_Monitor.Telegram;
using UCS_Status_Monitor.Monitor;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using Microsoft.Extensions.DependencyInjection;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace UCS_Status_Monitor.Mqtt
namespace UCS_Status_Monitor.MQTT
{
public interface IMQTTService
{
//Task EnqueuePacket(Models.SensorPacket packet);
}
public class MQTTService : BackgroundService, IMQTTService
public class MQTTService : IHostedService
{
private readonly ILogger<MQTTService> _logger;
private readonly MQTTConfig _mqttconfig;
private readonly ITelegramBotService _telegramBot;
private readonly MonitorHandler _monitorHandler;
private readonly IDbContextFactory<MonitorDbContext> _contextFactory;
private readonly IConfiguration _configuration;
private readonly IDbContextFactory<MonitorDbContext> _dbContextFactory;
public MQTTService(IServiceProvider serviceProvider)
private readonly X509Certificate2 _caCert;
private readonly X509Certificate2 _clientCert;
private readonly MqttClientOptions _mqttClientOptions;
private IMqttClient? _mqttClient;
private CancellationToken _cancellationToken;
public MQTTService(MonitorHandler monitorHandler, IDbContextFactory<MonitorDbContext> dbContextFactory, ILogger<MQTTService> logger, IOptions<MQTTConfig> options)
{
using IServiceScope scope = serviceProvider.CreateScope();
_logger = scope.ServiceProvider.GetRequiredService<ILogger<MQTTService>>();
_telegramBot = scope.ServiceProvider.GetRequiredService<ITelegramBotService>();
_mqttconfig = scope.ServiceProvider.GetRequiredService<IConfiguration>().GetSection("MQTT").Get<MQTTConfig>();
_monitorHandler = scope.ServiceProvider.GetRequiredService<MonitorHandler>();
_contextFactory = scope.ServiceProvider.GetRequiredService<IDbContextFactory<MonitorDbContext>>();
_configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
}
_monitorHandler = monitorHandler;
_dbContextFactory = dbContextFactory;
_logger = logger;
_mqttconfig = options?.Value ?? throw new KeyNotFoundException("Config \"MQTT\" section not found");
private readonly X509Certificate2 caCrt = new(File.ReadAllBytes(@"Certs\\ca.crt"));
//private readonly X509Certificate clientCert = new("Certs\\server.pfx", "12345");
private readonly X509Certificate2 clientCert2 = new("Certs\\server.pfx", "12345");
_caCert = X509CertificateLoader.LoadCertificateFromFile(_mqttconfig.CaCert);
_clientCert = X509CertificateLoader.LoadPkcs12FromFile(_mqttconfig.ClientCert, _mqttconfig.ClientCertPassword);
private readonly AutoResetEvent waitForConnection = new(false);
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
MqttFactory mqttFactory = new();
using IManagedMqttClient managedMqttClient = mqttFactory.CreateManagedMqttClient();
var managedMqttClientOptions = new ManagedMqttClientOptionsBuilder()
.WithClientOptions(new MqttClientOptionsBuilder()
_mqttClientOptions = new MqttClientOptionsBuilder()
.WithClientId(_mqttconfig.ClientID)
.WithTcpServer(_mqttconfig.BrokerAddress, _mqttconfig.BrokerPort)
.WithCredentials(_mqttconfig.Username, _mqttconfig.Password)
.WithTlsOptions(new MqttClientTlsOptions()
{
UseTls = true,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
})
.WithTlsOptions(new MqttClientTlsOptions()
{
UseTls = true,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
@@ -86,97 +62,96 @@ namespace UCS_Status_Monitor.Mqtt
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
chain.ChainPolicy.VerificationTime = DateTime.Now;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);
chain.ChainPolicy.CustomTrustStore.Add(caCrt);
chain.ChainPolicy.CustomTrustStore.Add(_caCert);
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
// convert provided X509Certificate to X509Certificate2
var x5092 = new X509Certificate2(certContext.Certificate);
return chain.Build(x5092);
},
ClientCertificatesProvider = new ClientCertProvider(clientCert2)
ClientCertificatesProvider = new ClientCertProvider(_clientCert)
})
//.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500)
.WithCleanSession()
.Build())
.Build();
}
managedMqttClient.ConnectingFailedAsync += OnConnectingFailed;
managedMqttClient.ConnectedAsync += OnConnected;
managedMqttClient.DisconnectedAsync += OnDisconnected;
managedMqttClient.ApplicationMessageReceivedAsync += OnApplicationMessageReceived;
await managedMqttClient.SubscribeAsync("#");
await managedMqttClient.StartAsync(managedMqttClientOptions);
waitForConnection.WaitOne();
while (!stoppingToken.IsCancellationRequested)
{
// var message = new MqttApplicationMessageBuilder()
// .WithTopic("MQTTNet/Test")
// .WithPayload("{\"Message\":\"Hello world\"}")
// .WithRetainFlag()
// .Build();
// await mqttClient.EnqueueAsync(message);
// //SpinWait.SpinUntil(() => managedMqttClient.PendingApplicationMessagesCount == 0, 10000);
// //Debug.WriteLine($"Pending messages = {managedMqttClient.PendingApplicationMessagesCount}");
// Debug.WriteLine($"Pending messages = {mqttClient.PendingApplicationMessagesCount}");
if (!managedMqttClient.IsConnected)
{
await managedMqttClient.StartAsync(managedMqttClientOptions);
}
else
{
// Wait until the queue is fully processed.
SpinWait.SpinUntil(() => managedMqttClient.PendingApplicationMessagesCount == 0, 10000);
}
await Task.Delay(10000, stoppingToken);
}
await managedMqttClient.StopAsync();
public async Task StartAsync(CancellationToken cancellationToken)
{
try
{
_cancellationToken = cancellationToken;
await ConnectMqtt(cancellationToken);
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
_logger.LogError(ex, "Setting up mqttclient failed");
Logger.LogError(_logger, "Mqttclient failed", ex);
}
}
private async Task<Task> OnConnectingFailed(ConnectingFailedEventArgs args)
public async Task StopAsync(CancellationToken cancellationToken)
{
Debug.WriteLine("Couldn't connect to broker." + args.Exception.Message);
_logger.LogError(args.Exception, "Connect to broker failed.");
return Task.CompletedTask;
await DisconnectMqtt();
_mqttClient?.Dispose();
_caCert.Dispose();
_clientCert.Dispose();
}
private async Task<Task> OnConnected(MqttClientConnectedEventArgs args)
private async Task ConnectMqtt(CancellationToken token)
{
Debug.WriteLine("Mqtt connected to broker");
waitForConnection.Set();
return Task.CompletedTask;
await DisconnectMqtt();
_mqttClient?.Dispose();
MqttClientFactory mqttFactory = new();
_mqttClient = mqttFactory.CreateMqttClient();
_mqttClient.ConnectedAsync += OnConnected;
_mqttClient.DisconnectedAsync += OnDisconnected;
_mqttClient.ApplicationMessageReceivedAsync += OnApplicationMessageReceived;
await _mqttClient.ConnectAsync(_mqttClientOptions, token);
MqttClientSubscribeOptions mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder().WithTopicFilter(filter =>
{
filter.WithTopic("#");
}).Build();
MqttClientSubscribeResult result = await _mqttClient.SubscribeAsync(mqttSubscribeOptions, token);
//Debug.WriteLine($"Subscribe result = {result.ReasonString}");
//Debug.WriteLine($"Subscribe result = {result.Items.First().ResultCode}");
}
private async Task<Task> OnDisconnected(MqttClientDisconnectedEventArgs args)
private async Task DisconnectMqtt()
{
Debug.WriteLine("Disconnected from broker.");
_logger.LogError("Disconnected from broker.");
return Task.CompletedTask;
if (_mqttClient != null)
{
if (_mqttClient.IsConnected)
{
await _mqttClient.TryDisconnectAsync();
}
}
}
//private async Task<Task> OnApplicationMessageProcessed(ApplicationMessageProcessedEventArgs args)
//{
// Debug.WriteLine("OnApplicationMessageProcessed");
// return Task.CompletedTask;
//}
private async Task OnConnected(MqttClientConnectedEventArgs args)
{
Debug.WriteLine($"Mqtt connected to broker - {args.ConnectResult}");
}
private async Task<Task> OnApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs args)
private async Task OnDisconnected(MqttClientDisconnectedEventArgs args)
{
Debug.WriteLine($"Disconnected from broker - {args.ReasonString}");
Logger.LogError(_logger, $"Disconnected from broker - {args.ReasonString}");
await ConnectMqtt(_cancellationToken);
}
private async Task OnApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs args)
{
//Debug.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
//Debug.WriteLine($"+ Topic = {args.ApplicationMessage.Topic}");
//Debug.WriteLine($"+ Payload = {Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment)}");
//Debug.WriteLine($"+ Payload = {Encoding.UTF8.GetString(args.ApplicationMessage.Payload)}");
//Debug.WriteLine($"+ QoS = {args.ApplicationMessage.QualityOfServiceLevel}");
//Debug.WriteLine($"+ Retain = {args.ApplicationMessage.Retain}");
//Debug.WriteLine("-------------------------------");
@@ -190,108 +165,161 @@ namespace UCS_Status_Monitor.Mqtt
if (device.Contains("ROUT"))
{
//5688HT001/S12ROUT01/V2
if (parts.Length == 2)
//if (parts.Length == 2)
//{
// //Version 1 message
// TeltonikaMessage? teltonikaMessage = MQTTDeviceMessage.Deserialize<TeltonikaMessage>(Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment), device, location);
// if (teltonikaMessage == null)
// {
// _logger.LogError($"Teltonika Mqtt error - {BitConverter.ToString(args.ApplicationMessage.PayloadSegment.ToArray())}");
// return Task.CompletedTask;
// }
// if (!_monitorHandler.TryGetDevice(device, out IMonitorObject router))
// {
// //Debug.WriteLine($"{device} Not found in list");
// router = new RouterMonitorDevice(_configuration.GetSection("MonitorWorker").GetValue<int>("RouterTimeOutMinutes"), _contextFactory, _telegramBot);
// _monitorHandler.AddDevice(device, router);
// }
// using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
// await router.Update(teltonikaMessage, db);
// await router.SetConnectionState(true, db);
// await db.SaveChangesAsync();
//}
//else
//{
if (parts[2] == "V2")
{
//Version 1 message
TeltonikaMessage? teltonikaMessage = TeltonikaMessage.Deserialize(Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment), device, location);
//Debug.WriteLine(Encoding.UTF8.GetString(args.ApplicationMessage.Payload));
//Version 2 message
TeltonikaMessageV2? teltonikaMessage = MQTTDeviceMessage.Deserialize<TeltonikaMessageV2>(Encoding.UTF8.GetString(args.ApplicationMessage.Payload), device, location);
if (teltonikaMessage == null)
{
_logger.LogError($"Teltonika Mqtt error - {BitConverter.ToString(args.ApplicationMessage.PayloadSegment.ToArray())}");
return Task.CompletedTask;
Logger.LogError(_logger, $"Teltonika Mqtt error - {Encoding.UTF8.GetString(args.ApplicationMessage.Payload)}");
return;
}
if (!_monitorHandler.TryGetDevice(device, out IMonitorObject router))
{
//Debug.WriteLine($"{device} Not found in list");
router = new RouterMonitorDevice(_configuration.GetSection("MonitorWorker").GetValue<int>("RouterTimeOutMinutes"), _contextFactory, _telegramBot);
_monitorHandler.AddDevice(device, router);
}
await router.Update(teltonikaMessage);
await router.SetConnectionState(true);
//using var dbContext = new MonitorDbContext(_configuration);
//Router router = new()
//{
// Location = location,
// Device = device,
// Temperature = teltonikaMessage.TempValue(),
// Uptime = teltonikaMessage.UptimeValue(),
// ThisMonthRX = teltonikaMessage.ThisMonthRX,
// ThisMonthTX = teltonikaMessage.ThisMonthTX,
// LastMonthRX = teltonikaMessage.LastMonthRX,
// LastMonthTX = teltonikaMessage.LastMonthTX,
// RSSI = teltonikaMessage.RSSI,
// WanIp = teltonikaMessage.WanIp,
// Timestamp = DateTime.Now
//};
//dbContext.Routers.Add(router);
//await dbContext.SaveChangesAsync();
//await _telegramBot.Send($"RX:{teltonikaMessage.ThisMonthRX / 1000000}MB TX:{teltonikaMessage.ThisMonthTX / 1000000}MB");
}
else
{
if (parts[2] == "V2")
{
//Version 2 message
TeltonikaMessageV2? teltonikaMessage = TeltonikaMessageV2.Deserialize(Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment), device, location);
if (teltonikaMessage == null)
{
_logger.LogError($"Teltonika Mqtt error - {BitConverter.ToString(args.ApplicationMessage.PayloadSegment.ToArray())}");
return Task.CompletedTask;
}
if (!_monitorHandler.TryGetDevice(device, out IMonitorObject router))
{
//Debug.WriteLine($"{device} Not found in list");
router = new RouterMonitorDevice(_configuration.GetSection("MonitorWorker").GetValue<int>("RouterTimeOutMinutes"), _contextFactory, _telegramBot);
_monitorHandler.AddDevice(device, router);
}
await router.Update(teltonikaMessage);
await router.SetConnectionState(true);
}
IRouterMonitorDevice router = _monitorHandler.GetDevice<IRouterMonitorDevice>(device);
using MonitorDbContext db = await _dbContextFactory.CreateDbContextAsync();
await router.Update(teltonikaMessage, db);
await router.SetConnectionState(true, db);
await db.SaveChangesAsync();
((IBaseMonitorDevice)router).DeviceChangedEvent();
}
//}
}
if (device.Contains("CAM"))
{
Debug.WriteLine(args.ApplicationMessage.Topic);
Debug.WriteLine(Encoding.UTF8.GetString(args.ApplicationMessage.Payload));
if (args.ApplicationMessage.Topic.EndsWith("/event/connection"))
{
AxisCamConnectionMessage? axisCamMessage = AxisCamConnectionMessage.Deserialize(Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment), device, location);
//Debug.WriteLine("Connection");
AxisCamConnectionMessage? axisCamMessage = MQTTDeviceMessage.Deserialize<AxisCamConnectionMessage>(Encoding.UTF8.GetString(args.ApplicationMessage.Payload), device, location);
if (axisCamMessage == null)
{
_logger.LogError($"Axis cam Mqtt error - {BitConverter.ToString(args.ApplicationMessage.PayloadSegment.ToArray())}");
return Task.CompletedTask;
Logger.LogError(_logger, $"Axis cam Mqtt error - {Encoding.UTF8.GetString(args.ApplicationMessage.Payload)}");
return;
}
if (!_monitorHandler.TryGetDevice(device, out IMonitorObject axisCam))
{
//Debug.WriteLine($"{device} Not found in list");
axisCam = new AxisCamMonitorDevice(_configuration.GetSection("MonitorWorker").GetValue<int>("AxisCamTimeOutMinutes"), _contextFactory, _telegramBot);
_monitorHandler.AddDevice(device, axisCam);
}
await axisCam.Update(axisCamMessage);
await axisCam.SetConnectionState(true);
IAxisCamMonitorDevice axisCam = _monitorHandler.GetDevice<IAxisCamMonitorDevice>(device);
using MonitorDbContext db = await _dbContextFactory.CreateDbContextAsync();
await axisCam.Update(axisCamMessage, db);
await axisCam.SetConnectionState(axisCamMessage.Connected, db);
await db.SaveChangesAsync();
((IBaseMonitorDevice)axisCam).DeviceChangedEvent();
}
else if (args.ApplicationMessage.Topic.EndsWith("/status"))
//else if (args.ApplicationMessage.Topic.EndsWith("/status"))
else
{
AxisCamStatusMessage? axisCamStatusMessage = AxisCamStatusMessage.Deserialize(Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment), device, location);
//Debug.WriteLine("Status");
//Debug.WriteLine(args.ApplicationMessage.Payload.Length);
AxisCamStatusMessage? axisCamStatusMessage = MQTTDeviceMessage.Deserialize<AxisCamStatusMessage>(Encoding.UTF8.GetString(args.ApplicationMessage.Payload), device, location);
if (axisCamStatusMessage == null)
{
_logger.LogError($"Axis cam Mqtt error - {BitConverter.ToString(args.ApplicationMessage.PayloadSegment.ToArray())}");
return Task.CompletedTask;
Logger.LogError(_logger, $"Axis cam Mqtt error - {Encoding.UTF8.GetString(args.ApplicationMessage.Payload)}");
return;
}
if (!_monitorHandler.TryGetDevice(device, out IMonitorObject axisCam))
{
//Debug.WriteLine($"{device} Not found in list");
axisCam = new AxisCamMonitorDevice(_configuration.GetSection("MonitorWorker").GetValue<int>("AxisCamTimeOutMinutes"), _contextFactory, _telegramBot);
_monitorHandler.AddDevice(device, axisCam);
}
await axisCam.Update(axisCamStatusMessage);
await axisCam.SetConnectionState(true);
IAxisCamMonitorDevice axisCam = _monitorHandler.GetDevice<IAxisCamMonitorDevice>(device);
using MonitorDbContext db = await _dbContextFactory.CreateDbContextAsync();
await axisCam.Update(axisCamStatusMessage, db);
await db.SaveChangesAsync();
((IBaseMonitorDevice)axisCam).DeviceChangedEvent();
}
//else
//{
// //onvif:Device/axis:Status/SystemRead
// //onvif:Device/axis:Status/Temperature/Above_or_below
// //axis:CameraApplicationPlatform/VMD/Camera1ProfileANY
// //onvif:RuleEngine/axis:VMD3/vmd3_video_1
// //onvif:Device/axis:Status/Temperature/Above
// //5623MT001/S13CAM03/event/tns:onvif/Device/tns:axis/Status/Temperature/Above
// //{"topic":"onvif:Device/axis:Status/Temperature/Above","timestamp":1720515011253,"message":{"source":{},"key":{},"data":{"sensor_level":"0"}}}
// //5623MT001/S13CAM03/event/tns:onvif/Device/tns:axis/Status/Temperature/Below
// //{"topic":"onvif:Device/axis:Status/Temperature/Below","timestamp":1720515011254,"message":{"source":{},"key":{},"data":{"sensor_level":"0"}}}
// //5623MT001/S13CAM03/event/tns:onvif/Device/tns:axis/Status/Temperature/Inside
// //{"topic":"onvif:Device/axis:Status/Temperature/Inside","timestamp":1720515011254,"message":{"source":{},"key":{},"data":{"sensor_level":"1"}}}
// AxisCamStatusMessage? axisCamStatusMessage = MQTTDeviceMessage.Deserialize<AxisCamStatusMessage>(Encoding.UTF8.GetString(args.ApplicationMessage.Payload), device, location);
// if (axisCamStatusMessage == null)
// {
// //LogError($"Axis cam Mqtt error - {BitConverter.ToString(args.ApplicationMessage.PayloadSegment.ToArray())}");
// LogError($"Axis cam Mqtt error - {Encoding.UTF8.GetString(args.ApplicationMessage.Payload)}");
// return Task.CompletedTask;
// }
// if (!_monitorHandler.TryGetDevice(device, out IMonitorDevice axisCam))
// {
// axisCam = new AxisCamMonitorDevice(_contextFactory, _telegramBot);
// _monitorHandler.AddDevice(device, axisCam);
// }
// using MonitorDbContext db = await _contextFactory.CreateDbContextAsync();
// await axisCam.Update(axisCamStatusMessage, db);
// await axisCam.SetConnectionState(true, db);
// await db.SaveChangesAsync();
// ((BaseMonitorDevice)axisCam).DeviceChangedEvent();
//}
}
}
public async Task RemoveLastWillClient(string topic)
{
Debug.WriteLine($"MQTT Service Remove Client {topic}");
if (_mqttClient != null)
{
await _mqttClient.PublishAsync(
new MqttApplicationMessageBuilder()
.WithTopic($"{topic}/event/connection")
.WithRetainFlag(true)
.Build()
);
await _mqttClient.PublishAsync(
new MqttApplicationMessageBuilder()
.WithTopic($"{topic}/status")
.WithRetainFlag(true)
.Build()
);
await _mqttClient.PublishAsync(
new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithRetainFlag(true)
.Build()
);
}
return Task.CompletedTask;
}
}
}

View File

@@ -1,33 +1,36 @@
using System;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace UCS_Status_Monitor.MQTT.Teltonika
{
public class Base
{
[JsonPropertyName("time")]
public int Time { get; set; }
public uint Time { get; set; }
public string UptimeString()
{
TimeSpan uptime = TimeSpan.FromSeconds(Time);
return $"{uptime.Days} days {uptime.Hours} hours {uptime.Minutes} min {uptime.Seconds} sec";
}
public TimeSpan UptimeValue()
{
return TimeSpan.FromSeconds(Time);
}
//public string UptimeString()
//{
// return UptimeString(DateTime.Now);
//}
//public string UptimeString(DateTime time)
//{
// TimeSpan uptime = TimeSpan.FromSeconds(Time) - time.TimeOfDay;
// return $"{uptime.Days} days {uptime.Hours} hours {uptime.Minutes} min {uptime.Seconds} sec";
//}
//public TimeSpan UptimeValue()
//{
// return TimeSpan.FromSeconds(Time);
//}
[JsonPropertyName("local_time")]
public string LocalTime { get; set; }
public string? LocalTime { get; set; }
[JsonPropertyName("fw")]
public string FirmwareVersion { get; set; }
public string? FirmwareVersion { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
public string? Name { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
public string? Id { get; set; }
}
}

View File

@@ -6,43 +6,43 @@ namespace UCS_Status_Monitor.MQTT.Teltonika
public class GSM
{
[JsonPropertyName("connstate")]
public string ConnState { get; set; }
public string? ConnState { get; set; }
[JsonPropertyName("psstate")]
public string PsState { get; set; }
public string? PsState { get; set; }
[JsonPropertyName("netstate")]
public string NetState { get; set; }
public string? NetState { get; set; }
[JsonPropertyName("imei")]
public string IMEI { get; set; }
public string? IMEI { get; set; }
[JsonPropertyName("iccid")]
public string IccId { get; set; }
public string? IccId { get; set; }
[JsonPropertyName("model")]
public string Model { get; set; }
public string? Model { get; set; }
[JsonPropertyName("manuf")]
public string Manufacturer { get; set; }
public string? Manufacturer { get; set; }
[JsonPropertyName("serial")]
public string Serial { get; set; }
public string? Serial { get; set; }
[JsonPropertyName("revision")]
public string Revision { get; set; }
public string? Revision { get; set; }
[JsonPropertyName("imsi")]
public string IMSI { get; set; }
public string? IMSI { get; set; }
[JsonPropertyName("simstate")]
public string SimState { get; set; }
public string? SimState { get; set; }
[JsonPropertyName("pinstate")]
public string PinState { get; set; }
public string? PinState { get; set; }
[JsonPropertyName("modemtime")]
public string ModemTime { get; set; }
public string? ModemTime { get; set; }
[JsonPropertyName("rssi")]
public int RSSI { get; set; }
@@ -63,50 +63,58 @@ namespace UCS_Status_Monitor.MQTT.Teltonika
public int RSRQ { get; set; }
[JsonPropertyName("cellid")]
public string CellId { get; set; }
public string? CellId { get; set; }
[JsonPropertyName("operator")]
public string Operator { get; set; }
public string? Operator { get; set; }
[JsonPropertyName("opernum")]
public int OperatorNumber { get; set; }
[JsonPropertyName("conntype")]
public string ConnType { get; set; }
public string? ConnType { get; set; }
[JsonPropertyName("temp")]
public int Temperature { get; set; }
public int? Temperature { get; set; }
public string TempString()
{
string temps = Temperature.ToString().Insert(2, ".");
float tempf = float.Parse(temps, CultureInfo.InvariantCulture); //use . separator
return $"{tempf}℃";
if (Temperature != null)
{
string temps = Temperature.ToString().Insert(2, ".");
float tempf = float.Parse(temps, CultureInfo.InvariantCulture); //use . separator
return $"{tempf}℃";
}
return "??℃";
}
public float TempValue()
{
string temps = Temperature.ToString().Insert(2, ".");
return float.Parse(temps, CultureInfo.InvariantCulture); //use . separator
if (Temperature != null)
{
string temps = Temperature.ToString().Insert(2, ".");
return float.Parse(temps, CultureInfo.InvariantCulture); //use . separator
}
return 0;
}
[JsonPropertyName("pincount")]
public int PinCount { get; set; }
[JsonPropertyName("network")]
public string Network { get; set; }
public string? Network { get; set; }
[JsonPropertyName("serving")]
public string Serving { get; set; }
public string? Serving { get; set; }
[JsonPropertyName("modem")]
public string Modem { get; set; }
public string? Modem { get; set; }
[JsonPropertyName("ip")]
public string[] IpV4 { get; set; }
public string[]? IpV4 { get; set; }
[JsonPropertyName("ipv6")]
public string[] IpV6 { get; set; }
public string[]? IpV6 { get; set; }
}
}

View File

@@ -1,26 +1,25 @@
using System.Text.Json.Serialization;
using System;
namespace UCS_Status_Monitor.MQTT.Teltonika
{
public class MNF
{
[JsonPropertyName("name")]
public string Name { get; set; }
public string? Name { get; set; }
[JsonPropertyName("serial")]
public string Serial { get; set; }
public string? Serial { get; set; }
[JsonPropertyName("mac")]
public string Mac { get; set; }
public string? Mac { get; set; }
[JsonPropertyName("maceth")]
public string MacEth { get; set; }
public string? MacEth { get; set; }
[JsonPropertyName("batch")]
public string Batch { get; set; }
public string? Batch { get; set; }
[JsonPropertyName("hwver")]
public string HardwareVersion { get; set; }
public string? HardwareVersion { get; set; }
}
}

View File

@@ -0,0 +1,53 @@
{
"Base": {
"time": 1732882033,
"local_time": "2024-11-29 13:07:13",
"fw": "RUT2_R_00.07.05",
"name": "S13ROUT01",
"id": "1"
},
"GSM": {
"connstate": "Connected",
"psstate": "attached",
"netstate": "Registered, home",
"imei": "864086069216152",
"iccid": "8931163200114870600F",
"model": "SLM750-VE",
"manuf": "Meiglink",
"serial": "750VE14LHD061614966",
"revision": "SLM750-V_4.57.20_EQ101",
"imsi": "204163600375610",
"simstate": "inserted",
"pinstate": "OK",
"modemtime": "24/11/29,12:06:54",
"rssi": -68,
"rscp": 0,
"ecio": 0,
"rsrp": -98,
"sinr": 4,
"rsrq": -11,
"cellid": "6594927",
"operator": "Odido Odido",
"opernum": 20416,
"conntype": "LTE",
"temp": 430,
"pincount": 3,
"network": "LTE,20416",
"serving": "5,LTE,FDD LTE,204,16",
"modem": "1-1",
"ip": [ "10.163.119.57" ],
"ipv6": []
},
"Usage": {
"tx": 324285533,
"rx": 240975943
},
"MNF": {
"name": "RUT2400DXXXX",
"serial": "6000777612",
"mac": "20972712A840",
"maceth": "20972712A841",
"batch": "0126",
"hwver": "0012"
}
}

View File

@@ -0,0 +1,45 @@
{
"Base": {
"time": 1732882214,
"local_time": "2024-11-29 13:10:14",
"fw": "RUT2_R_00.07.06.10",
"name": "R11ROUT01",
"id": "1"
},
"GSM": {
"connstate": "Connected",
"psstate": "attached",
"imei": "864431061231637",
"iccid": "8931163200118159331F",
"model": "SLM750-VE",
"manuf": "Meiglink",
"serial": "750VE14LHD101002311",
"revision": "SLM750-V_4.57.20_EQ101",
"imsi": "204163556707140",
"simstate": "inserted",
"pinstate": "OK",
"modemtime": "24/11/29,12:10:23",
"operator": "Odido Odido",
"opernum": 20416,
"conntype": "LTE",
"temp": 300,
"pincount": 3,
"network": "LTE,20416",
"serving": "3,LTE,FDD LTE,204,16",
"modem": "1-1",
"ip": [ "10.187.138.39" ],
"ipv6": []
},
"Usage": {
"tx": 159653562,
"rx": 124650070
},
"MNF": {
"name": "RUT2400DXXXX",
"serial": "1127218922",
"mac": "001E42586F09",
"maceth": "001E42586F0A",
"batch": "0114",
"hwver": "0011"
}
}

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,51 @@
{
"Base": {
"time": 1740057898,
"local_time": "2025-02-20 14:24:58",
"fw": "RUT2_R_00.07.06.17",
"name": "Base",
"id": "1"
},
"GSM": {
"connstate": "Connected",
"psstate": "attached",
"imei": "862757052517861",
"iccid": "8931163200123024074F",
"model": "EC25-EC",
"manuf": "Quectel",
"serial": "MPQ21L804036136",
"revision": "EC25ECGAR06A09M1G_01.001.01.001",
"imsi": "204163405381469",
"simstate": "inserted",
"pinstate": "OK",
"modemtime": "25/02/20,13:24:58",
"rssi": -69,
"rscp": 0,
"ecio": 0,
"rsrp": -105,
"sinr": 1,
"rsrq": -15,
"operator": "20416",
"opernum": 20416,
"conntype": "LTE",
"temp": 450,
"pincount": 3,
"network": "LTE,20416",
"serving": "3,LTE,FDD,204,16",
"modem": "1-1",
"ip": [ "178.225.40.3" ],
"ipv6": []
},
"Usage": {
"tx": 567987330,
"rx": 267378309
},
"MNF": {
"name": "RUT24006XXXX",
"serial": "1121899358",
"mac": "001E4244DF43",
"maceth": "001E4244DF44",
"batch": "0107",
"hwver": "0010"
}
}

View File

@@ -1,129 +1,105 @@
using System;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Telegram.Bot.Types;
//using System;
//using System.Globalization;
//using System.Text.Json;
//using System.Text.Json.Serialization;
//using UCS_Status_Monitor.Extensions;
namespace UCS_Status_Monitor.MQTT.Teltonika
{
public class TeltonikaMessage
{
//["Temp":"450","Uptime":"11561053","ThisMonthRX":"244716147","ThisMonthTX":"330139099","RSSI":"-61","LastMonthRX":"953029102","LastMonthTX":"499902102","WanIp":"178,224,90,9"]
//namespace UCS_Status_Monitor.MQTT.Teltonika
//{
// public class TeltonikaMessage
// {
// //["Temp":"450","Uptime":"11561053","ThisMonthRX":"244716147","ThisMonthTX":"330139099","RSSI":"-61","LastMonthRX":"953029102","LastMonthTX":"499902102","WanIp":"178,224,90,9"]
public static TeltonikaMessage Deserialize(string json, string device, string location)
{
try
{
json = json.Replace('[', '{');
json = json.Replace(']', '}');
TeltonikaMessage? message = JsonSerializer.Deserialize<TeltonikaMessage>(json, new JsonSerializerOptions()
{
NumberHandling = JsonNumberHandling.AllowReadingFromString
});
if (message != null)
{
message.Device = device;
message.Location = location;
}
return message;
}
catch (Exception)
{
return null;
}
}
// public static TeltonikaMessage Deserialize(string json, string device, string location)
// {
// try
// {
// json = json.Replace('[', '{');
// json = json.Replace(']', '}');
// TeltonikaMessage? message = JsonSerializer.Deserialize<TeltonikaMessage>(json, new JsonSerializerOptions()
// {
// NumberHandling = JsonNumberHandling.AllowReadingFromString
// });
// if (message != null)
// {
// message.Device = device;
// message.Location = location;
// }
// return message;
// }
// catch (Exception)
// {
// return null;
// }
// }
[JsonIgnore]
public string Device { get; set; }
// [JsonIgnore]
// public string Device { get; set; }
[JsonIgnore]
public string Location { get; set; }
// [JsonIgnore]
// public string Location { get; set; }
private float _temp;
public string Temp
{
get
{
return $"{_temp}℃";
}
set
{
string temp = value.Insert(2, ".");
_temp = float.Parse(temp, CultureInfo.InvariantCulture); //use . separator
}
}
public float TempValue()
{
return _temp;
}
// private float _temp;
// public string Temp
// {
// get
// {
// return $"{_temp}℃";
// }
// set
// {
// string temp = value.Insert(2, ".");
// _temp = float.Parse(temp, CultureInfo.InvariantCulture); //use . separator
// }
// }
// public float TempValue()
// {
// return _temp;
// }
private TimeSpan _uptime;
public string Uptime
{
get
{
return $"{_uptime.Days} days {_uptime.Hours} hours {_uptime.Minutes} min {_uptime.Seconds} sec";
}
set
{
_uptime = TimeSpan.FromSeconds(uint.Parse(value));
}
}
public TimeSpan UptimeValue()
{
return _uptime;
}
// private TimeSpan _uptime;
// public string Uptime
// {
// get
// {
// return _uptime.GetUptime();
// }
// set
// {
// _uptime = TimeSpan.FromSeconds(uint.Parse(value));
// }
// }
// public TimeSpan UptimeValue()
// {
// return _uptime;
// }
//value / 1000000 = MB
public uint ThisMonthRX { get; set; }
// //value / 1000000 = MB
// public uint ThisMonthRX { get; set; }
//value / 1000000 = MB
public uint ThisMonthTX { get; set; }
// //value / 1000000 = MB
// public uint ThisMonthTX { get; set; }
//value in dBm
public int RSSI { get; set; }
// //value in dBm
// public int RSSI { get; set; }
//value / 1000000 = MB
public uint LastMonthRX { get; set; }
// //value / 1000000 = MB
// public uint LastMonthRX { get; set; }
//value / 1000000 = MB
public uint LastMonthTX { get; set; }
// //value / 1000000 = MB
// public uint LastMonthTX { get; set; }
private string _wanIP;
public string WanIp
{
get
{
return _wanIP;
}
set
{
_wanIP = value.Replace(',', '.');
}
}
//public override string ToString()
//{
// var sb = new StringBuilder();
// sb.Append($"Temp = {Temp}");
// sb.Append(Environment.NewLine);
// sb.Append($"Uptime = {Uptime}");
// sb.Append(Environment.NewLine);
// sb.Append($"ThisMonthRX = {ThisMonthRX}");
// sb.Append(Environment.NewLine);
// sb.Append($"ThisMonthTX = {ThisMonthTX}");
// sb.Append(Environment.NewLine);
// sb.Append($"RSSI = {RSSI} dBm");
// sb.Append(Environment.NewLine);
// sb.Append($"LastMonthRX = {LastMonthRX}");
// sb.Append(Environment.NewLine);
// sb.Append($"LastMonthTX = {LastMonthTX}");
// sb.Append(Environment.NewLine);
// sb.Append($"WanIp = {WanIp}");
// return sb.ToString();
//}
}
}
// private string _wanIP;
// public string WanIp
// {
// get
// {
// return _wanIP;
// }
// set
// {
// _wanIP = value.Replace(',', '.');
// }
// }
// }
//}

View File

@@ -1,11 +1,6 @@
using System.Text.Json;
using System;
using System.Diagnostics;
using System.Text.Json.Serialization;
namespace UCS_Status_Monitor.MQTT.Teltonika
namespace UCS_Status_Monitor.MQTT.Teltonika
{
public class TeltonikaMessageV2
public class TeltonikaMessageV2 : MQTTDeviceMessage
{
//{"Base":{
// "time":1722521441,
@@ -61,59 +56,9 @@ namespace UCS_Status_Monitor.MQTT.Teltonika
//}}
public static TeltonikaMessageV2 Deserialize(string json, string device, string location)
{
try
{
//Debug.WriteLine(json);
TeltonikaMessageV2? message = JsonSerializer.Deserialize<TeltonikaMessageV2>(json, new JsonSerializerOptions()
{
NumberHandling = JsonNumberHandling.AllowReadingFromString,
PropertyNameCaseInsensitive = false,
});
if (message != null)
{
message.Device = device;
message.Location = location;
}
return message;
}
catch (Exception ex)
{
Debug.WriteLine($"TeltonikaMessageV2: {ex.Message}");
return null;
}
}
[JsonIgnore]
public string Device { get; set; }
[JsonIgnore]
public string Location { get; set; }
public Base Base { get; set; }
public GSM GSM { get; set; }
public Usage Usage { get; set; }
public MNF MNF { get; set; }
////value / 1000000 = MB
//public UInt32 ThisMonthRX { get; set; }
////value / 1000000 = MB
//public UInt32 ThisMonthTX { get; set; }
////value in dBm
//public Int32 RSSI { get; set; }
////value / 1000000 = MB
//public UInt32 LastMonthRX { get; set; }
////value / 1000000 = MB
//public UInt32 LastMonthTX { get; set; }
public Base? Base { get; set; }
public GSM? GSM { get; set; }
public Usage? Usage { get; set; }
public MNF? MNF { get; set; }
}
}

View File

@@ -1,13 +1,14 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;
namespace UCS_Status_Monitor.MQTT.Teltonika
{
public class Usage
{
[JsonPropertyName("tx")]
public int Tx { get; set; }
public UInt64 Tx { get; set; }
[JsonPropertyName("rx")]
public int Rx { get; set; }
public UInt64 Rx { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Diagnostics.Metrics;
namespace UCS_Status_Monitor.Metrics
{
public class ControllerMetrics
{
private readonly Histogram<double> _requestTimeHistogram;
public ControllerMetrics(IMeterFactory meterFactory)
{
using var meter = meterFactory.Create("SDN_Status_Monitor");
_requestTimeHistogram = meter.CreateHistogram<double>(name: "Controller.RequestTime", unit: "ms", description: "Process time for each controller request");
}
public void RequestTime(string url, double elapsedMilliseconds)
{
_requestTimeHistogram.Record(elapsedMilliseconds, new KeyValuePair<string, object?>("url", url));
}
}
}

View File

@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;
namespace UCS_Status_Monitor.Metrics
{
public sealed class LogRequestTimeActionFilter(ControllerMetrics controllerMetrics) : IActionFilter
{
readonly Stopwatch _stopwatch = new();
private readonly ControllerMetrics _controllerMetrics = controllerMetrics;
public void OnActionExecuting(ActionExecutingContext context) => _stopwatch.Start();
public void OnActionExecuted(ActionExecutedContext context)
{
_stopwatch.Stop();
Debug.WriteLine($"Request Time metric - {_stopwatch.Elapsed.TotalMilliseconds} ms - {context.HttpContext.Request.GetDisplayUrl()}");
_controllerMetrics.RequestTime(context.HttpContext.Request.GetDisplayUrl(), _stopwatch.Elapsed.TotalMilliseconds);
}
}
}

View File

@@ -0,0 +1,37 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Metrics;
using System.Threading;
namespace UCS_Status_Monitor.Metrics
{
public static class MetricsExtension
{
/// <summary>
/// Enables console output for metrics for debugging purposes. This is not recommended for production use.
/// </summary>
/// <param name="builder">The metrics builder.</param>
/// <returns>The original metrics builder for chaining.</returns>
//public static IMetricsBuilder AddEFCoreMetrics(this IMetricsBuilder builder) => builder.AddListener<DebugConsoleMetricListener>();
//public static void AddEFCoreMetrics(this IMetricsBuilder builder)
//{
// //builder.AddListener<HangfireMetricsListener>(); //register a listener for Hangfire
// //builder.EnableMetrics("Hangfire", "enqueued-queues:count", null, MeterScope.Global);
//}
public static void AddMetricsListener(this IServiceCollection services, CancellationToken token)
{
services.AddSingleton<ControllerMetrics>();
services.AddControllers(options => options.Filters.Add<LogRequestTimeActionFilter>());
//services.AddControllers(options => options.Filters.Add<LogAuthorizationFilterAttribute>());
//services.AddSingleton<AperioMetrics>();
//services.AddSingleton<EFCoreMetrics>();
//services.AddHostedService<MetricsBackgroundService>();
}
}
}

View File

@@ -0,0 +1,390 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using UCS_Status_Monitor.Database;
#nullable disable
namespace UCS_Status_Monitor.Migrations
{
[DbContext(typeof(MonitorDbContext))]
[Migration("20241129135901_Add_loggings")]
partial class Add_loggings
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.10");
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.AxisCam", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Connected")
.HasColumnType("INTEGER");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Device")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Location")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SerialNumber")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("SystemReady")
.HasColumnType("INTEGER");
b.Property<string>("Temperature")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("Timestamp")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("AxisCams", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.EventLogError", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("Index")
.HasColumnType("INTEGER");
b.Property<string>("Message")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("TimeGenerated")
.HasColumnType("TEXT");
b.Property<int>("UCSSystemId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("UCSSystemId");
b.ToTable("Errors", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Logging", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int?>("AxisCamId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Date")
.HasColumnType("TEXT");
b.Property<int?>("RouterId")
.HasColumnType("INTEGER");
b.Property<bool>("State")
.HasColumnType("INTEGER");
b.Property<int?>("UCSSystemId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("AxisCamId");
b.HasIndex("RouterId");
b.HasIndex("UCSSystemId");
b.ToTable("Loggings", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Router", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Connected")
.HasColumnType("INTEGER");
b.Property<string>("Device")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("FirmwareVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Location")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("RSSI")
.HasColumnType("INTEGER");
b.Property<float>("Temperature")
.HasColumnType("REAL");
b.Property<uint>("ThisMonthRX")
.HasColumnType("INTEGER");
b.Property<uint>("ThisMonthTX")
.HasColumnType("INTEGER");
b.Property<DateTime>("Timestamp")
.HasColumnType("TEXT");
b.Property<string>("WanIp")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Routers", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Sensor", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ComputerName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Configfile")
.IsRequired()
.HasColumnType("TEXT");
b.Property<long>("Count")
.HasColumnType("INTEGER");
b.Property<DateTime>("Date")
.HasColumnType("TEXT");
b.Property<string>("TxData")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("TxString")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UCSId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Sensors", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSDevice", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("BoxID")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("LastStateChange")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("State")
.HasColumnType("INTEGER");
b.Property<int>("UCSSystemId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("UCSSystemId");
b.ToTable("UCSDevices", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSSystem", b =>
{
b.Property<int>("UCSSystemId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AxisVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("BIOSVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("BoschVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ComputerModel")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ComputerName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ConfigFileName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("ConnectionState")
.HasColumnType("INTEGER");
b.Property<string>("DotNetVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("LastMessageClient")
.HasColumnType("TEXT");
b.Property<DateTime>("LastMessageTime")
.HasColumnType("TEXT");
b.Property<string>("Monitors")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OSCaption")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OSVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("PhysicalMemory")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProcessorName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("StartTime")
.HasColumnType("TEXT");
b.Property<string>("SystemUptime")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UCSVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("USBDisks")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Uptime")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("VideoController")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("UCSSystemId");
b.HasIndex("ComputerName");
b.ToTable("UCSSystems", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.EventLogError", b =>
{
b.HasOne("UCS_Status_Monitor.Models.Database.UCSSystem", "UCSSystem")
.WithMany("Errors")
.HasForeignKey("UCSSystemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("UCSSystem");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Logging", b =>
{
b.HasOne("UCS_Status_Monitor.Models.Database.AxisCam", "AxisCam")
.WithMany("Loggings")
.HasForeignKey("AxisCamId");
b.HasOne("UCS_Status_Monitor.Models.Database.Router", "Router")
.WithMany("Loggings")
.HasForeignKey("RouterId");
b.HasOne("UCS_Status_Monitor.Models.Database.UCSSystem", "UCSSystem")
.WithMany("Loggings")
.HasForeignKey("UCSSystemId");
b.Navigation("AxisCam");
b.Navigation("Router");
b.Navigation("UCSSystem");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSDevice", b =>
{
b.HasOne("UCS_Status_Monitor.Models.Database.UCSSystem", "UCSSystem")
.WithMany("Devices")
.HasForeignKey("UCSSystemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("UCSSystem");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.AxisCam", b =>
{
b.Navigation("Loggings");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Router", b =>
{
b.Navigation("Loggings");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSSystem", b =>
{
b.Navigation("Devices");
b.Navigation("Errors");
b.Navigation("Loggings");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,151 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace UCS_Status_Monitor.Migrations
{
/// <inheritdoc />
public partial class Add_loggings : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Loggings_UCSSystems_UCSSystemId",
table: "Loggings");
migrationBuilder.DropColumn(
name: "LastMonthRX",
table: "Routers");
migrationBuilder.DropColumn(
name: "LastMonthTX",
table: "Routers");
migrationBuilder.RenameColumn(
name: "Uptime",
table: "Routers",
newName: "FirmwareVersion");
migrationBuilder.AlterColumn<int>(
name: "UCSSystemId",
table: "Loggings",
type: "INTEGER",
nullable: true,
oldClrType: typeof(int),
oldType: "INTEGER");
migrationBuilder.AddColumn<int>(
name: "AxisCamId",
table: "Loggings",
type: "INTEGER",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "RouterId",
table: "Loggings",
type: "INTEGER",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Loggings_AxisCamId",
table: "Loggings",
column: "AxisCamId");
migrationBuilder.CreateIndex(
name: "IX_Loggings_RouterId",
table: "Loggings",
column: "RouterId");
migrationBuilder.AddForeignKey(
name: "FK_Loggings_AxisCams_AxisCamId",
table: "Loggings",
column: "AxisCamId",
principalTable: "AxisCams",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Loggings_Routers_RouterId",
table: "Loggings",
column: "RouterId",
principalTable: "Routers",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Loggings_UCSSystems_UCSSystemId",
table: "Loggings",
column: "UCSSystemId",
principalTable: "UCSSystems",
principalColumn: "UCSSystemId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Loggings_AxisCams_AxisCamId",
table: "Loggings");
migrationBuilder.DropForeignKey(
name: "FK_Loggings_Routers_RouterId",
table: "Loggings");
migrationBuilder.DropForeignKey(
name: "FK_Loggings_UCSSystems_UCSSystemId",
table: "Loggings");
migrationBuilder.DropIndex(
name: "IX_Loggings_AxisCamId",
table: "Loggings");
migrationBuilder.DropIndex(
name: "IX_Loggings_RouterId",
table: "Loggings");
migrationBuilder.DropColumn(
name: "AxisCamId",
table: "Loggings");
migrationBuilder.DropColumn(
name: "RouterId",
table: "Loggings");
migrationBuilder.RenameColumn(
name: "FirmwareVersion",
table: "Routers",
newName: "Uptime");
migrationBuilder.AddColumn<uint>(
name: "LastMonthRX",
table: "Routers",
type: "INTEGER",
nullable: false,
defaultValue: 0u);
migrationBuilder.AddColumn<uint>(
name: "LastMonthTX",
table: "Routers",
type: "INTEGER",
nullable: false,
defaultValue: 0u);
migrationBuilder.AlterColumn<int>(
name: "UCSSystemId",
table: "Loggings",
type: "INTEGER",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "INTEGER",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_Loggings_UCSSystems_UCSSystemId",
table: "Loggings",
column: "UCSSystemId",
principalTable: "UCSSystems",
principalColumn: "UCSSystemId",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@@ -0,0 +1,394 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using UCS_Status_Monitor.Database;
#nullable disable
namespace UCS_Status_Monitor.Migrations
{
[DbContext(typeof(MonitorDbContext))]
[Migration("20250501063851_AddUCSDeviceMessage")]
partial class AddUCSDeviceMessage
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.4");
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.AxisCam", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Connected")
.HasColumnType("INTEGER");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Device")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Location")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SerialNumber")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("SystemReady")
.HasColumnType("INTEGER");
b.Property<string>("Temperature")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("Timestamp")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("AxisCams", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.EventLogError", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("Index")
.HasColumnType("INTEGER");
b.Property<string>("Message")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("TimeGenerated")
.HasColumnType("TEXT");
b.Property<int>("UCSSystemId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("UCSSystemId");
b.ToTable("Errors", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Logging", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int?>("AxisCamId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Date")
.HasColumnType("TEXT");
b.Property<int?>("RouterId")
.HasColumnType("INTEGER");
b.Property<bool>("State")
.HasColumnType("INTEGER");
b.Property<int?>("UCSSystemId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("AxisCamId");
b.HasIndex("RouterId");
b.HasIndex("UCSSystemId");
b.ToTable("Loggings", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Router", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Connected")
.HasColumnType("INTEGER");
b.Property<string>("Device")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("FirmwareVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Location")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("RSSI")
.HasColumnType("INTEGER");
b.Property<float>("Temperature")
.HasColumnType("REAL");
b.Property<uint>("ThisMonthRX")
.HasColumnType("INTEGER");
b.Property<uint>("ThisMonthTX")
.HasColumnType("INTEGER");
b.Property<DateTime>("Timestamp")
.HasColumnType("TEXT");
b.Property<string>("WanIp")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Routers", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Sensor", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ComputerName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Configfile")
.IsRequired()
.HasColumnType("TEXT");
b.Property<long>("Count")
.HasColumnType("INTEGER");
b.Property<DateTime>("Date")
.HasColumnType("TEXT");
b.Property<string>("TxData")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("TxString")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UCSId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Sensors", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSDevice", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("BoxID")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("LastStateChange")
.HasColumnType("TEXT");
b.Property<string>("Message")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("State")
.HasColumnType("INTEGER");
b.Property<int>("UCSSystemId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("UCSSystemId");
b.ToTable("UCSDevices", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSSystem", b =>
{
b.Property<int>("UCSSystemId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AxisVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("BIOSVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("BoschVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ComputerModel")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ComputerName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ConfigFileName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("ConnectionState")
.HasColumnType("INTEGER");
b.Property<string>("DotNetVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("LastMessageClient")
.HasColumnType("TEXT");
b.Property<DateTime>("LastMessageTime")
.HasColumnType("TEXT");
b.Property<string>("Monitors")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OSCaption")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OSVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("PhysicalMemory")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProcessorName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("StartTime")
.HasColumnType("TEXT");
b.Property<string>("SystemUptime")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UCSVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("USBDisks")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Uptime")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("VideoController")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("UCSSystemId");
b.HasIndex("ComputerName");
b.ToTable("UCSSystems", (string)null);
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.EventLogError", b =>
{
b.HasOne("UCS_Status_Monitor.Models.Database.UCSSystem", "UCSSystem")
.WithMany("Errors")
.HasForeignKey("UCSSystemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("UCSSystem");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Logging", b =>
{
b.HasOne("UCS_Status_Monitor.Models.Database.AxisCam", "AxisCam")
.WithMany("Loggings")
.HasForeignKey("AxisCamId");
b.HasOne("UCS_Status_Monitor.Models.Database.Router", "Router")
.WithMany("Loggings")
.HasForeignKey("RouterId");
b.HasOne("UCS_Status_Monitor.Models.Database.UCSSystem", "UCSSystem")
.WithMany("Loggings")
.HasForeignKey("UCSSystemId");
b.Navigation("AxisCam");
b.Navigation("Router");
b.Navigation("UCSSystem");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSDevice", b =>
{
b.HasOne("UCS_Status_Monitor.Models.Database.UCSSystem", "UCSSystem")
.WithMany("Devices")
.HasForeignKey("UCSSystemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("UCSSystem");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.AxisCam", b =>
{
b.Navigation("Loggings");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Router", b =>
{
b.Navigation("Loggings");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSSystem", b =>
{
b.Navigation("Devices");
b.Navigation("Errors");
b.Navigation("Loggings");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace UCS_Status_Monitor.Migrations
{
/// <inheritdoc />
public partial class AddUCSDeviceMessage : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Message",
table: "UCSDevices",
type: "TEXT",
nullable: false,
defaultValue: "");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Message",
table: "UCSDevices");
}
}
}

View File

@@ -15,7 +15,7 @@ namespace UCS_Status_Monitor.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.7");
modelBuilder.HasAnnotation("ProductVersion", "9.0.5");
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.AxisCam", b =>
{
@@ -89,17 +89,27 @@ namespace UCS_Status_Monitor.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int?>("AxisCamId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Date")
.HasColumnType("TEXT");
b.Property<int?>("RouterId")
.HasColumnType("INTEGER");
b.Property<bool>("State")
.HasColumnType("INTEGER");
b.Property<int>("UCSSystemId")
b.Property<int?>("UCSSystemId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("AxisCamId");
b.HasIndex("RouterId");
b.HasIndex("UCSSystemId");
b.ToTable("Loggings", (string)null);
@@ -118,11 +128,9 @@ namespace UCS_Status_Monitor.Migrations
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("LastMonthRX")
.HasColumnType("INTEGER");
b.Property<uint>("LastMonthTX")
.HasColumnType("INTEGER");
b.Property<string>("FirmwareVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Location")
.IsRequired()
@@ -143,9 +151,6 @@ namespace UCS_Status_Monitor.Migrations
b.Property<DateTime>("Timestamp")
.HasColumnType("TEXT");
b.Property<TimeSpan>("Uptime")
.HasColumnType("TEXT");
b.Property<string>("WanIp")
.IsRequired()
.HasColumnType("TEXT");
@@ -205,6 +210,10 @@ namespace UCS_Status_Monitor.Migrations
b.Property<DateTime>("LastStateChange")
.HasColumnType("TEXT");
b.Property<string>("Message")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
@@ -328,11 +337,21 @@ namespace UCS_Status_Monitor.Migrations
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Logging", b =>
{
b.HasOne("UCS_Status_Monitor.Models.Database.AxisCam", "AxisCam")
.WithMany("Loggings")
.HasForeignKey("AxisCamId");
b.HasOne("UCS_Status_Monitor.Models.Database.Router", "Router")
.WithMany("Loggings")
.HasForeignKey("RouterId");
b.HasOne("UCS_Status_Monitor.Models.Database.UCSSystem", "UCSSystem")
.WithMany("Loggings")
.HasForeignKey("UCSSystemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("UCSSystemId");
b.Navigation("AxisCam");
b.Navigation("Router");
b.Navigation("UCSSystem");
});
@@ -348,6 +367,16 @@ namespace UCS_Status_Monitor.Migrations
b.Navigation("UCSSystem");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.AxisCam", b =>
{
b.Navigation("Loggings");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.Router", b =>
{
b.Navigation("Loggings");
});
modelBuilder.Entity("UCS_Status_Monitor.Models.Database.UCSSystem", b =>
{
b.Navigation("Devices");

View File

@@ -1,25 +0,0 @@
using System;
namespace UCS_Status_Monitor.Models
{
public class CameraTableModel
{
public string TableColor { get; set; } = string.Empty;
public string Device { get; set; } = string.Empty;
public string Location { get; set; } = string.Empty;
public string SerialNumber { get; set; } = string.Empty;
public string Timestamp { get; set; } = string.Empty;
public bool Connected { get; set; }
public string Description { get; set; } = string.Empty;
public bool SystemReady { get; set; }
public string Temperature { get; set; } = string.Empty;
}
}

View File

@@ -1,20 +1,22 @@
using System;
using System.Text.Json;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using System.Text.Json.Serialization;
namespace UCS_Status_Monitor.Models
{
{
//DataContract for Serializing Data - required to serve in JSON format
[DataContract]
public class ChartModel
{
private readonly JsonSerializerOptions _options;
public ChartModel()
{
Data = new List<int>();
Labels = new List<DateTime>();
Data = [];
Labels = [];
_options = new();
_options.Converters.Add(new CustomDateTimeConverter("d-M-y H:mm"));
}
public List<int> Data { get; private set; }
@@ -26,7 +28,22 @@ namespace UCS_Status_Monitor.Models
public List<DateTime> Labels { get; private set; }
public string GetLabelsString()
{
return JsonSerializer.Serialize(this.Labels);
return JsonSerializer.Serialize(this.Labels, _options);
}
}
public class CustomDateTimeConverter(string format) : JsonConverter<DateTime>
{
private readonly string _format = format;
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.ParseExact(reader.GetString(), _format, null);
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString(_format));
}
}
}

View File

@@ -1,23 +1,53 @@
using System.ComponentModel.DataAnnotations;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using UCS_Status_Monitor.Monitor;
using UCS_Status_Monitor.MQTT.Axis;
namespace UCS_Status_Monitor.Models.Database
{
public class AxisCam
{
public void Update(AxisCamConnectionMessage message)
public AxisCam() { }
public AxisCam(AxisCamConnectionMessage message)
{
Location = message.Location;
Device = message.Device;
SerialNumber = message.SerialNumber;
Timestamp = message.Timestamp;
Connected = message.Connected;
Description = message.Description;
//Debug.WriteLine($"Axis timestamp {Timestamp.FormatDateTime()}");
Update(message);
}
public AxisCam(AxisCamStatusMessage message)
{
Update(message);
}
public void Update(AxisCamConnectionMessage message)
{
ArgumentNullException.ThrowIfNull(message);
Location = message.Location ?? "??";
Device = message.Device ?? "??";
SerialNumber = message.SerialNumber ?? "";
Timestamp = message.Timestamp ?? DateTime.MinValue;
Connected = message.Connected;
Description = message.Description ?? "";
//SystemReady = true;
//Temperature = "??";
}
public void Update(AxisCamStatusMessage message)
{
ArgumentNullException.ThrowIfNull(message);
Location = message.Location ?? "??";
Device = message.Device ?? "??";
SerialNumber = message.SerialNumber ?? "";
//Timestamp = message.Timestamp ?? DateTime.MinValue;
//Connected = message.Connected;
//Description = message.Description ?? "";
//SystemReady = true;
//Temperature = "??";
}
[Key]
public int Id { get; set; }
[Display(Name = "Location")]
@@ -43,5 +73,10 @@ namespace UCS_Status_Monitor.Models.Database
[Display(Name = "Temperature")]
public string Temperature { get; set; } = string.Empty;
public ICollection<Logging> Loggings { get; set; } = [];
[NotMapped]
public AxisCamMonitorDevice? MonitorDevice { get; set; }
}
}

View File

@@ -6,6 +6,7 @@ namespace UCS_Status_Monitor.Models.Database
{
public class EventLogError
{
[Key]
public int Id { get; set; }
[Display(Name = "Log index")]
@@ -15,9 +16,10 @@ namespace UCS_Status_Monitor.Models.Database
public DateTime TimeGenerated { get; set; }
[Display(Name = "Message")]
public string Message { get; set; }
public string Message { get; set; } = string.Empty;
[ForeignKey("UCSSystemId")]
public virtual UCSSystem UCSSystem { get; set; }
[Required]
public UCSSystem UCSSystem { get; set; }
}
}

View File

@@ -6,6 +6,7 @@ namespace UCS_Status_Monitor.Models.Database
{
public class Logging
{
[Key]
public int Id { get; set; }
[Display(Name = "Log date")]
@@ -14,7 +15,17 @@ namespace UCS_Status_Monitor.Models.Database
[Display(Name = "System connection")]
public bool State { get; set; }
//[ForeignKey("UCSSystemId")]
//[Required]
//public virtual UCSSystem UCSSystem { get; set; }
[ForeignKey("UCSSystemId")]
public virtual UCSSystem UCSSystem { get; set; }
public UCSSystem? UCSSystem { get; set; }
[ForeignKey("AxisCamId")]
public AxisCam? AxisCam { get; set; }
[ForeignKey("RouterId")]
public Router? Router { get; set; }
}
}

View File

@@ -1,7 +1,9 @@
using System.ComponentModel.DataAnnotations;
using System;
using Telegram.Bot.Types;
using UCS_Status_Monitor.MQTT.Teltonika;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using UCS_Status_Monitor.Monitor;
namespace UCS_Status_Monitor.Models.Database
{
@@ -9,115 +11,73 @@ namespace UCS_Status_Monitor.Models.Database
{
public Router() { }
public void Update(TeltonikaMessage message)
public Router(TeltonikaMessageV2 message)
{
Location = message.Location;
Device = message.Device;
Temperature = message.TempValue();
Uptime = message.UptimeValue();
ThisMonthRX = message.ThisMonthRX;
ThisMonthTX = message.ThisMonthTX;
LastMonthRX = message.LastMonthRX;
LastMonthTX = message.LastMonthTX;
RSSI = message.RSSI;
WanIp = message.WanIp;
Timestamp = DateTime.Now;
Update(message);
}
public void Update(TeltonikaMessageV2 message)
{
Location = message.Location;
Device = message.Device;
Temperature = message.GSM.TempValue();
//Uptime = teltonikaMessage.UptimeValue(),
//ThisMonthRX = teltonikaMessage.ThisMonthRX,
//ThisMonthTX = teltonikaMessage.ThisMonthTX,
//LastMonthRX = teltonikaMessage.LastMonthRX,
//LastMonthTX = teltonikaMessage.LastMonthTX,
RSSI = message.GSM.RSSI;
WanIp = message.GSM.IpV4[0];
ArgumentNullException.ThrowIfNull(message);
Location = message.Location ?? "??";
Device = message.Device ?? "??";
if (message.GSM != null)
{
Temperature = message.GSM.TempValue();
RSSI = message.GSM.RSSI;
WanIp = message.GSM.IpV4?[0] ?? "??";
}
if (message.Usage != null)
{
ThisMonthRX = (uint)message.Usage.Rx;
ThisMonthTX = (uint)message.Usage.Tx;
}
Timestamp = DateTime.Now;
FirmwareVersion = message.Base?.FirmwareVersion ?? "??";
}
public string GetTemperature()
{
return $"{Temperature}℃";
}
public string GetUptime()
{
return $"{Uptime.Days} days {Uptime.Hours} hours {Uptime.Minutes} min {Uptime.Seconds} sec";
}
public string GetThisMonthRX()
{
//return $"{ThisMonthRX / 1000000} MB";
return $"{ThisMonthRX / 1048576} MB";
}
public string GetThisMonthTX()
{
//return $"{ThisMonthTX / 1000000} MB";
return $"{ThisMonthTX / 1048576} MB";
}
public string ThisMonthTotal()
{
//return $"{(ThisMonthTX + ThisMonthRX) / 1000000} MB";
return $"{(ThisMonthTX + ThisMonthRX) / 1048576} MB";
}
public string GetRSSI()
{
return $"{RSSI} dBm";
}
public string GetLastMonthRX()
{
//return $"{LastMonthRX / 1000000} MB";
return $"{LastMonthRX / 1048576} MB";
}
public string GetLastMonthTX()
{
//return $"{LastMonthTX / 1000000} MB";
return $"{LastMonthTX / 1048576} MB";
}
public string LastMonthTotal()
{
//return $"{(LastMonthRX + LastMonthTX) / 1000000} MB";
return $"{(LastMonthRX + LastMonthTX) / 1048576} MB";
}
[Key]
public int Id { get; set; }
[Display(Name = "Location")]
public string Location { get; set; }
public string Location { get; set; } = string.Empty;
[Display(Name = "Device")]
public string Device { get; set; }
public string Device { get; set; } = string.Empty;
[Display(Name = "Temperature")]
public float Temperature { get; set; }
[Display(Name = "Uptime")]
public TimeSpan Uptime { get; set; }
[Display(Name = "This month rx")]
public UInt32 ThisMonthRX { get; set; }
public UInt64 ThisMonthRX { get; set; }
[Display(Name = "This month tx")]
public UInt32 ThisMonthTX { get; set; }
[Display(Name = "Last month rx")]
public UInt32 LastMonthRX { get; set; }
[Display(Name = "Last month tx")]
public UInt32 LastMonthTX { get; set; }
public UInt64 ThisMonthTX { get; set; }
[Display(Name = "RSSI")]
public Int32 RSSI { get; set; }
[Display(Name = "Wan ip address")]
public string WanIp { get; set; }
public string WanIp { get; set; } = string.Empty;
[Display(Name = "Timestamp")]
public DateTime Timestamp { get; set; }
[Display(Name = "Connected")]
public bool Connected { get; set; }
[Display(Name = "Firmware version")]
public string FirmwareVersion { get; set; } = string.Empty;
public ICollection<Logging> Loggings { get; } = [];
[NotMapped]
public RouterMonitorDevice? MonitorDevice { get; set; }
}
}

View File

@@ -1,46 +1,33 @@
using UCS_Status_Monitor.Sensors;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using System;
namespace UCS_Status_Monitor.Models.Database
{
[Obsolete("Old UCS sensors")]
public class Sensor
{
public Sensor() { }
public Sensor(SensorPacket sensor)
{
Date = sensor.Date;
ComputerName = sensor.ComputerName ?? "??";
Configfile = sensor.Configfile ?? "??";
UCSId = sensor.UCSId ?? "??";
TxString = sensor.TxString ?? "??";
TxData = sensor.TxData ?? "??";
if (sensor.Count.HasValue)
{
Count = sensor.Count.Value;
}
}
[Key]
public int Id { get; set; }
[Display(Name = "Date")]
public DateTime Date { get; set; }
[Display(Name = "Computer name")]
public string ComputerName { get; set; }
public string ComputerName { get; set; } = string.Empty;
[Display(Name = "Configfile")]
public string Configfile { get; set; }
public string Configfile { get; set; } = string.Empty;
[Display(Name = "UCS id")]
public string UCSId { get; set; }
public string UCSId { get; set; } = string.Empty;
[Display(Name = "Tx String")]
public string TxString { get; set; }
public string TxString { get; set; } = string.Empty;
[Display(Name = "Tx Data")]
public string TxData { get; set; }
public string TxData { get; set; } = string.Empty;
[Display(Name = "Message number")]
public Int64 Count { get; set; }

View File

@@ -6,20 +6,25 @@ namespace UCS_Status_Monitor.Models.Database
{
public class UCSDevice
{
[Key]
public int Id { get; set; }
[Display(Name = "Name")]
public string Name { get; set; }
public string Name { get; set; } = string.Empty;
[Display(Name = "Box ID")]
public string BoxID { get; set; }
public string BoxID { get; set; } = string.Empty;
public Boolean State { get; set; }
[Display(Name = "Message")]
public string Message { get; set; } = string.Empty;
[Display(Name = "Last message date")]
public DateTime LastStateChange { get; set; }
[ForeignKey("UCSSystemId")]
public virtual UCSSystem UCSSystem { get; set; }
[Required]
public UCSSystem UCSSystem { get; set; }
}
}

View File

@@ -1,7 +1,9 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using System;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Globalization;
using UCS_Status_Monitor.Extensions;
namespace UCS_Status_Monitor.Models.Database
@@ -18,11 +20,16 @@ namespace UCS_Status_Monitor.Models.Database
public void Update(Telemetry.TelemetryPacket telemetry)
{
ComputerName = telemetry.ComputerName;
ArgumentNullException.ThrowIfNull(telemetry);
ComputerName = telemetry.ComputerName ?? "??";
LastMessageTime = DateTime.Now;
ConnectionState = true;
StartTime = telemetry.StartTime != null ? DateTime.Parse(telemetry.StartTime) : DateTime.MinValue;
LastMessageClient = telemetry.Date != null ? DateTime.Parse(telemetry.Date) : DateTime.MinValue;
StartTime = telemetry.StartTime.ParseDeviceTime();
LastMessageClient = telemetry.Date.ParseDeviceTime();
ConfigFileName = telemetry.ConfigFileName ?? "??";
Uptime = telemetry.Uptime ?? "??";
SystemUptime = telemetry.SystemUptime ?? "??";
@@ -85,13 +92,13 @@ namespace UCS_Status_Monitor.Models.Database
}
}
[Key]
public int UCSSystemId { get; set; }
public bool ConnectionState { get; set; }
[Display(Name = "System")]
public string ComputerName { get; set; }
public string ComputerName { get; set; } = string.Empty;
[Display(Name = "UCS start date")]
public DateTime StartTime { get; set; }
@@ -103,58 +110,58 @@ namespace UCS_Status_Monitor.Models.Database
public DateTime LastMessageClient { get; set; }
[Display(Name = "UCS uptime")]
public string Uptime { get; set; }
public string Uptime { get; set; } = string.Empty;
[Display(Name = "System uptime")]
public string SystemUptime { get; set; }
public string SystemUptime { get; set; } = string.Empty;
[Display(Name = "System model")]
public string ComputerModel { get; set; }
public string ComputerModel { get; set; } = string.Empty;
[Display(Name = "Processor")]
public string ProcessorName { get; set; }
public string ProcessorName { get; set; } = string.Empty;
[Display(Name = "Memory")]
public string PhysicalMemory { get; set; }
public string PhysicalMemory { get; set; } = string.Empty;
[Display(Name = "Video controller")]
public string VideoController { get; set; }
public string VideoController { get; set; } = string.Empty;
[Display(Name = "Monitors")]
public string Monitors { get; set; }
public string Monitors { get; set; } = string.Empty;
[Display(Name = "Configfile")]
public string ConfigFileName { get; set; }
public string ConfigFileName { get; set; } = string.Empty;
[Display(Name = "UCS Version")]
public string UCSVersion { get; set; }
public string UCSVersion { get; set; } = string.Empty;
[Display(Name = "Axis Version")]
public string AxisVersion { get; set; }
public string AxisVersion { get; set; } = string.Empty;
[Display(Name = "Bosch Version")]
public string BoschVersion { get; set; }
public string BoschVersion { get; set; } = string.Empty;
[Display(Name = "OS Version")]
public string OSVersion { get; set; }
public string OSVersion { get; set; } = string.Empty;
[Display(Name = "OS Caption")]
public string OSCaption { get; set; }
public string OSCaption { get; set; } = string.Empty;
[Display(Name = ".Net Version")]
public string DotNetVersion { get; set; }
public string DotNetVersion { get; set; } = string.Empty;
[Display(Name = "BIOS Version")]
public string BIOSVersion { get; set; }
public string BIOSVersion { get; set; } = string.Empty;
[Display(Name = "USBDisks")]
public string USBDisks { get; set; }
public string USBDisks { get; set; } = string.Empty;
public virtual ICollection<UCSDevice> Devices { get; set; }
public ICollection<UCSDevice> Devices { get; set; } = [];
public virtual ICollection<Logging> Loggings { get; set; }
public ICollection<Logging> Loggings { get; } = [];
public virtual ICollection<EventLogError> Errors { get; set; }
public ICollection<EventLogError> Errors { get; } = [];
}
}

View File

@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace UCS_Status_Monitor.Models
{
public class HomeTableModel
{
public string TableColor { get; set; }
public string ComputerName { get; set; }
public string ConfigFileName { get; set; }
public string Uptime { get; set; }
public string LastMessageTime { get; set; }
}
}

View File

@@ -1,22 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using UCS_Status_Monitor.Models.Database;
namespace UCS_Status_Monitor.Models
{
public class LoggingViewModel
{
public LoggingViewModel()
{
LoggingChart = new ChartModel();
}
public UCSSystem? UCSSystem { get; set; }
public AxisCam? AxisCam { get; set; }
public Router? Router { get; set; }
public UCSSystem UCSSystem { get; set; }
public IEnumerable<Logging> Loggings { get; set; } = [];
public IEnumerable<Logging> Loggings { get; set; }
public ChartModel LoggingChart { get; set; }
public ChartModel LoggingChart { get; set; } = new();
}
}

View File

@@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace UCS_Status_Monitor.Models
{
public class OverviewTableModel
{
public string TableColor { get; set; }
public int UCSSystemId { get; set; }
public string ComputerName { get; set; }
public string LastMessageTime { get; set; }
public string Uptime { get; set; }
public string SystemUptime { get; set; }
public string ComputerModel { get; set; }
public string ProcessorName { get; set; }
public string PhysicalMemory { get; set; }
public string VideoController { get; set; }
public string Monitors { get; set; }
public string ConfigFileName { get; set; }
public string UCSVersion { get; set; }
public string AxisVersion { get; set; }
public string BoschVersion { get; set; }
public string BiosVersion { get; set; }
public string OSVersion { get; set; }
public string OSCaption { get; set; }
public string DotNetVersion { get; set; }
public string USBDisks { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More