using System; using System.Collections.Generic; using System.Linq; using System.Text; using SafeMobileLib; using System.Threading; using SafeMobileLib.MessageDecoders; using System.Collections; using System.Net.Mail; using System.Threading.Tasks; namespace AppServer { class LocationThread { private InterthreadMessageQueue callOutQueue; private DBsettingsManager DBSettings; private volatile Boolean BeforeWriteDB; private volatile LocationDecoder dec2; private volatile DBsubsOperationManager dbsubsoperManage; private volatile DBvehiclesManager dbvehs; private DBvehiclesManager DBvehInfo; public static volatile Int32 LocationCheckQueuesCount = 0; Int64 count = 0; private bool sendCalloutStop; public LocationThread(/*GatewayID_IP trboID_IP, UInt16 arsPort, Boolean capPlus, String multicastIP, String multicastPort*/) { callOutQueue = new InterthreadMessageQueue(); Task.Factory.StartNew(ConsumeCallOutClear); try { Console.WriteLine("1:cfg.DB_IP:" + Program.cfg.DB_IP); Console.WriteLine("2:cfg.DB_schema:" + Program.cfg.DB_schema); Console.WriteLine("3:cfg.DB_user:" + Program.cfg.DB_user); Console.WriteLine("4:cfg.DB_pass:" + Program.cfg.DB_passwd); Console.WriteLine("5:cfg.DB_port:" + Program.cfg.DB_port); dbsubsoperManage = new DBsubsOperationManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port); //dbsubsoperManage.InitConnection(); dbvehs = new DBvehiclesManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port); DBSettings = new DBsettingsManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port); } catch (Exception ex) { Console.WriteLine("Erorr conver port:"+ex.ToString()); } } public void PushStatus(String IMEI, Status_for_tab stat) { Utils.WriteLine("Send PushStatus:" + stat + " Imei:" + IMEI, ConsoleColor.Yellow); byte[] cmd = Utils.Convert_text_For_multicast("#0.0#153#" + IMEI + "#" + (Int32)stat + "#"); MainForm.udp.Send(cmd, cmd.Length); } public void handleConnection() { DBvehInfo = new DBvehiclesManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port); SM.Debug("Location Thread - Waiting for Position"); if (MainForm.VehListWithGroupDetails.Count == 0 && dbvehs != null) { MainForm.VehListWithGroupDetails.Clear(); List list = dbvehs.getAllVehicles(); foreach (Vehicles veh in list) { // remove old object if still exists if (MainForm.VehListWithGroupDetails.Contains(veh.Imei)) MainForm.VehListWithGroupDetails.Remove(veh.Imei); MainForm.VehListWithGroupDetails.Add(veh.Imei, veh); } } for (int i = 0; i < 70; i++) { ThreadStart action = () => { Consume(); }; Thread t = new Thread(action) { IsBackground = true }; t.Start(); //Task.Factory.StartNew(() => Consume()); } while (MainForm.isRunning) { // keep the Location Thread running for receiving and other stuffs Thread.Sleep(100); } Utils.WriteLine("ENDING RRRRRR ", ConsoleColor.Green); } private void Consume() { while (MainForm.isRunning) { try { string line = MainForm.LocationQueue.GetItem(50); bool prevGps = false; // search for position in the previous Location queue if no new one is received if (line == default(string)) { line = MainForm.prevLocationQueue.GetItem(1); // flag that this gps position is from a previous instance of App Server and don't need to // generate alerts on message bus for geofence, landmark, speeding and also will not update // the unit status prevGps = true; } LocationCheckQueuesCount++; while (line != default(string)) { BeforeWriteDB = true; string[] tempArr = line.Split("#".ToCharArray()); //imei try { #region INSERT POSITION IN DB string radioID2 = tempArr[0]; String[] locString = new String[tempArr.Length - 1]; for (int i = 0; i < (tempArr.Length - 1); i++) locString[i] = tempArr[i + 1]; bool active = false; // check if radio id is assigned and active if (!MainForm.VehList.ContainsKey(radioID2.ToString()) || (MainForm.VehList.ContainsKey(radioID2.ToString()) && !((active = ((Vehicle_Data)MainForm.VehList[radioID2.ToString()]).active)))) { Utils.WriteLine($"Skipping position {line} because {radioID2} is not in the vehicle list [{active}]", ConsoleColor.Yellow); line = MainForm.LocationQueue.GetItem(1); prevGps = false; continue; } else if ( MainClass.isGPSCheckboxChecked && !(((VehicleStatus)MainForm.VehicleHashStat[radioID2]).curentStatus == Status_for_tab.EMERG)) { Utils.WriteLine($"Skipping position for unit: {radioID2} because EmergencyOnly Checkbox is checked and the unit is not in emergency!", ConsoleColor.Yellow); line = MainForm.LocationQueue.GetItem(1); prevGps = false; continue; } LocationDecoder dec2 = new LocationDecoder(radioID2, locString); if (dec2.cell.lat != null) { Utils.WriteLine($"GPS [time: {dec2.cell.location_time:HH:mm:ss}][{dec2.cell.lat}, {dec2.cell.lng}] from {radioID2}[{dec2.cell.spd} kmh]", ConsoleColor.DarkGreen); dec2.UpdateDBDirect(dbsubsoperManage); //dbsubsoperManage.CloseConnection(); } else { Utils.WriteLine($"Received invalid GPS position from {radioID2}", ConsoleColor.DarkRed); } BeforeWriteDB = false; #endregion // display the number of unadded positions after each 50 positions added if (count++ % 10 == 0) Utils.WriteLine($"{MainForm.LocationQueue.Count} live gps & {MainForm.prevLocationQueue.Count} prev gps waiting to be added to db", ConsoleColor.White); #region ALARM CHECK & HANDLER //get alarms settings if (MainForm.VehList.ContainsKey(radioID2.ToString()) && (dec2.cell.lat != null)) { try { Vehicle_Data v_data = (Vehicle_Data)MainForm.VehList[radioID2.ToString()]; Alarm alarm = v_data.alm; bool zone = false; bool landMark = false; String SpeedProccess = ""; if (alarm.Zone != "") zone = true; if (alarm.Landmark != "") landMark = true; if (zone || landMark) { SpeedProccess = processZoneAlarm(radioID2, dec2.cell, zone, landMark, alarm.Email, !prevGps); } // if don't have limit's in area I take general alarm if (SpeedProccess == "") SpeedProccess = alarm.Speed; if (SpeedProccess != "") { string[] temp = SpeedProccess.Split("_".ToCharArray()); int speedT = (int)Convert.ToDouble(temp[0]); string speedU = temp[1]; processSpeedAlarm(radioID2, dec2.cell, speedT, speedU, alarm.Email, !prevGps); } } catch (Exception ex) { Utils.WriteLine("Error and add Alarm:" + ex.ToString(), ConsoleColor.Red); throw new ArgumentException("AlarmError"); } } #endregion #region STOLEN //stolen if (MainForm.VehList.ContainsKey(radioID2) && (MainForm.VehStolen.ContainsKey(radioID2.ToString())) && (dec2.cell.lat != null)) { int status2 = Convert.ToInt32(MainForm.VehStolen[radioID2]); if (status2 == 1) { bool shouldDisableUnit = false; double lat = 0; double lng = 0; Double.TryParse(dec2.cell.lat, out lat); Double.TryParse(dec2.cell.lng, out lng); // get settings value for Stolen on No GPS Fix Location string value = MainForm.dbSettings.getSettingValue(0, Utils.StolenNoGPSFix); bool stolenNoGPSFix = false; bool.TryParse(value, out stolenNoGPSFix); if (stolenNoGPSFix && Math.Abs(lat) < 0.1 && Math.Abs(lng) < 0.1) { Utils.WriteLine("No GPS fix location received for a stolen vehicle " + radioID2, ConsoleColor.Cyan); shouldDisableUnit = true; } // get settings value for Stolen on No GPS Fix Location value = MainForm.dbSettings.getSettingValue(0, Utils.StolenValidGPS); bool stolenGPSFix = false; bool.TryParse(value, out stolenGPSFix); if (stolenGPSFix && (Math.Abs(lat) > 0.1 || Math.Abs(lng) > 0.1)) { Utils.WriteLine("GPS location received for a stolen vehicle " + radioID2, ConsoleColor.Cyan); shouldDisableUnit = true; } if (shouldDisableUnit) { try { // skip sending enable/disable if the unit is not in the vehicles list if (!MainForm.VehList.ContainsKey(radioID2)) { continue; } //get unit system position int unitSC_ID = ((Vehicle_Data)MainForm.VehList[radioID2]).sc_id; UnitSysPosition sysPos = DBvehInfo.getSystemPosition(unitSC_ID); string dest = "0.0." + radioID2; if (sysPos != null) dest = sysPos.Gw_id + "." + sysPos.R_gw_id + "." + radioID2; //send radio disable to GW Utils.WriteLine("Radio disable was sent on " + sysPos.Gw_id + "." + sysPos.R_gw_id + " gateway", ConsoleColor.Cyan); string test2 = $"#{(int)MessageBusCmds.RadioEnableDisableRequest}#" + dest + "#0#"; MainForm.udp.Send(Utils.Convert_text_For_multicast("#0.0" + test2), Utils.Convert_text_For_multicast("#0.0" + test2).Length); } catch (Exception ex) { Utils.WriteLine("Error and add Stolen:" + ex.ToString(), ConsoleColor.Red); throw new ArgumentException("StolenError"); } } } } #endregion #region STATUS UPDATE //Calculate status if (MainForm.VehicleHashStat.ContainsKey(radioID2.ToString()) && !prevGps) { VehicleStatus vehicleStatus = (VehicleStatus)MainForm.VehicleHashStat[radioID2]; //MADE ON status when is the case if ((vehicleStatus.curentStatus == Status_for_tab.MADEOFF) || (vehicleStatus.curentStatus == Status_for_tab.OFF)) { vehicleStatus.curentStatus = Status_for_tab.MADEON; PushStatus(radioID2, Status_for_tab.MADEON); } // update last status location and position time vehicleStatus.lastPositionTime = DateTime.Now; vehicleStatus.lat = dec2.cell.d_lat; vehicleStatus.lng = dec2.cell.d_lng; // do not push any status update if the current status is emergency if (vehicleStatus.curentStatus != Status_for_tab.EMERG) { if (dec2.cell.lat != "0" && dec2.cell.lat != "0.00000") { if (vehicleStatus.curentStatus != Status_for_tab.GPS_ON) { vehicleStatus.curentStatus = Status_for_tab.GPS_ON; //SM.Debug("Push Status GPS ON for radio:"+radioID2); PushStatus(radioID2, Status_for_tab.GPS_ON); } } else { if (vehicleStatus.curentStatus != Status_for_tab.NOGPSFIX) { vehicleStatus.curentStatus = Status_for_tab.NOGPSFIX; PushStatus(radioID2, Status_for_tab.NOGPSFIX); } } } } #endregion Status_for_tab status = ((VehicleStatus)MainForm.VehicleHashStat[radioID2]).curentStatus; String heading = dec2.cell.heading ?? ""; //add position to MainForm.websocketLocationQueue if (MainForm.hasDBAccess && dec2.cell.lat != null) MainForm.CheckLocationQueueAndSendToWebSocket(radioID2, Convert.ToDouble(dec2.cell.lat), Convert.ToDouble(dec2.cell.lng), Convert.ToInt32(dec2.cell.spd), DateTo70Format(dec2.cell.location_time), heading, status); } catch (Exception ex) { Utils.WriteLine("Error on add location mess to DB: " + ex.ToString(), ConsoleColor.Red); if ((!ex.ToString().Contains("23505")) && (BeforeWriteDB)) { try { string test2 = "#210#1#Can't write GPS data in DB#"; if (ex.Message == "AlarmError") test2 = "#210#5#Can't write Alarm data in DB#"; else if (ex.Message == "StolenError") test2 = "#210#6#Can't write Stolen data in DB#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test2), SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test2).Length); } catch (Exception ex2) { SM.Debug("Error on sending Message to SD that APPServer has problem: " + ex2.ToString()); } } } line = MainForm.LocationQueue.GetItem(1); prevGps = false; } Thread.Sleep(5); } catch (Exception e) { Console.WriteLine("##### Error on proccess Location #########\n" + e.ToString()); Thread.Sleep(100); } Thread.Sleep(5); } } //CallOut stop request on msgBus private void ConsumeCallOutClear() { while (MainForm.isRunning) { CallOut callout = callOutQueue.Peek(100); if(callout != null) { callout = callOutQueue.GetItem(1); sendCalloutStop = false; while (!sendCalloutStop) { // check time and send if > 5 seconds if (DateTime.Now >= callout.Time.AddSeconds(5)) //Checks if 5 seconds passed since a Callout was sent sendCalloutStop = true; if (sendCalloutStop) { // send callout clear string test = "#178#" + callout.RadioID.ToString() + "#" + callout.Severity + "#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test), SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test).Length); Utils.WriteLine($"Sent CallOut Stop request with Severity [{callout.Severity}] for unit {callout.RadioID.ToString()} "); } } } } } private void sendMailGeo(string mes, String subj, string mailAdr) { if (Program.cfg.enableEmailService && !String.IsNullOrEmpty(Program.cfg.emailAddress) && !String.IsNullOrEmpty(mailAdr)) { try { MailAddress from = new MailAddress(Program.cfg.emailAddress); String[] address = mailAdr.Split(";".ToCharArray()); MailAddress to = new MailAddress(address[0]); MailMessage message = new MailMessage(from, to); if (address.Count() > 1) { Boolean skipeFirst = true; foreach (String obj in address) { if (skipeFirst) { skipeFirst = false; } else message.To.Add(new MailAddress(obj)); } } message.Subject = subj; message.Body = mes; EmailServerSSL.sendEmail(Program.cfg.smtpServer, Program.cfg.smtpPort, Program.cfg.emailAddress, Program.cfg.emailPassword, message, Program.cfg.smtpSSLState); } catch (Exception ex) { Console.WriteLine("Exception in sendMailGeo: ", ex.ToString()); } } else { Utils.WriteLine("Email Server not Set", ConsoleColor.Cyan); } } private void sendAlarmMail(string title, string mes, string mailAdr) { if (Program.cfg.enableEmailService && !String.IsNullOrEmpty(Program.cfg.emailAddress) && !String.IsNullOrEmpty(mailAdr)) { try { MailAddress from = new MailAddress(Program.cfg.emailAddress); MailAddress to = new MailAddress(mailAdr); MailMessage message = new MailMessage(from, to); message.Subject = title; message.Body = mes; EmailServerSSL.sendEmail(Program.cfg.smtpServer, Program.cfg.smtpPort, Program.cfg.emailAddress, Program.cfg.emailPassword, message, Program.cfg.smtpSSLState); } catch (Exception ex) { Utils.WriteLine("Exception in sendMailAlarm2: {0}" + ex.ToString(), ConsoleColor.Red); } } else { Utils.WriteLine("Email Server not Set",ConsoleColor.Cyan); } } private String processZoneAlarm(string radioID, htCell_t cell, bool zone, bool landMArk, string mailAdr, bool sendOnMsgBus) { double lat = double.Parse(cell.lat); double lng = double.Parse(cell.lng); uint time = DateTo70Format(cell.location_time); Int32 speed = Int32.Parse(cell.spd); // in kmh String Speedtoproccess = ""; DBalarmManager DBalarm = new DBalarmManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port); // I don't procces Lat=0 and LNG=0 NO FIX GPS if (!((Math.Round(lat) == 0) && (Math.Round(lng) == 0))) { if (!MainForm.ZonesBussy) { if (MainForm.VehList[radioID.ToString()] != null) { if (zone) { foreach (ZoneClass obj2 in ((Vehicle_Data)MainForm.VehList[radioID.ToString()]).zonelist) { Int32 position = 0; Boolean validAlarm = false; String tmpresp = obj2.CheckZone(lat, lng, out position); String speedMiles = Convert.ToString((int)Math.Round(speed * 0.621371192)); //speed check on zone // OBS : speed limit defined in a geofence is alwats saved in km in the DB // OBS : spped received from the message bus is always in KM/H if ((position == 2) && (obj2.speed > 0) && (obj2.speed < speed)) { if (obj2.speedUnit.Equals("m")) Speedtoproccess = (obj2.speed / 0.621371) + "_m"; else Speedtoproccess = obj2.speed.ToString() + "_k"; } //end speed check in zone if (tmpresp.Length > 1) { if (obj2.AlarmType == 3) validAlarm = true; else if ((obj2.AlarmType == 1) && (position == 2)) validAlarm = true; else if ((obj2.AlarmType == 2) && (position == 1)) validAlarm = true; else if (obj2.AlarmType == 4) validAlarm = false; if (validAlarm) { DBalarm.Insert_Zone_Alarm(((Vehicle_Data)MainForm.VehList[radioID.ToString()]).sc_id, time, obj2.zone_id, obj2.action, true); // send Alert by email if the emailServer is configured if (Program.cfg.enableEmailService && !String.IsNullOrEmpty(Program.cfg.emailAddress) && !String.IsNullOrEmpty(mailAdr)) { string veh_name = ((Vehicle_Data)MainForm.VehList[radioID.ToString()]).Name; string speed_km_or_mph = obj2.speedUnit.Equals("k") ? $"{speed} km/h" : $"{speedMiles} mph"; string message = $"Zone alarm for {veh_name} {tmpresp}. Unit speed {speed_km_or_mph} at time: {Utils.UnixTimeStampToDateTime(time).ToLocalTime()} [{cell.lat},{cell.lng} ]"; string title = $"Zone alarm for {veh_name}"; Task.Factory.StartNew(() => { sendAlarmMail(title, message, mailAdr); }); } String test = ""; if (sendOnMsgBus) { //send alarm on message buss test = "#136#" + radioID.ToString() + "#" + tmpresp + "#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test), SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test).Length); } String date = DateTime.Now.ToUniversalTime().DateTo70Format().ToString(); ///send SMS UnitSysPosition tmpX = null; if (obj2.sentmsg) { String listOfUnits = obj2.unitids; String listOfImeis = obj2.imeilist; String[] tmpunits = listOfUnits.Split(",".ToCharArray()); String[] tmpimeis = listOfImeis.Split(",".ToCharArray()); Hashtable tmpHashName = new Hashtable(); if (tmpunits.Count() > 1) { for (Int32 i = 0; i < tmpunits.Count() - 1; i++) tmpHashName.Add((String)tmpunits[i], (String)tmpimeis[i]); } foreach (String keyobj in tmpHashName.Keys) { int obj = -1; Int32.TryParse(keyobj, out obj); if (obj > -1 && sendOnMsgBus) { tmpX = dbvehs.getSystemPosition(Convert.ToInt32(keyobj)); test = "#142#" + tmpX.Gw_id + "." + tmpX.R_gw_id + "." + (String)tmpHashName[keyobj] + "#" + /*"Message from unit " + ((Vehicle_Data)MainForm.VehList[radioID.ToString()]).Name + " :" +*/ obj2.msgbody + "#" + date + "#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0." + date + test), SafeMobileLib.Utils.Convert_text_For_multicast("#0." + date + test).Length); Thread.Sleep(100); Utils.WriteLine($"Zone alert sms request [{obj2.msgbody}] for unit {(String)tmpHashName[keyobj]} on gw [{(tmpX.Gw_id + "." + tmpX.R_gw_id)}]"); } } } if (obj2.sentmsg2 && sendOnMsgBus) { tmpX = dbvehs.getSystemPositionIMEI(radioID); test = "#142#" + tmpX.Gw_id + "." + tmpX.R_gw_id + "." + radioID + "#" + obj2.msgbody2 + "#" + DateTime.Now.ToUniversalTime().DateTo70Format().ToString() + "#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0." + date + test), SafeMobileLib.Utils.Convert_text_For_multicast("#0." + date + test).Length); Utils.WriteLine($"Zone alert sms request [{obj2.msgbody2}] for unit {radioID} on gw [{(tmpX.Gw_id + "." + tmpX.R_gw_id)}]"); } //send Callout if(obj2.callout && tmpresp.ToString().Contains("IN ")) { tmpX = dbvehs.getSystemPositionIMEI(radioID); test = "#177#" + radioID.ToString() + "#" + obj2.calloutSeverity + "#" + obj2.name + "#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test), SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test).Length); callOutQueue.PostItem(new CallOut() { RadioID = radioID, Severity = obj2.calloutSeverity, Time = DateTime.Now}); Utils.WriteLine($"Zone CallOut request with Severity [{obj2.calloutSeverity}] for unit {radioID} on gw [{(tmpX.Gw_id + "." + tmpX.R_gw_id)}]"); } // send by email if the emailServer is configured if (Program.cfg.enableEmailService && obj2.sentemail) { Task.Factory.StartNew(() => { sendMailGeo(obj2.body, "Message from unit " + ((Vehicle_Data)MainForm.VehList[radioID.ToString()]).Name + ": " + obj2.subj, obj2.email); }); } } } } } if (landMArk) { foreach (LandMark obj2 in ((Vehicle_Data)MainForm.VehList[radioID.ToString()]).landlist) { String tmpresp = obj2.CheckPosition(lat, lng); String speedMiles = Convert.ToString((int)Math.Round(speed * 0.621371192)); if (tmpresp.Length > 1) { int sc_id = ((Vehicle_Data)MainForm.VehList[radioID.ToString()]).sc_id; // insert Alert into database Utils.WriteLine("Insert Landmarks Alarm " + radioID.ToString() + " " + sc_id); DBalarm.Insert_Zone_Alarm(sc_id, time, obj2.land_id, obj2.action, false); // send alert by email if the emailServer is configured if (Program.cfg.enableEmailService && !String.IsNullOrEmpty(Program.cfg.emailAddress) && !String.IsNullOrEmpty(mailAdr)) { string veh_name = ((Vehicle_Data)MainForm.VehList[radioID.ToString()]).Name; string speed_km_or_mph = obj2.speedUnit.Equals("k") ? $"{speed} km/h" : $"{speedMiles} mph"; string message = $"Landmark alarm for {veh_name} {tmpresp}. Unit speed {speed_km_or_mph} at time: {Utils.UnixTimeStampToDateTime(time).ToLocalTime()} [{cell.lat},{cell.lng} ]"; string title = $"Landmark alarm for {veh_name}"; Task.Factory.StartNew(() => { sendAlarmMail(title, message, mailAdr); }); } //send Alert on message buss if (sendOnMsgBus) { //send alarm on message buss string test = "#137#" + radioID.ToString() + "#" + tmpresp + "#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test), SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test).Length); } //send CallOut if(obj2.callout && tmpresp.ToString().Contains("IN ")) { string test = "#177#" + radioID + "#" + obj2.calloutSeverity + "#" + obj2.name + "#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test), SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test).Length); callOutQueue.PostItem(new CallOut() { RadioID = radioID, Severity = obj2.calloutSeverity, Time = DateTime.Now }); Utils.WriteLine($"Landmark CallOut request with Severity [{obj2.calloutSeverity}] for unit {radioID} "); } } } } } } } return Speedtoproccess; } private uint DateTo70Format(DateTime param) { long nOfSeconds; System.DateTime dt70 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); TimeSpan span = param - dt70; nOfSeconds = (long)span.TotalSeconds; return ((uint)nOfSeconds); } #region speed alarm private void processSpeedAlarm(string radioID, htCell_t cell, int speedTreshold, string speedUnits, string mailAdr, bool sendOnMsgBus) { DBalarmManager DBalarm = new DBalarmManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port); int treshold = (int)Convert.ToDouble(speedTreshold); if (speedUnits == "m") treshold = (int)(treshold * 1.609); int speed = (int)Convert.ToDouble(cell.spd); if (speed >= treshold) { uint time = DateTo70Format(cell.location_time); // insert alert into database DBalarm.Insert_Speed_Alarm(radioID, time, speed, cell.lat, cell.lng); //send Alert by email if EmailServer si configured if (Program.cfg.enableEmailService && !String.IsNullOrEmpty(mailAdr)) { int speedMiles = (int)Math.Round(speed * 0.621371192); string veh_name = ((Vehicle_Data)MainForm.VehList[radioID.ToString()]).Name; string speed_km_or_mph = (speedUnits != "m") ? $"{speed} km/h" : $"{speedMiles} mph"; string message = $"Speed alarm for {veh_name}. Unit speed {speed_km_or_mph} at time: {Utils.UnixTimeStampToDateTime(time).ToLocalTime()} [{cell.lat},{cell.lng}]"; string title = $"Speed alarm for unit {veh_name}"; Task.Factory.StartNew(() => { sendAlarmMail(title, message, mailAdr); }); } //send Alert on message buss if (sendOnMsgBus) { //send alarm on message buss string speed4send = $"{speed}_{speedUnits}"; string test = "#135#" + radioID.ToString() + "#" + speed4send + "#"; MainForm.udp.Send(SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test), SafeMobileLib.Utils.Convert_text_For_multicast("#0.0" + test).Length); } } } #endregion } }