diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index f199d4b..58c09db 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -45,7 +45,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ steps.create_deb.outputs.builddaterelease }} - release_name: Nightly from master + release_name: Nightly from ${{ steps.create_deb.outputs.builddaterelease }} body: This is a nightly release. It may be not working properly. draft: false prerelease: true diff --git a/CHANGELOG.md b/CHANGELOG.md index a9ddd52..7457fb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelogs +## 1.3.0 - New Gateway +### New Features +* Implement Lora-Gateway-Data 1.1.0 Format +### Bugfixes +### Changes +* Refactoring +* Make requests.conf not needed anymore. + ## 1.2.10 ### New Features * Posibility to display sensor data on map diff --git a/Lora-Map/Lora-Map.csproj b/Lora-Map/Lora-Map.csproj index 8a0d913..4cc87b5 100644 --- a/Lora-Map/Lora-Map.csproj +++ b/Lora-Map/Lora-Map.csproj @@ -1,4 +1,4 @@ - + Exe @@ -10,32 +10,34 @@ Displays Items with Coordinates from Mqtt on a Map Fraunhofer FIT LoraMap.IoT.Fit.Fraunhofer - Copyright © Fraunhofer FIT, BlubbFish 2018 - 11.12.2019 + Copyright © Fraunhofer FIT, BlubbFish 2018 - 20.01.2020 BlubbFish - 1.2.10 + 1.3.0 LICENSE https://github.com/MONICA-Project/lora-map https://github.com/MONICA-Project/lora-map.git git de-DE - 1.2.10 Refactoring is the thing -1.2.9 The PüMa Release -1.2.8 Improving the UI -1.2.7 Reorganise a lot of things, add Support for Cameradata -1.2.6 New Types of marker for person -1.2.5 Set textsize for every zoomlevel -1.2.4 Can draw Textmarkers on the Map, use MGRS (UTM) on the Map -1.2.3 #9 display polygons and marker on the map -1.2.2 Bugfix, if only recieve panic packet with gps data, update the marker on the map also -1.2.1 #6 Load the map from the Device -1.2.0 #4 Possible to Ex and Import Setting -1.1.7 #8 Editor for Names -1.1.6 #5 Create admin area -1.1.5 Add support for alert button -1.1.4 #3 Create icons for devices -1.1.3 #1 Click on icon and show details -1.1.2 #2 Show versions number in Site -1.1.1 Add Debian package config + + 1.3.0 New Gateway + 1.2.10 Refactoring is the thing + 1.2.9 The PüMa Release + 1.2.8 Improving the UI + 1.2.7 Reorganise a lot of things, add Support for Cameradata + 1.2.6 New Types of marker for person + 1.2.5 Set textsize for every zoomlevel + 1.2.4 Can draw Textmarkers on the Map, use MGRS (UTM) on the Map + 1.2.3 #9 display polygons and marker on the map + 1.2.2 Bugfix, if only recieve panic packet with gps data, update the marker on the map also + 1.2.1 #6 Load the map from the Device + 1.2.0 #4 Possible to Ex and Import Setting + 1.1.7 #8 Editor for Names + 1.1.6 #5 Create admin area + 1.1.5 Add support for alert button + 1.1.4 #3 Create icons for devices + 1.1.3 #1 Click on icon and show details + 1.1.2 #2 Show versions number in Site + 1.1.1 Add Debian package config lora mqtt map lagekarte Fraunhofer.Fit.IoT.LoraMap.Program @@ -59,9 +61,6 @@ - - PreserveNewest - PreserveNewest diff --git a/Lora-Map/Model/Admin/AdminModel.cs b/Lora-Map/Model/Admin/AdminModel.cs index 3546f7a..4c405b8 100644 --- a/Lora-Map/Model/Admin/AdminModel.cs +++ b/Lora-Map/Model/Admin/AdminModel.cs @@ -44,7 +44,7 @@ private Boolean SetJsonFile(HttpListenerContext cont, String filename, AdminEven cont.Request.InputStream.Close(); reader.Close(); try { - JsonMapper.ToObject(rawData); + _ = JsonMapper.ToObject(rawData); } catch (Exception) { Helper.WriteError("501 - Error recieving " + filename + ", no valid json " + cont.Request.Url.PathAndQuery); cont.Response.StatusCode = 501; @@ -74,7 +74,7 @@ private Boolean GetJsonFile(HttpListenerContext cont, String filename) { private Boolean Login(HttpListenerContext cont) { Dictionary POST = Webserver.GetPostParams(cont.Request); if(POST.ContainsKey("user") && POST["user"] == this.settings["admin_user"] && POST.ContainsKey("pass") && POST["pass"] == this.settings["admin_pass"]) { - Int64 sessionid = 0; + Int64 sessionid; while(true) { sessionid = AdminSession.GetRandomSessionid(); if(!this.session.ContainsKey(sessionid)) { @@ -110,22 +110,24 @@ private Boolean Login(HttpListenerContext cont) { private Boolean CheckAuth(HttpListenerContext cont) { #if DEBUG + Helper.WriteError("200 - AUTH-Bypassed!"); return true; - #endif - if(cont.Request.Url.PathAndQuery.StartsWith("/admin/login.html")) { - return true; - } else { - if(cont.Request.Cookies["loramapsession"] != null) { - if(Int64.TryParse(cont.Request.Cookies["loramapsession"].Value, out Int64 sessionid)) { - if(this.session.ContainsKey(sessionid)) { - return this.session[sessionid].IsLoggedin; + #else + if(cont.Request.Url.PathAndQuery.StartsWith("/admin/login.html")) { + return true; + } else { + if(cont.Request.Cookies["loramapsession"] != null) { + if(Int64.TryParse(cont.Request.Cookies["loramapsession"].Value, out Int64 sessionid)) { + if(this.session.ContainsKey(sessionid)) { + return this.session[sessionid].IsLoggedin; + } } } + cont.Response.StatusCode = 403; + Helper.WriteError("403 - " + cont.Request.Url.PathAndQuery); } - cont.Response.StatusCode = 403; - Helper.WriteError("403 - " + cont.Request.Url.PathAndQuery); - } - return false; + return false; + #endif } } } diff --git a/Lora-Map/Model/AlarmItem.cs b/Lora-Map/Model/AlarmItem.cs index 36c3854..83c02fa 100644 --- a/Lora-Map/Model/AlarmItem.cs +++ b/Lora-Map/Model/AlarmItem.cs @@ -1,81 +1,32 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using LitJson; namespace Fraunhofer.Fit.IoT.LoraMap.Model { - class AlarmItem { - public Double Rssi { get; private set; } - public Double Snr { get; private set; } - public DateTime Lorarecievedtime { get; private set; } - public DateTime Recievedtime { get; private set; } - public Double Latitude { get; private set; } - public Double Longitude { get; private set; } - public UTMData UTM { get; private set; } - public Double Hdop { get; private set; } - public Boolean Fix { get; private set; } - public Double Height { get; private set; } - public List ButtonPressed => this.buttonhistory.Keys.ToList(); - + public class AlarmItem : PositionItem { private readonly SortedDictionary buttonhistory = new SortedDictionary(); - public AlarmItem(JsonData json) => this.Update(json); + public List ButtonPressed => this.buttonhistory.Keys.ToList(); - public void Update(JsonData json) { - this.Rssi = json["Rssi"].IsInt ? (Int32)json["Rssi"] : (Double)json["Rssi"]; - this.Snr = json["Snr"].IsInt ? (Int32)json["Snr"] : (Double)json["Snr"]; - if (DateTime.TryParse((String)json["Receivedtime"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) { - this.Lorarecievedtime = updatetime.ToUniversalTime(); - } - this.Recievedtime = DateTime.UtcNow; - this.Latitude = json["Gps"]["Latitude"].IsInt ? (Int32)json["Gps"]["Latitude"] : (Double)json["Gps"]["Latitude"]; - this.Longitude = json["Gps"]["Longitude"].IsInt ? (Int32)json["Gps"]["Longitude"] : (Double)json["Gps"]["Longitude"]; - this.Fix = (Boolean)json["Gps"]["Fix"]; - if (!this.Fix) { - this.Latitude = json["Gps"]["LastLatitude"].IsInt ? (Int32)json["Gps"]["LastLatitude"] : (Double)json["Gps"]["LastLatitude"]; - this.Longitude = json["Gps"]["LastLongitude"].IsInt ? (Int32)json["Gps"]["LastLongitude"] : (Double)json["Gps"]["LastLongitude"]; - } - this.UTM = new UTMData(this.Latitude, this.Longitude); - this.Hdop = json["Gps"]["Hdop"].IsInt ? (Int32)json["Gps"]["Hdop"] : (Double)json["Gps"]["Hdop"]; - this.Height = json["Gps"]["Height"].IsInt ? (Int32)json["Gps"]["Height"] : (Double)json["Gps"]["Height"]; + public AlarmItem(JsonData json) : base(json, null) { + } + + public override void Update(JsonData json) { + base.Update(json); this.SetHistory(json); } private void SetHistory(JsonData json) { - String key = json["BatteryLevel"].ToString(); - key += "_" + json["Calculatedcrc"].ToString(); - key += "_" + json["Gps"]["Hdop"].ToString(); - key += "_" + json["Gps"]["Height"].ToString(); - key += "_" + json["Gps"]["Fix"].ToString(); - key += "_" + json["Gps"]["LastLatitude"].ToString(); - key += "_" + json["Gps"]["LastLongitude"].ToString(); - key += "_" + json["Gps"]["Time"].ToString(); - if(!this.buttonhistory.ContainsValue(key)) { - this.buttonhistory.Add(DateTime.UtcNow, key); - if(this.buttonhistory.Count > 10) { - this.buttonhistory.Remove(this.buttonhistory.Keys.ToList().First()); + if(json.ContainsKey("Hash") && json["Hash"].IsString) { + String key = json["Hash"].ToString(); + if(!this.buttonhistory.ContainsValue(key)) { + this.buttonhistory.Add(DateTime.UtcNow, key); + if(this.buttonhistory.Count > 10) { + _ = this.buttonhistory.Remove(this.buttonhistory.Keys.ToList().First()); + } } - } + } } - - public static String GetId(JsonData json) => (String)json["Name"]; - - public static Boolean CheckJson(JsonData json) => - json.ContainsKey("Rssi") && (json["Rssi"].IsDouble || json["Rssi"].IsInt) - && json.ContainsKey("Snr") && (json["Snr"].IsDouble || json["Snr"].IsInt) - && json.ContainsKey("Receivedtime") && json["Receivedtime"].IsString - && json.ContainsKey("BatteryLevel") && (json["BatteryLevel"].IsDouble || json["BatteryLevel"].IsInt) - && json.ContainsKey("Gps") && json["Gps"].IsObject - && json["Gps"].ContainsKey("Latitude") && (json["Gps"]["Latitude"].IsDouble || json["Gps"]["Latitude"].IsInt) - && json["Gps"].ContainsKey("Longitude") && (json["Gps"]["Longitude"].IsDouble || json["Gps"]["Longitude"].IsInt) - && json["Gps"].ContainsKey("LastLatitude") && (json["Gps"]["LastLatitude"].IsDouble || json["Gps"]["LastLatitude"].IsInt) - && json["Gps"].ContainsKey("LastLongitude") && (json["Gps"]["LastLongitude"].IsDouble || json["Gps"]["LastLongitude"].IsInt) - && json["Gps"].ContainsKey("LastGPSPos") && json["Gps"]["LastGPSPos"].IsString - && json["Gps"].ContainsKey("Hdop") && (json["Gps"]["Hdop"].IsDouble || json["Gps"]["Hdop"].IsInt) - && json["Gps"].ContainsKey("Fix") && json["Gps"]["Fix"].IsBoolean - && json["Gps"].ContainsKey("Height") && (json["Gps"]["Height"].IsDouble || json["Gps"]["Height"].IsInt) - && json.ContainsKey("Name") && json["Name"].IsString && - json.ContainsKey("Calculatedcrc") && json["Calculatedcrc"].IsInt; } -} \ No newline at end of file +} diff --git a/Lora-Map/Model/PositionItem.cs b/Lora-Map/Model/PositionItem.cs index f94c1c5..db742f0 100644 --- a/Lora-Map/Model/PositionItem.cs +++ b/Lora-Map/Model/PositionItem.cs @@ -3,7 +3,10 @@ using LitJson; namespace Fraunhofer.Fit.IoT.LoraMap.Model { - class PositionItem { + public class PositionItem { + private Double _lastLat = 0; + private Double _lastLon = 0; + public Double Rssi { get; private set; } public Double Snr { get; private set; } public DateTime Lorarecievedtime { get; private set; } @@ -27,7 +30,7 @@ public PositionItem(JsonData json, JsonData marker) { } public void UpdateMarker(JsonData marker, String id) { - if(marker.ContainsKey(id)) { + if(marker != null && marker.ContainsKey(id)) { this.Name = marker[id].ContainsKey("name") && marker[id]["name"].IsString ? (String)marker[id]["name"] : id; this.Icon = marker[id].ContainsKey("marker.svg") && marker[id]["marker.svg"].IsObject ? Marker.ParseMarkerConfig(marker[id]["marker.svg"], this.Name) : marker[id].ContainsKey("icon") && marker[id]["icon"].IsString ? (String)marker[id]["icon"] : null; this.Group = marker[id].ContainsKey("Group") && marker[id]["Group"].IsString ? (String)marker[id]["Group"] : "no"; @@ -38,45 +41,39 @@ public void UpdateMarker(JsonData marker, String id) { } } public static Boolean CheckJson(JsonData json) => - json.ContainsKey("Rssi") && (json["Rssi"].IsDouble || json["Rssi"].IsInt) - && json.ContainsKey("Snr") && (json["Snr"].IsDouble || json["Snr"].IsInt) - && json.ContainsKey("Receivedtime") && json["Receivedtime"].IsString - && json.ContainsKey("BatteryLevel") && (json["BatteryLevel"].IsDouble || json["BatteryLevel"].IsInt) + json.ContainsKey("BatteryLevel") && (json["BatteryLevel"].IsDouble || json["BatteryLevel"].IsInt) && json.ContainsKey("Gps") && json["Gps"].IsObject && json["Gps"].ContainsKey("Latitude") && (json["Gps"]["Latitude"].IsDouble || json["Gps"]["Latitude"].IsInt) && json["Gps"].ContainsKey("Longitude") && (json["Gps"]["Longitude"].IsDouble || json["Gps"]["Longitude"].IsInt) - && json["Gps"].ContainsKey("LastLatitude") && (json["Gps"]["LastLatitude"].IsDouble || json["Gps"]["LastLatitude"].IsInt) - && json["Gps"].ContainsKey("LastLongitude") && (json["Gps"]["LastLongitude"].IsDouble || json["Gps"]["LastLongitude"].IsInt) - && json["Gps"].ContainsKey("LastGPSPos") && json["Gps"]["LastGPSPos"].IsString - && json["Gps"].ContainsKey("Hdop") && (json["Gps"]["Hdop"].IsDouble || json["Gps"]["Hdop"].IsInt) && json["Gps"].ContainsKey("Fix") && json["Gps"]["Fix"].IsBoolean && json["Gps"].ContainsKey("Height") && (json["Gps"]["Height"].IsDouble || json["Gps"]["Height"].IsInt) && json.ContainsKey("Name") && json["Name"].IsString; public static String GetId(JsonData json) => (String)json["Name"]; - public void Update(JsonData json) { - this.Rssi = json["Rssi"].IsInt ? (Int32)json["Rssi"] : (Double)json["Rssi"]; - this.Snr = json["Snr"].IsInt ? (Int32)json["Snr"] : (Double)json["Snr"]; - if(DateTime.TryParse((String)json["Receivedtime"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) { - this.Lorarecievedtime = updatetime.ToUniversalTime(); - } + public virtual void Update(JsonData json) { + this.Rssi = json.ContainsKey("Rssi") && (json["Rssi"].IsDouble || json["Rssi"].IsInt) && Double.TryParse(json["Rssi"].ToString(), out Double rssi) ? rssi : 0; + this.Snr = json.ContainsKey("Snr") && (json["Snr"].IsDouble || json["Snr"].IsInt) && Double.TryParse(json["Snr"].ToString(), out Double snr) ? snr : 0; + this.Lorarecievedtime = json.ContainsKey("Receivedtime") && json["Receivedtime"].IsString && DateTime.TryParse((String)json["Receivedtime"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime) ? updatetime.ToUniversalTime() : DateTime.UtcNow; this.Recievedtime = DateTime.UtcNow; this.Battery = Math.Round(json["BatteryLevel"].IsInt ? (Int32)json["BatteryLevel"] : (Double)json["BatteryLevel"], 2); this.Batterysimple = this.Battery < 3.44 ? 0 : this.Battery < 3.53 ? 1 : this.Battery < 3.6525 ? 2 : this.Battery < 3.8825 ? 3 : 4; + this.Latitude = json["Gps"]["Latitude"].IsInt ? (Int32)json["Gps"]["Latitude"] : (Double)json["Gps"]["Latitude"]; this.Longitude = json["Gps"]["Longitude"].IsInt ? (Int32)json["Gps"]["Longitude"] : (Double)json["Gps"]["Longitude"]; this.Fix = (Boolean)json["Gps"]["Fix"]; + this.Height = json["Gps"]["Height"].IsInt ? (Int32)json["Gps"]["Height"] : (Double)json["Gps"]["Height"]; + this.Hdop = json["Gps"].ContainsKey("Hdop") && (json["Gps"]["Hdop"].IsDouble || json["Gps"]["Hdop"].IsInt) && Double.TryParse(json["Gps"]["Hdop"].ToString(), out Double hdop) ? hdop : 0; + if(!this.Fix) { - this.Latitude = json["Gps"]["LastLatitude"].IsInt ? (Int32)json["Gps"]["LastLatitude"] : (Double)json["Gps"]["LastLatitude"]; - this.Longitude = json["Gps"]["LastLongitude"].IsInt ? (Int32)json["Gps"]["LastLongitude"] : (Double)json["Gps"]["LastLongitude"]; - } - this.UTM = new UTMData(this.Latitude, this.Longitude); - if(DateTime.TryParse((String)json["Gps"]["LastGPSPos"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime lastgpstime)) { - this.Lastgpspostime = lastgpstime.ToUniversalTime(); + this.Latitude = this._lastLat; + this.Longitude = this._lastLon; + } else { + this._lastLat = this.Latitude; + this._lastLon = this.Longitude; + this.Lastgpspostime = DateTime.UtcNow; } - this.Hdop = json["Gps"]["Hdop"].IsInt ? (Int32)json["Gps"]["Hdop"] : (Double)json["Gps"]["Hdop"]; - this.Height = json["Gps"]["Height"].IsInt ? (Int32)json["Gps"]["Height"] : (Double)json["Gps"]["Height"]; + this.UTM = new UTMData(this.Latitude, this.Longitude); } diff --git a/Lora-Map/Program.cs b/Lora-Map/Program.cs index 687c249..f999e1f 100644 --- a/Lora-Map/Program.cs +++ b/Lora-Map/Program.cs @@ -12,16 +12,11 @@ static void Main(String[] _1) { _ = Console.ReadLine(); return; } - if(!InIReader.ConfigExist("requests")) { - Helper.WriteError("requests.ini not found!"); - _ = Console.ReadLine(); - return; - } InIReader ini = InIReader.GetInstance("settings"); Dictionary backenddata = ini.GetSection("mqtt"); backenddata.Add("topic", "lora/#;camera/#;sfn/#"); ADataBackend b = (ADataBackend)ABackend.GetInstance(backenddata, ABackend.BackendType.Data); - _ = new Server(b, ini.GetSection("webserver"), InIReader.GetInstance("requests")); + _ = new Server(b, ini.GetSection("webserver")); } } } diff --git a/Lora-Map/Server.cs b/Lora-Map/Server.cs index 0383c3c..9c33f5a 100644 --- a/Lora-Map/Server.cs +++ b/Lora-Map/Server.cs @@ -31,7 +31,7 @@ class Server : Webserver { private readonly Object lockDensy = new Object(); private readonly Object lockSensor = new Object(); - public Server(ADataBackend backend, Dictionary settings, InIReader requests) : base(backend, settings, requests) { + public Server(ADataBackend backend, Dictionary settings) : base(backend, settings, null) { this.logger.SetPath(settings["loggingpath"]); this.CheckJsonFiles(); this.admin = new AdminModel(settings); @@ -71,7 +71,7 @@ private void CheckJsonFiles() { protected override void Backend_MessageIncomming(Object sender, BackendEvent mqtt) { try { JsonData d = JsonMapper.ToObject(mqtt.Message); - if(PositionItem.CheckJson(d) && ((String)mqtt.From).Contains("lora/data")) { + if(((String)mqtt.From).Contains("lora/data") && PositionItem.CheckJson(d)) { String name = PositionItem.GetId(d); lock(this.lockData) { if(this.positions.ContainsKey(name)) { @@ -81,8 +81,8 @@ protected override void Backend_MessageIncomming(Object sender, BackendEvent mqt } } Console.WriteLine("Koordinate erhalten!"); - } else if(AlarmItem.CheckJson(d) && ((String)mqtt.From).Contains("lora/panic")) { - String name = AlarmItem.GetId(d); + } else if(((String)mqtt.From).Contains("lora/panic") && PositionItem.CheckJson(d)) { + String name = PositionItem.GetId(d); lock(this.lockPanic) { if(this.alarms.ContainsKey(name)) { this.alarms[name].Update(d); @@ -98,7 +98,7 @@ protected override void Backend_MessageIncomming(Object sender, BackendEvent mqt } } Console.WriteLine("PANIC erhalten!"); - } else if(Camera.CheckJson(d) && ((String)mqtt.From).Contains("camera/count")) { + } else if(((String)mqtt.From).Contains("camera/count") && Camera.CheckJson(d)) { String cameraid = Camera.GetId(d); lock(this.lockCount) { if(this.counter.ContainsKey(cameraid)) { diff --git a/Lora-Map/config-example/requests.conf.example b/Lora-Map/config-example/requests.conf.example deleted file mode 100644 index 5d9d8f8..0000000 --- a/Lora-Map/config-example/requests.conf.example +++ /dev/null @@ -1,2 +0,0 @@ -[js/map.js] -start_location=50.7, 7.2 \ No newline at end of file