Newer
Older
using System;
using System.Text.RegularExpressions;
using Fraunhofer.Fit.Iot.Lora.Events;
namespace Fraunhofer.Fit.Iot.Lora.Trackers {
public class Tracker {
private enum ParseType {
Update,
Panic
}
public delegate void UpdateDataEvent(Object sender, DataUpdateEvent e);
public delegate void UpdatePanicEvent(Object sender, PanicUpdateEvent e);
public delegate void UpdateStatusEvent(Object sender, StatusUpdateEvent e);
public event UpdateDataEvent DataUpdate;
public event UpdatePanicEvent PanicUpdate;
public Int32 Bandwidth { get; private set; }
public UInt16 CalculatedCRC { get; private set; }
public Byte CodingRate { get; private set; }
public String CRCStatus { get; private set; }
public Status DeviceStatus { get; private set; }
public UInt32 Frequency { get; private set; }
public Int32 FrequencyOffset { get; private set; }
public GpsInfo Gps { get; private set; }
public String IpAddress { get; private set; }
public String Modulation { get; private set; }
public Double PacketRssi { get; private set; }
public Byte RecieverInterface { get; private set; }
public Byte RecieverRadio { get; private set; }
public DateTime ReceivedTime { get; private set; }
public Double Rssi { get; private set; }
public Double SnrMax { get; private set; }
public Double SnrMin { get; private set; }
public Byte SpreadingFactor { get; private set; }
public UInt32 Time { get; private set; }
public Int32 Version { get; private set; }
public Boolean WifiActive { get; private set; }
public String WifiSsid { get; private set; }
public enum Status {
Unknown,
Startup,
Powersave,
Shutdown
}

philip.schell
committed
public Tracker() => this.Gps = new GpsInfo();
private void Parse(Byte[] data, ParseType dataType) {
if (data.Length == 21) {
Single lat = BitConverter.ToSingle(data, 3);
Single lon = BitConverter.ToSingle(data, 7);
Single hdop = ((Single)data[11]) / 10;
Single height = ((Single)BitConverter.ToUInt16(data, 12)) / 10;
Byte hour = data[14];
Byte minute = data[15];
Byte second = data[16];
Byte day = data[17];
Byte month = data[18];
UInt16 year = (UInt16)(data[19] + 2000);
this.BatteryLevel = (((Single)data[20]) + 230) / 100;
this.Gps.SetUpdate(lat, lon, height, hdop, hour, minute, second, day, month, year);
//Console.WriteLine("lat: " + lat + " lon: " + lon + " hdop: " + hdop + " heigt: " + height + " hh:mm:ss: " + hour + ":" + minute + ":" + second + " DD.MM.YY: " + day + "." + month + "." + year + " bat: " + this.BatteryLevel);

philip.schell
committed
if (dataType == ParseType.Panic) {
this.PanicUpdate?.Invoke(this, new PanicUpdateEvent(this));
}

philip.schell
committed
this.DataUpdate?.Invoke(this, new DataUpdateEvent(this));
private void Parse(String text) {
String[] texts = text.Split(new String[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
this.Name = GetName(text, 0);
String[] infos = texts[1].Split(',');
if (infos.Length >= 6 && Double.TryParse(infos[5], out Double batteryLevel)) {
this.BatteryLevel = batteryLevel;
}
this.Gps.SetUpdate(texts[1]);
this.DataUpdate?.Invoke(this, new DataUpdateEvent(this));
}
private void ParseStatus(String text) {
String[] texts = text.Split(new String[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
if(texts.Length != 3) {
return;
}
this.Name = GetName(text, 1);
String[] infos = texts[2].Split(',');
if(infos.Length != 7) {
return;
}
if (Int32.TryParse(infos[0], out Int32 version)) {
this.Version = version;
}
this.IpAddress = infos[1];
this.WifiSsid = infos[2];
this.WifiActive = infos[3] == "t";
if (Double.TryParse(infos[4], out Double batteryLevel)) {
this.BatteryLevel = batteryLevel;
}
if (Int32.TryParse(infos[5], out Int32 freqOffset)) {
this.FrequencyOffset = freqOffset;
}
if(Int32.TryParse(infos[6], out Int32 deviceStatus)) {
if(deviceStatus == 0) {
this.DeviceStatus = Status.Shutdown;
} else if(deviceStatus == 1) {
this.DeviceStatus = Status.Startup;
} else if(deviceStatus == 2) {
this.DeviceStatus = Status.Powersave;
}
this.StatusUpdate?.Invoke(this, new StatusUpdateEvent(this));
if(e is Ic800ALoraClientEvent) {
Ic800ALoraClientEvent ic = e as Ic800ALoraClientEvent;
this.Bandwidth = ic.Bandwidth;
this.CalculatedCRC = ic.Calculatedcrc;
this.CodingRate = ic.CodingRate;
this.CRCStatus = ic.CrcStatus;
this.Frequency = ic.Frequency;
this.RecieverInterface = ic.Interface;
this.Modulation = ic.Modulation;
this.RecieverRadio = ic.Radio;
this.SnrMax = ic.SnrMax;
this.SnrMin = ic.SnrMin;
this.SpreadingFactor = ic.Spreadingfactor;
this.Time = ic.Time;
}
this.PacketRssi = e.Packetrssi;
this.Rssi = e.Rssi;
this.Snr = e.Snr;
public void SetUpdate(LoraClientEvent e, String data) {
this.SetUpdate(e);
this.Parse(data);
}
public void SetUpdate(LoraClientEvent e, Byte[] data) {
this.SetUpdate(e);
this.Parse(data, ParseType.Update);
}
public void SetPanics(LoraClientEvent e, Byte[] data) {
this.SetUpdate(e);
this.Parse(data, ParseType.Panic);
public void SetStatus(LoraClientEvent e, String textStatus) {
this.SetUpdate(e);
this.ParseStatus(textStatus);
}
#endregion
#region Static Functions
public static Boolean CheckPacket(String message) {
String[] m;
if (message.Contains("\r\n")) {
m = message.Split(new String[] { "\r\n" }, StringSplitOptions.None);
} else if (message.Contains("\n")) {
m = message.Split(new String[] { "\n" }, StringSplitOptions.None);
} else {
return false;
}
if (m.Length == 2) { //Normal Data Packet
if (m[0] == "") { //Name should not be empty
if (!Regex.Match(m[1], "[0-9]+.[0-9]{5,10},[0-9]+.[0-9]{5,10},[0-9]{6},[0-9]+.[0-9]{2},[0-9]+.[0-9],[0-9].[0-9]{2}").Success) { //lon,lat,hhmmss,hdop,height,bat not match
if (m.Length == 3) { //Debug Packet
if (m[0] != "deb") { //first must be "deb"
return false;
}
if (m[1] == "") { //Name should not be empty
//version,ip,ssid,wififlag,battery,offset,statusmode
if (!Regex.Match(m[2], "^[0-9]+,[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3},[^,]+,[tf],[0-9].[0-9]{2},(-[0-9]+|[0-9]+),[0-9]").Success) {
return false;
}
return true;
}
return false;
}
public static String GetName(String message, Int32 index) {
if (message.Contains("\r\n")) {
return message.Split(new String[] { "\r\n" }, StringSplitOptions.None)[index].Trim();
} else if (message.Contains("\n")) {
return message.Split(new String[] { "\n" }, StringSplitOptions.None)[index].Trim();
} else {
return "";
}
if(data.Length >= 3) {
Byte[] ret = new Byte[2];
for (Int32 i = 0; i < 2; i++) {
if (ret[1] == 0) {
return System.Text.Encoding.ASCII.GetString(new Byte[] { ret[0] }).Trim();
} else {
return System.Text.Encoding.ASCII.GetString(ret).Trim();
}