Skip to content

Commit

Permalink
[1.3.0] New Gateway
Browse files Browse the repository at this point in the history
## New Features
* Implement Lora-Gateway-Data 1.1.0 Format
## Bugfixes
## Changes
* Refactoring
* Make requests.conf not needed anymore.
  • Loading branch information
blubbfish committed Jan 20, 2020
2 parents 977e541 + c96941b commit 61ed348
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 141 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
47 changes: 23 additions & 24 deletions Lora-Map/Lora-Map.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand All @@ -10,32 +10,34 @@
<Description>Displays Items with Coordinates from Mqtt on a Map</Description>
<Company>Fraunhofer FIT</Company>
<PackageId>LoraMap.IoT.Fit.Fraunhofer</PackageId>
<Copyright>Copyright © Fraunhofer FIT, BlubbFish 2018 - 11.12.2019</Copyright>
<Copyright>Copyright © Fraunhofer FIT, BlubbFish 2018 - 20.01.2020</Copyright>
<Authors>BlubbFish</Authors>
<Version>1.2.10</Version>
<Version>1.3.0</Version>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageProjectUrl>https://github.com/MONICA-Project/lora-map</PackageProjectUrl>
<RepositoryUrl>https://github.com/MONICA-Project/lora-map.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<NeutralLanguage>de-DE</NeutralLanguage>
<PackageReleaseNotes>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</PackageReleaseNotes>
<PackageReleaseNotes>
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</PackageReleaseNotes>
<PackageTags>lora mqtt map lagekarte</PackageTags>
<StartupObject>Fraunhofer.Fit.IoT.LoraMap.Program</StartupObject>
</PropertyGroup>
Expand All @@ -59,9 +61,6 @@
</ItemGroup>

<ItemGroup>
<None Update="config-example\requests.conf.example">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="config-example\settings.conf.example">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
30 changes: 16 additions & 14 deletions Lora-Map/Model/Admin/AdminModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class AdminModel {
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;
Expand Down Expand Up @@ -74,7 +74,7 @@ class AdminModel {
private Boolean Login(HttpListenerContext cont) {
Dictionary<String, String> 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)) {
Expand Down Expand Up @@ -110,22 +110,24 @@ class AdminModel {

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
}
}
}
81 changes: 16 additions & 65 deletions Lora-Map/Model/AlarmItem.cs
Original file line number Diff line number Diff line change
@@ -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<DateTime> ButtonPressed => this.buttonhistory.Keys.ToList();

public class AlarmItem : PositionItem {
private readonly SortedDictionary<DateTime, String> buttonhistory = new SortedDictionary<DateTime, String>();

public AlarmItem(JsonData json) => this.Update(json);
public List<DateTime> 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;
}
}
}
45 changes: 21 additions & 24 deletions Lora-Map/Model/PositionItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -27,7 +30,7 @@ class PositionItem {
}

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";
Expand All @@ -38,45 +41,39 @@ class PositionItem {
}
}
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);
}


Expand Down
7 changes: 1 addition & 6 deletions Lora-Map/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,11 @@ class Program {
_ = Console.ReadLine();
return;
}
if(!InIReader.ConfigExist("requests")) {
Helper.WriteError("requests.ini not found!");
_ = Console.ReadLine();
return;
}
InIReader ini = InIReader.GetInstance("settings");
Dictionary<String, String> 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"));
}
}
}
10 changes: 5 additions & 5 deletions Lora-Map/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Server : Webserver {
private readonly Object lockDensy = new Object();
private readonly Object lockSensor = new Object();

public Server(ADataBackend backend, Dictionary<String, String> settings, InIReader requests) : base(backend, settings, requests) {
public Server(ADataBackend backend, Dictionary<String, String> settings) : base(backend, settings, null) {
this.logger.SetPath(settings["loggingpath"]);
this.CheckJsonFiles();
this.admin = new AdminModel(settings);
Expand Down Expand Up @@ -71,7 +71,7 @@ class Server : Webserver {
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)) {
Expand All @@ -81,8 +81,8 @@ class Server : Webserver {
}
}
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);
Expand All @@ -98,7 +98,7 @@ class Server : Webserver {
}
}
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)) {
Expand Down
2 changes: 0 additions & 2 deletions Lora-Map/config-example/requests.conf.example

This file was deleted.

0 comments on commit 61ed348

Please sign in to comment.