Added mqtt camera handler

This commit is contained in:
Martijn Scheepers
2022-07-27 13:00:42 +02:00
parent b63c4f8f71
commit 4abed8501a
13 changed files with 678 additions and 162 deletions

View File

@@ -0,0 +1,136 @@
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.Tasks;
namespace UCS_Status_Monitor.UnitTest
{
[TestClass]
public class MQTT_Test
{
private static readonly Dictionary<string, string> inMemorySettings = new()
{
{ "Database", "UCSStatusMonitorTestDB.db" },
{ "SectionName:SomeKey", "SectionValue" },
};
private readonly IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();
//[TestMethod]
//public void ConnectionstatesPacketTest()
//{
// ILogger<TelemetryService> logger = Mock.Of<ILogger<TelemetryService>>();
// ITelegramBotService telegrambot = Mock.Of<ITelegramBotService>();
// TelemetryService telemetryWorker = new(logger, configuration, telegrambot);
// Models.TelemetryPacket telemetryPacket = new()
// {
// ComputerName = "PXX - UCS99",
// };
// //list == null
// telemetryWorker.ProcessPacket(telemetryPacket);
// Assert.AreEqual(1, telemetryWorker.SystemCount());
// Assert.AreEqual(0, telemetryWorker.DeviceCount());
// //empty list
// telemetryPacket.Connectionstates = new List<Models.ConnectionState>();
// telemetryWorker.ProcessPacket(telemetryPacket);
// Assert.AreEqual(0, telemetryWorker.DeviceCount("PXX - UCS99"));
// //list with empty device
// telemetryPacket.Connectionstates.Add(new Models.ConnectionState() { });
// telemetryWorker.ProcessPacket(telemetryPacket);
// Assert.AreEqual(0, telemetryWorker.DeviceCount("PXX - UCS99"));
// //only ID
// telemetryPacket.Connectionstates.Add(new Models.ConnectionState() { ID = "DX" });
// telemetryWorker.ProcessPacket(telemetryPacket);
// Assert.AreEqual(1, telemetryWorker.DeviceCount("PXX - UCS99"));
// telemetryPacket.Connectionstates.Add(new Models.ConnectionState() { ID = "D1", Name = "DienstIngang", State = true, LastStateChange = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss") });
// telemetryWorker.ProcessPacket(telemetryPacket);
// Assert.AreEqual(2, telemetryWorker.DeviceCount("PXX - UCS99"));
// telemetryPacket.Connectionstates.Add(new Models.ConnectionState() { ID = "D2", Name = "AchterIngang", State = true, LastStateChange = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss") });
// telemetryWorker.ProcessPacket(telemetryPacket);
// Assert.AreEqual(3, telemetryWorker.DeviceCount("PXX - UCS99"));
// //Bestaat all
// telemetryPacket.Connectionstates.Add(new Models.ConnectionState() { ID = "D2", Name = "AchterIngang", State = true, LastStateChange = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss") });
// telemetryWorker.ProcessPacket(telemetryPacket);
// Assert.AreEqual(3, telemetryWorker.DeviceCount("PXX - UCS99"));
//}
[TestMethod]
public void Parse_Teltonika_Json()
{
string json = "";
var message = TeltonikaMessage.Deserialize(json);
Assert.IsNull(message);
json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
message = TeltonikaMessage.Deserialize(json);
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);
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(TeltonikaMessage));
//Temp
Assert.AreEqual(36.0, message.TempValue());
Assert.AreEqual("36℃", message.Temp);
//Uptime
var 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]
public void Parse_AxisCam_Json()
{
string json = "";
var message = AxisCamMessage.Deserialize(json);
Assert.IsNull(message);
json = "lufhy2q9478ry78aq39 f3g789fy egy 3ghuieg heasuhg egh eisulgh uielg hsalgire";
message = AxisCamMessage.Deserialize(json);
Assert.IsNull(message);
json = "{ \"serialNumber\": \"B8A44F4A646C\",\"timestamp\": \"2022-07-26T08:33:59.336107Z\",\"connected\": true,\"description\": \"Connected\"}";
message = AxisCamMessage.Deserialize(json);
Assert.IsNotNull(message);
Assert.IsInstanceOfType(message, typeof(AxisCamMessage));
//SerialNumber
Assert.AreEqual("B8A44F4A646C", message.SerialNumber);
//Timestamp
Assert.AreEqual("26-7-2022 08:33:59", message.Timestamp.ToString());
//Connected
Assert.AreEqual(true, message.Connected);
//Description
Assert.AreEqual("Connected", message.Description);
}
}
}

View File

@@ -464,5 +464,51 @@ namespace UCS_Status_Monitor.Controllers
return View(sensors.ToList());
}
[HttpGet]
[Authorize]
public ActionResult Cameras()
{
return View();
}
[HttpGet]
[Authorize]
public async Task<JsonResult> GetCamerasTable()
{
using var dbContext = new MonitorDbContext(_configuration);
List<CameraTableModel> camsList = await dbContext.AxisCams
.OrderByDescending(o => o.Device)
.Select(a => new CameraTableModel
{
//LastMessageTime = Helpers.Html.FormatDateTime(a.LastMessageTime),
TableColor = a.TableColor(),
Device = a.Device,
Location = a.Location,
SerialNumber = a.SerialNumber,
Timestamp = a.Timestamp,
Connected = a.Connected,
Description = a.Description
}).ToListAsync();
return Json(camsList);
//List<Router> routers = await dbContext.Routers
// //.Include(d => d.Devices)
// .OrderByDescending(o => o.Location)
// .ToListAsync();
// //.Select(a => new HomeTableModel
// //{
// // //ComputerName = a.ComputerName,
// // ComputerName = a.ComputerNameWithError(),
// // ConfigFileName = a.ConfigFileName,
// // Uptime = a.Uptime,
// // LastMessageTime = Helpers.Html.FormatDateTime(a.LastMessageTime),
// // TableColor = a.TableColor(),
// //}).ToListAsync();
//return Json(routers);
}
}
}

View File

@@ -29,6 +29,8 @@ namespace UCS_Status_Monitor.Database
public DbSet<Models.Logging> Loggings { get; set; }
public DbSet<Models.EventLogError> Errors { get; set; }
public DbSet<Models.Sensor> Sensors { get; set; }
public DbSet<Models.Router> Routers { get; set; }
public DbSet<Models.AxisCam> AxisCams { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
@@ -42,6 +44,8 @@ namespace UCS_Status_Monitor.Database
modelBuilder.Entity<Models.Logging>().ToTable("Loggings");
modelBuilder.Entity<Models.EventLogError>().ToTable("Errors");
modelBuilder.Entity<Models.Sensor>().ToTable("Sensors");
modelBuilder.Entity<Models.Router>().ToTable("Routers");
modelBuilder.Entity<Models.AxisCam>().ToTable("AxisCams");
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace UCS_Status_Monitor
{
public class AxisCamMessage
{
//{
// "serialNumber": "B8A44F4A646C",
// "timestamp": "2022-07-26T08:33:59.336107Z",
// "connected": true,
// "description": "Connected"
//}
public static AxisCamMessage Deserialize(string json)
{
try
{
return JsonSerializer.Deserialize<AxisCamMessage>(json, new JsonSerializerOptions()
{
NumberHandling = JsonNumberHandling.AllowReadingFromString
});
}
catch (Exception)
{
return null;
}
}
[JsonPropertyName("serialNumber")]
public string SerialNumber { get; set; }
[JsonPropertyName("timestamp")]
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}";
//}
}
}

View File

@@ -2,19 +2,21 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MQTTnet;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using UCS_Status_Monitor.Database;
namespace UCS_Status_Monitor
{
@@ -42,196 +44,179 @@ namespace UCS_Status_Monitor
//private readonly X509Certificate clientCert = new X509Certificate2("Certs\\server.crt", "Certs\\server.key");
private readonly X509Certificate clientCert = new X509Certificate2("Certs\\server.pfx", "12345");
//private IManagedMqttClient managedMqttClient;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
var options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(new MqttClientOptionsBuilder()
.WithClientId(_mqttconfig.ClientID)
.WithTcpServer(_mqttconfig.BrokerAddress, _mqttconfig.BrokerPort)
.WithCredentials(_mqttconfig.Username, _mqttconfig.Password)
//.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500)
.WithTls(new MqttClientOptionsBuilderTlsParameters
{
UseTls = true,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
var mqttFactory = new MqttFactory();
using (var managedMqttClient = mqttFactory.CreateManagedMqttClient())
{
var managedMqttClientOptions = new ManagedMqttClientOptionsBuilder()
.WithClientOptions(new MqttClientOptionsBuilder()
.WithClientId(_mqttconfig.ClientID)
.WithTcpServer(_mqttconfig.BrokerAddress, _mqttconfig.BrokerPort)
.WithCredentials(_mqttconfig.Username, _mqttconfig.Password)
//.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500)
.WithTls(new MqttClientOptionsBuilderTlsParameters
{
UseTls = true,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
CertificateValidationHandler = (certContext) =>
{
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
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.TrustMode = X509ChainTrustMode.CustomRootTrust;
CertificateValidationHandler = (certContext) =>
{
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
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.TrustMode = X509ChainTrustMode.CustomRootTrust;
// convert provided X509Certificate to X509Certificate2
var x5092 = new X509Certificate2(certContext.Certificate);
return chain.Build(x5092);
},
Certificates = new List<X509Certificate>()
// convert provided X509Certificate to X509Certificate2
var x5092 = new X509Certificate2(certContext.Certificate);
return chain.Build(x5092);
},
Certificates = new List<X509Certificate>()
{
clientCert
}
})
.WithCleanSession()
.Build())
.Build();
IManagedMqttClient mqttClient = new MqttFactory().CreateManagedMqttClient();
//mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnConnected);
mqttClient.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate(OnConnectingFailed);
//mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnDisconnected);
mqttClient.UseApplicationMessageReceivedHandler(async e =>
{
await MessageReceived(e);
});
await mqttClient.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("#").Build());
await mqttClient.StartAsync(options);
while (!stoppingToken.IsCancellationRequested)
{
var message = new MqttApplicationMessageBuilder()
.WithTopic("MQTTNet/Test")
.WithPayload("{\"Message\":\"Hello world\"}")
.WithExactlyOnceQoS()
.WithRetainFlag()
})
.WithCleanSession()
.Build())
.Build();
await mqttClient.PublishAsync(message, stoppingToken);
managedMqttClient.ConnectingFailedAsync += OnConnectingFailed;
managedMqttClient.ApplicationMessageReceivedAsync += OnApplicationMessageReceived;
//await mqttClient.PublishAsync("Topic", "Hello");
await managedMqttClient.SubscribeAsync("#");
await managedMqttClient.StartAsync(managedMqttClientOptions);
//SpinWait.SpinUntil(() => managedMqttClient.PendingApplicationMessagesCount == 0, 10000);
//Debug.WriteLine($"Pending messages = {managedMqttClient.PendingApplicationMessagesCount}");
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}");
// Debug.WriteLine($"Pending messages = {mqttClient.PendingApplicationMessagesCount}");
await Task.Delay(30000, stoppingToken);
await Task.Delay(30000, stoppingToken);
}
}
mqttClient.Dispose();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
_logger.LogError(ex, "Setting up mqttclient failed");
//throw;
}
}
//static void OnConnected(MqttClientConnectedEventArgs obj)
//{
// Debug.WriteLine("Successfully connected.");
//}
private void OnConnectingFailed(ManagedProcessFailedEventArgs obj)
private async Task<Task> OnConnectingFailed(ConnectingFailedEventArgs args)
{
Debug.WriteLine("Couldn't connect to broker." + obj.Exception.Message);
_logger.LogError(obj.Exception, "Connect to broker failed.");
Debug.WriteLine("Couldn't connect to broker." + args.Exception.Message);
_logger.LogError(args.Exception, "Connect to broker failed.");
return Task.CompletedTask;
}
//static void OnDisconnected(MqttClientDisconnectedEventArgs obj)
//{
// Debug.WriteLine("Successfully disconnected. " + obj.Exception.Message);
//}
private async Task<Task> OnApplicationMessageProcessed(ApplicationMessageProcessedEventArgs args)
{
Debug.WriteLine("OnApplicationMessageProcessed");
return Task.CompletedTask;
}
private async Task MessageReceived(MqttApplicationMessageReceivedEventArgs args)
private async Task<Task> OnApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs args)
{
//Debug.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
//Debug.WriteLine($"+ Topic = {args.ApplicationMessage.Topic}");
//Debug.WriteLine($"+ Payload = {Encoding.UTF8.GetString(args.ApplicationMessage.Payload)}");
//Debug.WriteLine($"+ QoS = {args.ApplicationMessage.QualityOfServiceLevel}");
//Debug.WriteLine($"+ Retain = {args.ApplicationMessage.Retain}");
//Debug.WriteLine("----------------");
//Debug.WriteLine("-------------------------------");
MqttMessage mqttMessage = new MqttMessage(args.ApplicationMessage.Topic, Encoding.UTF8.GetString(args.ApplicationMessage.Payload));
var parts = args.ApplicationMessage.Topic.Split('/');
string location = parts[0];
string device = parts[1];
//Debug.WriteLine($"Topic = {mqttMessage.Topic}");
Debug.WriteLine($"Location = {mqttMessage.Location}");
Debug.WriteLine($"Device = {mqttMessage.Device}");
Debug.WriteLine($"JSON = {mqttMessage.Json}");
foreach (var item in mqttMessage.JsonValues)
{
Debug.WriteLine($"+ {item.Key} - {item.Value}");
if (device.Contains("ROUT"))
{
TeltonikaMessage teltonikaMessage = TeltonikaMessage.Deserialize(Encoding.UTF8.GetString(args.ApplicationMessage.Payload));
if (teltonikaMessage == null)
{
_logger.LogError($"Teltonika Mqtt error - {args.ApplicationMessage.Payload}");
return Task.CompletedTask;
}
using var dbContext = new MonitorDbContext(_configuration);
Models.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
};
dbContext.Routers.Add(router);
await dbContext.SaveChangesAsync();
await _telegramBot.Send($"RX:{teltonikaMessage.ThisMonthRX / 1000000}MB TX:{teltonikaMessage.ThisMonthTX / 1000000}MB");
}
Debug.WriteLine("--------------------------");
//if (args.ApplicationMessage.Topic == "5688HT002/S12ROUT01")
//{
// //Debug.WriteLine("Router message");
// TeltronikaRouterMessage(Encoding.UTF8.GetString(args.ApplicationMessage.Payload));
//}
}
//private void TeltronikaRouterMessage(string json)
//{
// //"time":"14/03/2022 10:07:14","LastMonthRX":"303644051"
// //var result = JsonSerializer.Deserialize<List<KeyValuePair<string, string>>>(json);
// var values = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
// foreach (var pair in values)
// {
// Debug.WriteLine($"Key:{pair.Key} - value:{pair.Value}");
// }
//}
}
public class MqttMessage
{
public string Topic { get; set; }
public string Location { get; set; }
public string Device { get; set; }
public string Json { get; set; }
public Dictionary<string, string> JsonValues { get; set; } = new Dictionary<string, string>();
public MqttMessage(string topic, string json)
{
Topic = topic;
var parts = topic.Split('/');
Location = parts[0];
Device = parts[1];
Json = json;
//{"serialNumber": "B8A44F4A646C", "timestamp": "2022-03-11T22:07:13.581119Z", "connected": true, "description": "Connected"}
//{"time":"14/03/2022 11:08:15","LastMonthRX":"303648259"}
try
if (device.Contains("CAM"))
{
JsonValues = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
AxisCamMessage axisCamMessage = AxisCamMessage.Deserialize(Encoding.UTF8.GetString(args.ApplicationMessage.Payload));
if (axisCamMessage == null)
{
_logger.LogError($"Axis cam Mqtt error - {args.ApplicationMessage.Payload}");
return Task.CompletedTask;
}
using var dbContext = new MonitorDbContext(_configuration);
var existingCam = dbContext.AxisCams.Where(x => x.Location == location && x.Device == device).FirstOrDefault();
if (existingCam != null)
{
if (existingCam.Connected != axisCamMessage.Connected)
{
await _telegramBot.SendConnectionStatus($"{existingCam.Location} - {existingCam.Device}", axisCamMessage.Connected);
}
//update cam
existingCam.SerialNumber = axisCamMessage.SerialNumber;
existingCam.Timestamp = axisCamMessage.Timestamp;
existingCam.Connected = axisCamMessage.Connected;
existingCam.Description = axisCamMessage.Description;
dbContext.AxisCams.Update(existingCam);
await dbContext.SaveChangesAsync();
}
else
{
//new cam
Models.AxisCam newCam = new()
{
Location = location,
Device = device,
SerialNumber = axisCamMessage.SerialNumber,
Timestamp = axisCamMessage.Timestamp,
Connected = axisCamMessage.Connected,
Description = axisCamMessage.Description
};
dbContext.AxisCams.Add(newCam);
await dbContext.SaveChangesAsync();
await _telegramBot.Send($"🆕 <b>{newCam.Location} - {newCam.Device}</b> Added");
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
//throw;
}
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,115 @@
using System;
using System.Globalization;
using System.Text;
using System.Text.Json;
namespace UCS_Status_Monitor
{
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)
{
try
{
json = json.Replace('[', '{');
json = json.Replace(']', '}');
return JsonSerializer.Deserialize<TeltonikaMessage>(json, new JsonSerializerOptions()
{
NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString
});
}
catch (Exception)
{
return null;
}
}
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(UInt32.Parse(value));
}
}
public TimeSpan UptimeValue()
{
return _uptime;
}
//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; }
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();
//}
}
}

View File

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

View File

@@ -139,7 +139,7 @@ namespace UCS_Status_Monitor.Models
public DateTime Date { get; set; }
[Display(Name = "Computer name")]
public string ComputerName{ get; set; }
public string ComputerName { get; set; }
[Display(Name = "Configfile")]
public string Configfile { get; set; }
@@ -156,4 +156,62 @@ namespace UCS_Status_Monitor.Models
[Display(Name = "Message number")]
public Int64 Count { get; set; }
}
public partial class Router
{
public int Id { get; set; }
[Display(Name = "Location")]
public string Location { get; set; }
[Display(Name = "Device")]
public string Device { get; set; }
[Display(Name = "Temperature")]
public float Temperature { get; set; }
[Display(Name = "Uptime")]
public TimeSpan Uptime { get; set; }
[Display(Name = "This month received")]
public UInt32 ThisMonthRX { get; set; }
[Display(Name = "This month transmitted")]
public UInt32 ThisMonthTX { get; set; }
[Display(Name = "Last month received")]
public UInt32 LastMonthRX { get; set; }
[Display(Name = "Last month transmitted")]
public UInt32 LastMonthTX { get; set; }
[Display(Name = "RSSI")]
public Int32 RSSI { get; set; }
[Display(Name = "Wan ip address")]
public string WanIp { get; set; }
}
public partial class AxisCam
{
public int Id { get; set; }
[Display(Name = "Location")]
public string Location { get; set; }
[Display(Name = "Device")]
public string Device { get; set; }
[Display(Name = "SerialNumber")]
public string SerialNumber { get; set; }
[Display(Name = "Timestamp")]
public DateTime Timestamp { get; set; }
[Display(Name = "Connected")]
public bool Connected { get; set; }
[Display(Name = "Description")]
public string Description { get; set; }
}
}

View File

@@ -130,7 +130,7 @@ namespace UCS_Status_Monitor.Models
if (sensor.Count.HasValue)
{
Count = sensor.Count.Value;
}
}
}
public bool IsAlarm()
@@ -151,4 +151,63 @@ namespace UCS_Status_Monitor.Models
}
}
public partial class Router
{
public Router() { }
public Router(TeltonikaMessage message)
{
}
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";
}
public string GetThisMonthTX()
{
return $"{ThisMonthTX / 1000000} MB";
}
public string ThisMonthTotal()
{
return $"{(ThisMonthTX + ThisMonthRX) / 1000000} MB";
}
public string GetRSSI()
{
return $"{RSSI} dBm";
}
public string GetLastMonthRX()
{
return $"{LastMonthRX / 1000000} MB";
}
public string GetLastMonthTX()
{
return $"{LastMonthTX / 1000000} MB";
}
public string LastMonthTotal()
{
return $"{(LastMonthRX + LastMonthTX) / 1000000} MB";
}
}
public partial class AxisCam
{
public String TableColor()
{
if (this.Connected == true)
{
return "table-success";
}
return "table-danger";
}
}
}

View File

@@ -82,6 +82,12 @@ namespace UCS_Status_Monitor
_telegramBotService.Send($"♻️ <b>{system.ComputerName}</b> UCS restarted");
}
}
//TODO check usb stick, send telegram
//if (system.USBDisks == "??" && !string.IsNullOrEmpty(telemetry.ComputerInfo.USBDisks))
//{
//}
system.Update(telemetry);
dbContext.UCSSystems.Update(system);
}

View File

@@ -26,16 +26,16 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MQTTnet" Version="3.1.2" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="3.1.2" />
<PackageReference Include="MQTTnet" Version="4.0.2.221" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="4.0.2.221" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="6.0.0" />
<PackageReference Include="Telegram.Bot" Version="17.0.0" />
<PackageReference Include="Telegram.Bot" Version="18.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,33 @@
@{
Layout = "_Layout";
}
<script>
$(document).ready(function () {
$(function () {
setInterval(UpdateTable, 1000);
UpdateTable();
});
});
function UpdateTable() {
$.getJSON("@Url.Action("GetCamerasTable", "Home")", function (data) {
$("#cams").empty();
$.each(data, function (i, cam) {
$("#cams").prepend('<div class="col mb-4">' +
'<div class="card ' + cam.tableColor + ' rounded" style="width: 18rem;">'+
'<div class="card-body py-1 h-auto" ><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">Timestamp: ' + cam.timestamp + '</li>' +
'</ul>' +
'</div>' +
'</div>'
);
});
});
}
</script>
<div class="container-fluid">
<div class="row" id="cams">
</div>
</div>

View File

@@ -32,10 +32,20 @@
@Html.ActionLink("Overview", "Overview", "Home", null, new { @class = "nav-link" })
</li>
}
<environment include="Development">
@if (User.Identity.IsAuthenticated)
{
<li class="nav-item">
@Html.ActionLink("Sensors", "Sensors", "Home", null, new { @class = "nav-link" })
</li>
}
</environment>
@if (User.Identity.IsAuthenticated)
{
<li class="nav-item">
@Html.ActionLink("Sensors", "Sensors", "Home", null, new { @class = "nav-link" })
@Html.ActionLink("Cameras", "Cameras", "Home", null, new { @class = "nav-link" })
</li>
}
</ul>