add Panicclient and rewrite Botclient so that is less code

add the possiblity to ask the Server for Panic button presses
remove the version box and put that to the global version-info pannel
This commit is contained in:
BlubbFish 2019-03-27 19:36:45 +01:00
parent c25b6f7ebb
commit c90a311320
7 changed files with 183 additions and 136 deletions

View File

@ -46,6 +46,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Model\Marker.cs" /> <Compile Include="Model\Marker.cs" />
<Compile Include="Model\Panicclient.cs" />
<Compile Include="Server.cs" /> <Compile Include="Server.cs" />
<Compile Include="Model\Botclient.cs" /> <Compile Include="Model\Botclient.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />

View File

@ -1,63 +1,25 @@
using System; using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Reflection;
using BlubbFish.Utils;
using LitJson; using LitJson;
namespace Fraunhofer.Fit.IoT.LoraMap.Model { namespace Fraunhofer.Fit.IoT.LoraMap.Model {
class Botclient { class Botclient {
public Double Rssi { get; private set; }
public Double Snr { get; private set; }
public DateTime Upatedtime { get; private set; }
public Double Latitude { get; private set; }
public Double Longitude { get; private set; }
public Double Hdop { get; private set; }
public Double Battery { get; private set; }
public Int32 Batterysimple { get; private set; }
public Boolean Fix { get; private set; }
public Double Height { get; private set; }
public String Name { get; private set; }
public String Icon { get; private set; }
public Botclient(String id, JsonData json, JsonData marker) { public Botclient(JsonData json, JsonData marker) {
if (json.ContainsKey("Rssi") && json["Rssi"].IsDouble) { this.Update(json);
this.Rssi = (Double)json["Rssi"]; String id = GetId(json);
}
if (json.ContainsKey("Snr") && json["Snr"].IsDouble) {
this.Snr = (Double)json["Snr"];
}
if (json.ContainsKey("Receivedtime") && json["Receivedtime"].IsString) {
if (DateTime.TryParse((String)json["Receivedtime"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) {
this.Upatedtime = updatetime;
}
}
if (json.ContainsKey("BatteryLevel") && json["BatteryLevel"].IsDouble) {
this.Battery = Math.Round((Double)json["BatteryLevel"], 2);
if(this.Battery < 3) {
this.Batterysimple = 0;
} else if(this.Battery < 3.2) {
this.Batterysimple = 1;
} else if(this.Battery < 3.5) {
this.Batterysimple = 2;
} else if(this.Battery < 3.8) {
this.Batterysimple = 3;
} else {
this.Batterysimple = 4;
}
}
if (json.ContainsKey("Gps") && json["Gps"].IsObject) {
if (json["Gps"].ContainsKey("Latitude") && json["Gps"]["Latitude"].IsDouble) {
this.Latitude = (Double)json["Gps"]["Latitude"];
}
if (json["Gps"].ContainsKey("Longitude") && json["Gps"]["Longitude"].IsDouble) {
this.Longitude = (Double)json["Gps"]["Longitude"];
}
if (json["Gps"].ContainsKey("Fix") && json["Gps"]["Fix"].IsBoolean) {
this.Fix = (Boolean)json["Gps"]["Fix"];
}
if (json["Gps"].ContainsKey("LastLatitude") && json["Gps"]["LastLatitude"].IsDouble && !this.Fix) {
this.Latitude = (Double)json["Gps"]["LastLatitude"];
}
if (json["Gps"].ContainsKey("LastLongitude") && json["Gps"]["LastLongitude"].IsDouble && !this.Fix) {
this.Longitude = (Double)json["Gps"]["LastLongitude"];
}
if (json["Gps"].ContainsKey("Hdop") && json["Gps"]["Hdop"].IsDouble) {
this.Hdop = (Double)json["Gps"]["Hdop"];
}
if (json["Gps"].ContainsKey("Height") && json["Gps"]["Height"].IsDouble) {
this.Height = (Double)json["Gps"]["Height"];
}
}
if(marker.ContainsKey(id)) { if(marker.ContainsKey(id)) {
if(marker[id].ContainsKey("name") && marker[id]["name"].IsString) { if(marker[id].ContainsKey("name") && marker[id]["name"].IsString) {
this.Name = (String)marker[id]["name"]; this.Name = (String)marker[id]["name"];
@ -77,41 +39,50 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model {
} }
} }
public Double Rssi { get; private set; } public static Boolean CheckJson(JsonData json) => json.ContainsKey("Rssi") && json["Rssi"].IsDouble
public Double Snr { get; private set; } && json.ContainsKey("Snr") && json["Snr"].IsDouble
public DateTime Upatedtime { get; private set; } && json.ContainsKey("Receivedtime") && json["Receivedtime"].IsString
public Double Latitude { get; private set; } && json.ContainsKey("BatteryLevel") && json["BatteryLevel"].IsDouble
public Double Longitude { get; private set; } && json.ContainsKey("Gps") && json["Gps"].IsObject
public Double Hdop { get; private set; } && json["Gps"].ContainsKey("Latitude") && json["Gps"]["Latitude"].IsDouble
public Double Battery { get; private set; } && json["Gps"].ContainsKey("Longitude") && json["Gps"]["Longitude"].IsDouble
public Int32 Batterysimple { get; private set; } && json["Gps"].ContainsKey("LastLatitude") && json["Gps"]["LastLatitude"].IsDouble
public Boolean Fix { get; private set; } && json["Gps"].ContainsKey("LastLongitude") && json["Gps"]["LastLongitude"].IsDouble
public Double Height { get; private set; } && json["Gps"].ContainsKey("Hdop") && json["Gps"]["Hdop"].IsDouble
public String Name { get; private set; } && json["Gps"].ContainsKey("Fix") && json["Gps"]["Fix"].IsBoolean
public String Icon { get; private set; } && json["Gps"].ContainsKey("Height") && json["Gps"]["Height"].IsDouble
&& json.ContainsKey("Name") && json["Name"].IsString;
public virtual Dictionary<String, Object> ToDictionary() { public static String GetId(JsonData json) => (String)json["Name"];
Dictionary<String, Object> dictionary = new Dictionary<String, Object>(); public void Update(JsonData json) {
foreach (PropertyInfo item in this.GetType().GetProperties()) { this.Rssi = (Double)json["Rssi"];
if (item.CanRead && item.GetValue(this) != null) { this.Snr = (Double)json["Snr"];
if (item.GetValue(this).GetType().GetMethod("ToDictionary") != null) { if(DateTime.TryParse((String)json["Receivedtime"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) {
dictionary.Add(item.Name, item.GetValue(this).GetType().GetMethod("ToDictionary").Invoke(item.GetValue(this), null)); this.Upatedtime = updatetime;
} else if (item.GetValue(this).GetType().HasInterface(typeof(IDictionary))) {
Dictionary<String, Object> subdict = new Dictionary<String, Object>();
foreach (DictionaryEntry subitem in (IDictionary)item.GetValue(this)) {
if (subitem.Value.GetType().GetMethod("ToDictionary") != null) {
subdict.Add(subitem.Key.ToString(), subitem.Value.GetType().GetMethod("ToDictionary").Invoke(subitem.Value, null));
}
}
dictionary.Add(item.Name, subdict);
} else if (item.GetValue(this).GetType().BaseType == typeof(Enum)) {
dictionary.Add(item.Name, Helper.GetEnumDescription((Enum)item.GetValue(this)));
} else {
dictionary.Add(item.Name, item.GetValue(this));
}
}
} }
return dictionary; this.Battery = Math.Round((Double)json["BatteryLevel"], 2);
if(this.Battery < 3) {
this.Batterysimple = 0;
} else if(this.Battery < 3.2) {
this.Batterysimple = 1;
} else if(this.Battery < 3.5) {
this.Batterysimple = 2;
} else if(this.Battery < 3.8) {
this.Batterysimple = 3;
} else {
this.Batterysimple = 4;
}
this.Latitude = (Double)json["Gps"]["Latitude"];
this.Longitude = (Double)json["Gps"]["Longitude"];
this.Fix = (Boolean)json["Gps"]["Fix"];
if(!this.Fix) {
this.Latitude = (Double)json["Gps"]["LastLatitude"];
this.Longitude = (Double)json["Gps"]["LastLongitude"];
}
this.Hdop = (Double)json["Gps"]["Hdop"];
this.Height = (Double)json["Gps"]["Height"];
} }
} }
} }

View File

@ -0,0 +1,52 @@
using System;
using System.Globalization;
using LitJson;
namespace Fraunhofer.Fit.IoT.LoraMap.Model {
class Panicclient {
public Double Rssi { get; private set; }
public Double Snr { get; private set; }
public DateTime Upatedtime { get; private set; }
public Double Latitude { get; private set; }
public Double Longitude { get; private set; }
public Double Hdop { get; private set; }
public Boolean Fix { get; private set; }
public Double Height { get; private set; }
public DateTime Triggerdtime { get; private set; }
public Panicclient(JsonData json) => this.Update(json);
public void Update(JsonData json) {
this.Triggerdtime = DateTime.Now;
this.Rssi = (Double)json["Rssi"];
this.Snr = (Double)json["Snr"];
if(DateTime.TryParse((String)json["Receivedtime"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) {
this.Upatedtime = updatetime;
}
this.Latitude = (Double)json["Gps"]["Latitude"];
this.Longitude = (Double)json["Gps"]["Longitude"];
this.Fix = (Boolean)json["Gps"]["Fix"];
if(!this.Fix) {
this.Latitude = (Double)json["Gps"]["LastLatitude"];
this.Longitude = (Double)json["Gps"]["LastLongitude"];
}
this.Hdop = (Double)json["Gps"]["Hdop"];
this.Height = (Double)json["Gps"]["Height"];
}
public static String GetId(JsonData json) => (String)json["Name"];
public static Boolean CheckJson(JsonData json) => json.ContainsKey("Rssi") && json["Rssi"].IsDouble
&& json.ContainsKey("Snr") && json["Snr"].IsDouble
&& json.ContainsKey("Receivedtime") && json["Receivedtime"].IsString
&& json.ContainsKey("Gps") && json["Gps"].IsObject
&& json["Gps"].ContainsKey("Latitude") && json["Gps"]["Latitude"].IsDouble
&& json["Gps"].ContainsKey("Longitude") && json["Gps"]["Longitude"].IsDouble
&& json["Gps"].ContainsKey("LastLatitude") && json["Gps"]["LastLatitude"].IsDouble
&& json["Gps"].ContainsKey("LastLongitude") && json["Gps"]["LastLongitude"].IsDouble
&& json["Gps"].ContainsKey("Hdop") && json["Gps"]["Hdop"].IsDouble
&& json["Gps"].ContainsKey("Fix") && json["Gps"]["Fix"].IsBoolean
&& json["Gps"].ContainsKey("Height") && json["Gps"]["Height"].IsDouble
&& json.ContainsKey("Name") && json["Name"].IsString;
}
}

View File

@ -14,6 +14,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap {
class Server : Webserver class Server : Webserver
{ {
private readonly SortedDictionary<String, Botclient> locations = new SortedDictionary<String, Botclient>(); private readonly SortedDictionary<String, Botclient> locations = new SortedDictionary<String, Botclient>();
private readonly SortedDictionary<String, Panicclient> panics = new SortedDictionary<String, Panicclient>();
private readonly JsonData marker; private readonly JsonData marker;
private readonly Dictionary<String, Marker> markertable = new Dictionary<String, Marker>(); private readonly Dictionary<String, Marker> markertable = new Dictionary<String, Marker>();
@ -22,27 +23,22 @@ namespace Fraunhofer.Fit.IoT.LoraMap {
protected override void Backend_MessageIncomming(Object sender, BackendEvent e) { protected override void Backend_MessageIncomming(Object sender, BackendEvent e) {
try { try {
JsonData d = JsonMapper.ToObject(e.Message); JsonData d = JsonMapper.ToObject(e.Message);
if (d.ContainsKey("Rssi") && d["Rssi"].IsDouble if (Botclient.CheckJson(d) && ((String)e.From).Contains("lora/data")) {
&& d.ContainsKey("Snr") && d["Snr"].IsDouble String name = Botclient.GetId(d);
&& d.ContainsKey("Receivedtime") && d["Receivedtime"].IsString
&& d.ContainsKey("BatteryLevel") && d["BatteryLevel"].IsDouble
&& d.ContainsKey("Gps") && d["Gps"].IsObject
&& d["Gps"].ContainsKey("Latitude") && d["Gps"]["Latitude"].IsDouble
&& d["Gps"].ContainsKey("Longitude") && d["Gps"]["Longitude"].IsDouble
&& d["Gps"].ContainsKey("LastLatitude") && d["Gps"]["LastLatitude"].IsDouble
&& d["Gps"].ContainsKey("LastLongitude") && d["Gps"]["LastLongitude"].IsDouble
&& d["Gps"].ContainsKey("Hdop") && d["Gps"]["Hdop"].IsDouble
&& d["Gps"].ContainsKey("Fix") && d["Gps"]["Fix"].IsBoolean
&& d["Gps"].ContainsKey("Height") && d["Gps"]["Height"].IsDouble
&& d.ContainsKey("Name") && d["Name"].IsString) {
String name = (String)d["Name"];
Botclient b = new Botclient(name, d, this.marker);
if (this.locations.ContainsKey(name)) { if (this.locations.ContainsKey(name)) {
this.locations[name] = b; this.locations[name].Update(d);
} else { } else {
this.locations.Add(name, b); this.locations.Add(name, new Botclient(d, this.marker));
} }
Console.WriteLine("Koordinate erhalten!"); Console.WriteLine("Koordinate erhalten!");
} else if(Panicclient.CheckJson(d) && ((String)e.From).Contains("lora/panic")) {
String name = Panicclient.GetId(d);
if(this.panics.ContainsKey(name)) {
this.panics[name].Update(d);
} else {
this.panics.Add(name, new Panicclient(d));
}
Console.WriteLine("PANIC erhalten!");
} }
} catch (Exception ex) { } catch (Exception ex) {
Helper.WriteError(ex.Message); Helper.WriteError(ex.Message);
@ -52,14 +48,12 @@ namespace Fraunhofer.Fit.IoT.LoraMap {
protected override void SendResponse(HttpListenerContext cont) { protected override void SendResponse(HttpListenerContext cont) {
try { try {
if (cont.Request.Url.PathAndQuery.StartsWith("/loc")) { if (cont.Request.Url.PathAndQuery.StartsWith("/loc")) {
Dictionary<String, Object> ret = new Dictionary<String, Object>(); this.SendJsonResponse(this.locations, cont);
Byte[] buf = Encoding.UTF8.GetBytes(JsonMapper.ToJson(this.locations));
cont.Response.ContentLength64 = buf.Length;
cont.Response.OutputStream.Write(buf, 0, buf.Length);
Console.WriteLine("200 - " + cont.Request.Url.PathAndQuery);
return; return;
} } else if(cont.Request.Url.PathAndQuery.StartsWith("/panic")) {
if (cont.Request.Url.PathAndQuery.StartsWith("/icons/marker/Marker.svg") && cont.Request.Url.PathAndQuery.Contains("?")) { this.SendJsonResponse(this.panics, cont);
return;
} else if (cont.Request.Url.PathAndQuery.StartsWith("/icons/marker/Marker.svg") && cont.Request.Url.PathAndQuery.Contains("?")) {
String hash = cont.Request.Url.PathAndQuery.Substring(cont.Request.Url.PathAndQuery.IndexOf('?') + 1); String hash = cont.Request.Url.PathAndQuery.Substring(cont.Request.Url.PathAndQuery.IndexOf('?') + 1);
if (!this.markertable.ContainsKey(hash)) { if (!this.markertable.ContainsKey(hash)) {
this.markertable.Add(hash, new Marker(hash)); this.markertable.Add(hash, new Marker(hash));

View File

@ -15,17 +15,23 @@ object {
pointer-events: none; pointer-events: none;
} }
.leaflet-touch .leaflet-bar a {
width: 38px;
}
#menucollumn { #menucollumn {
width: 32px; width: 32px;
background-color: white; background-color: white;
background-clip: padding-box;
position: absolute; position: absolute;
top: 85px; top: 85px;
bottom: 35px; bottom: 10px;
left: 10px; left: 10px;
z-index: 5000; z-index: 5000;
border: #707070 2px solid; border: #707070 2px solid;
border: rgba(0,0,0,0.4) 2px solid; border: rgba(0,0,0,0.2) 2px solid;
border-radius: 4px border-radius: 4px;
padding: 3px;
} }
#menucollumn span { #menucollumn span {
display: block; display: block;
@ -42,33 +48,18 @@ object {
#menucollumn .info { #menucollumn .info {
background-image: url("icons/information.png"); background-image: url("icons/information.png");
} }
/*<div>Icons made by <a href="https://www.flaticon.com/authors/smashicons" title="Smashicons">Smashicons</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>*/
/*<div>Icons made by <a href="https://www.freepik.com/" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>*/
/**<div>Icons made by <a href="https://www.freepik.com/" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>*/
#version {
position: absolute;
bottom: 0;
left: 0;
z-index: 50000;
background-color: white;
border-radius: 5px;
height: 20px;
width: 40px;
border: #707070 2px solid;
border: rgba(0,0,0,0.4) 2px solid;
}
#pannels { #pannels {
position: absolute; position: absolute;
top: 85px; top: 85px;
left: 47px; left: 55px;
bottom: 35px; bottom: 10px;
width: 250px; width: 250px;
z-index: 50000; z-index: 50000;
background-color: white; background-color: white;
background-clip: padding-box;
border: #707070 2px solid; border: #707070 2px solid;
border: rgba(0,0,0,0.4) 2px solid; border: rgba(0,0,0,0.2) 2px solid;
border-radius: 4px; border-radius: 4px;
display: none; display: none;
font-size: 11px; font-size: 11px;
@ -132,4 +123,28 @@ object {
} }
#pannels #pannels_info .update { #pannels #pannels_info .update {
margin-bottom: 10px; margin-bottom: 10px;
}
#pannels #pannels_version {
padding: 5px;
display: none;
}
#pannels #pannels_version .versionstring {
font-weight: bold;
}
#pannels #pannels_version .versionstring #version {
font-weight: normal;
font-family: monospace;
display: inline;
}
#pannels #pannels_version .cicons {
font-weight: bold;
}
#pannels #pannels_version .cicons ul {
margin: 0;
padding: 0;
padding-left: 15px;
}
#pannels #pannels_version .cicons ul li {
font-weight: normal;
} }

View File

@ -12,13 +12,27 @@
<div id="menucollumn"> <div id="menucollumn">
<span class="pos" onclick="showHidePanel('pannels_pos');"></span> <span class="pos" onclick="showHidePanel('pannels_pos');"></span>
<span class="admin" onclick="showHidePanel('pannels_admin');"></span> <span class="admin" onclick="showHidePanel('pannels_admin');"></span>
<span class="info" onclick="showHidePanel('pannels_info');"></span> <span class="info" onclick="showHidePanel('pannels_version');"></span>
</div> </div>
<div id="version">vx.x.x</div>
<div id="pannels"> <div id="pannels">
<div id="pannels_pos"></div> <div id="pannels_pos"></div>
<div id="pannels_info"></div> <div id="pannels_info">
<!-- Shows infos about selected device here, this will be cleand by js -->
</div>
<div id="pannels_admin"></div> <div id="pannels_admin"></div>
<div id="pannels_version">
<div class="versionstring">
Version:
<div id="version">vx.x.x</div>
</div>
<div class="cicons">
Icons:
<ul>
<li><a href="https://www.flaticon.com/authors/smashicons" title="Smashicons">Smashicons</a> licensed <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></li>
<li><a href="https://www.freepik.com/" title="Freepik">Freepik</a> licensed <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></li>
</ul>
</div>
</div>
</div> </div>
<script type="text/javascript" src="js/leaflet/leaflet.js"></script> <script type="text/javascript" src="js/leaflet/leaflet.js"></script>
<script type="text/javascript" src="js/nav.js"></script> <script type="text/javascript" src="js/nav.js"></script>

View File

@ -56,7 +56,7 @@ function updateStatus() {
for (var id in serverLocation) { for (var id in serverLocation) {
if (serverLocation.hasOwnProperty(id)) { if (serverLocation.hasOwnProperty(id)) {
var markeritem = serverLocation[id]; var markeritem = serverLocation[id];
if (typeof (overviewStatus[id]) == "undefined") { if (typeof overviewStatus[id] === "undefined") {
overviewStatus[id] = createOverviewElement(markeritem, id); overviewStatus[id] = createOverviewElement(markeritem, id);
document.getElementById("pannels_pos").appendChild(overviewStatus[id]); document.getElementById("pannels_pos").appendChild(overviewStatus[id]);
} }