2024-02-22 16:43:59 +00:00
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 < CallOut > callOutQueue ;
private DBsettingsManager DBSettings ;
private volatile Boolean BeforeWriteDB ;
private volatile LocationDecoder dec2 ;
private volatile DBsubsOperationManager dbsubsoperManage ;
private volatile DBvehiclesManager dbvehs ;
private DBvehiclesManager DBvehInfo ;
2024-06-13 11:03:34 +00:00
2024-02-22 16:43:59 +00:00
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 < CallOut > ( ) ;
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 < Vehicles > 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 ;
2024-06-06 10:05:24 +00:00
string [ ] tempArr = line . Split ( "#" . ToCharArray ( ) ) ;
2024-02-22 16:43:59 +00:00
//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 ;
2024-06-13 11:03:34 +00:00
bool zone = ( alarm . Zone ! = "" ) ;
bool landMark = ( alarm . Landmark ! = "" ) ;
2024-02-22 16:43:59 +00:00
2024-06-13 11:03:34 +00:00
String SpeedProccess = "" ;
2024-02-22 16:43:59 +00:00
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 ! = "" )
{
2024-06-06 10:05:24 +00:00
string [ ] temp = SpeedProccess . Split ( "_" . ToCharArray ( ) ) ;
2024-02-22 16:43:59 +00:00
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
{
2024-06-07 13:20:57 +00:00
// skip sending enable/disable if the unit is not in the vehicles list
2024-02-22 16:43:59 +00:00
if ( ! MainForm . VehList . ContainsKey ( radioID2 ) )
{
continue ;
}
2024-07-01 14:39:01 +00:00
2024-02-22 16:43:59 +00:00
//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#" ;
2024-07-01 14:39:01 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0" + test2 ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
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 )
{
2024-06-06 10:05:24 +00:00
VehicleStatus vehicleStatus = ( VehicleStatus ) MainForm . VehicleHashStat [ radioID2 ] ;
2024-02-22 16:43:59 +00:00
//MADE ON status when is the case
2024-06-06 10:05:24 +00:00
if ( ( vehicleStatus . curentStatus = = Status_for_tab . MADEOFF )
| | ( vehicleStatus . curentStatus = = Status_for_tab . OFF ) )
2024-02-22 16:43:59 +00:00
{
2024-06-06 10:05:24 +00:00
vehicleStatus . curentStatus = Status_for_tab . MADEON ;
2024-02-22 16:43:59 +00:00
PushStatus ( radioID2 , Status_for_tab . MADEON ) ;
}
// update last status location and position time
2024-06-06 10:05:24 +00:00
vehicleStatus . lastPositionTime = DateTime . Now ;
vehicleStatus . lat = dec2 . cell . d_lat ;
vehicleStatus . lng = dec2 . cell . d_lng ;
2024-02-22 16:43:59 +00:00
// do not push any status update if the current status is emergency
2024-06-06 10:05:24 +00:00
if ( vehicleStatus . curentStatus ! = Status_for_tab . EMERG )
2024-02-22 16:43:59 +00:00
{
if ( dec2 . cell . lat ! = "0" & & dec2 . cell . lat ! = "0.00000" )
{
2024-06-06 10:05:24 +00:00
if ( vehicleStatus . curentStatus ! = Status_for_tab . GPS_ON )
2024-02-22 16:43:59 +00:00
{
2024-06-06 10:05:24 +00:00
vehicleStatus . curentStatus = Status_for_tab . GPS_ON ;
2024-02-22 16:43:59 +00:00
//SM.Debug("Push Status GPS ON for radio:"+radioID2);
PushStatus ( radioID2 , Status_for_tab . GPS_ON ) ;
}
}
else
{
2024-06-06 10:05:24 +00:00
if ( vehicleStatus . curentStatus ! = Status_for_tab . NOGPSFIX )
2024-02-22 16:43:59 +00:00
{
2024-06-06 10:05:24 +00:00
vehicleStatus . curentStatus = Status_for_tab . NOGPSFIX ;
2024-02-22 16:43:59 +00:00
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#" ;
2024-07-01 14:39:01 +00:00
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#" ;
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0" + test2 ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
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 + "#" ;
2024-07-01 14:39:01 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0" + test ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
Utils . WriteLine ( $"Sent CallOut Stop request with Severity [{callout.Severity}] for unit {callout.RadioID.ToString()} " ) ;
}
}
}
}
}
private void sendMailGeo ( string mes , String subj , string mailAdr )
{
2024-06-07 13:20:57 +00:00
2024-06-13 11:03:34 +00:00
if ( Program . cfg . enableEmailService )
2024-02-22 16:43:59 +00:00
{
2024-06-13 11:03:34 +00:00
if ( ! String . IsNullOrEmpty ( Program . cfg . emailAddress ) & & ! String . IsNullOrEmpty ( mailAdr ) )
2024-06-12 15:18:20 +00:00
{
2024-06-13 11:03:34 +00:00
if ( MainForm . IsBlacklistedAddress ( mailAdr ) )
{
2024-06-21 13:27:20 +00:00
Utils . WriteLine ( $"sendMailGeo : The email '{subj}' was not sent. Email address '{mailAdr}' is in blacklist count = {MainForm.blackListAddress[mailAdr]}" ) ;
2024-06-13 11:03:34 +00:00
return ;
}
2024-06-12 15:18:20 +00:00
2024-06-13 11:03:34 +00:00
try
2024-02-22 16:43:59 +00:00
{
2024-06-13 11:03:34 +00:00
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 )
2024-06-07 13:20:57 +00:00
{
2024-06-13 11:03:34 +00:00
Boolean skipeFirst = true ;
foreach ( String obj in address )
{
if ( skipeFirst )
{ skipeFirst = false ; }
else
message . To . Add ( new MailAddress ( obj ) ) ;
}
2024-06-07 13:20:57 +00:00
}
2024-06-13 11:03:34 +00:00
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 )
{
2024-06-21 13:27:20 +00:00
if ( ex . ToString ( ) . Contains ( "timed out" ) | |
ex . ToString ( ) . Contains ( "the client was not authenticated" ) )
2024-06-13 11:03:34 +00:00
MainForm . HandleTimeoutError ( mailAdr ) ;
Utils . WriteLine ( $"Exception in sendMailGeo: {ex.ToString()}" ) ;
2024-02-22 16:43:59 +00:00
}
2024-06-07 13:20:57 +00:00
}
2024-06-13 11:03:34 +00:00
else
2024-06-07 13:20:57 +00:00
{
2024-06-13 11:03:34 +00:00
Utils . WriteLine ( $"Missing email address From = {Program.cfg.emailAddress} To = {mailAdr})" , ConsoleColor . Cyan ) ;
2024-02-22 16:43:59 +00:00
}
}
2024-06-07 13:20:57 +00:00
else
2024-02-22 16:43:59 +00:00
{
2024-06-07 13:20:57 +00:00
Utils . WriteLine ( "Email Server not Set" , ConsoleColor . Cyan ) ;
2024-02-22 16:43:59 +00:00
}
2024-06-07 13:20:57 +00:00
2024-02-22 16:43:59 +00:00
}
2024-06-13 11:03:34 +00:00
2024-02-22 16:43:59 +00:00
private void sendAlarmMail ( string title , string mes , string mailAdr )
{
2024-06-13 11:03:34 +00:00
if ( Program . cfg . enableEmailService )
2024-02-22 16:43:59 +00:00
{
2024-06-13 11:03:34 +00:00
if ( ! String . IsNullOrEmpty ( Program . cfg . emailAddress ) & & ! String . IsNullOrEmpty ( mailAdr ) )
2024-06-12 15:18:20 +00:00
{
2024-06-13 11:03:34 +00:00
if ( MainForm . IsBlacklistedAddress ( mailAdr ) )
{
2024-06-21 13:27:20 +00:00
Utils . WriteLine ( $" sendAlarmMail : The email '{title}' was not sent. Email address '{mailAdr}' is in blacklist count = {MainForm.blackListAddress[mailAdr]}" ) ;
2024-06-13 11:03:34 +00:00
return ;
}
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 )
{
2024-06-21 13:27:20 +00:00
if ( ex . ToString ( ) . Contains ( "timed out" ) | |
ex . ToString ( ) . Contains ( "the client was not authenticated" ) )
2024-06-13 11:03:34 +00:00
MainForm . HandleTimeoutError ( mailAdr ) ;
Utils . WriteLine ( "Exception in sendMailAlarm2: {0}" + ex . ToString ( ) , ConsoleColor . Red ) ;
}
2024-02-22 16:43:59 +00:00
}
2024-06-13 11:03:34 +00:00
else
2024-02-22 16:43:59 +00:00
{
2024-06-13 11:03:34 +00:00
Utils . WriteLine ( $"Missing email address From = {Program.cfg.emailAddress} To = {mailAdr})" , ConsoleColor . Cyan ) ;
2024-02-22 16:43:59 +00:00
}
}
else
{
2024-06-12 15:18:20 +00:00
Utils . WriteLine ( "Email Server not Set" , ConsoleColor . Cyan ) ;
2024-02-22 16:43:59 +00:00
}
2024-06-12 15:18:20 +00:00
}
2024-02-22 16:43:59 +00:00
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 ;
2024-06-06 10:05:24 +00:00
2024-02-22 16:43:59 +00:00
if ( validAlarm )
{
2024-06-07 13:20:57 +00:00
2024-02-22 16:43:59 +00:00
DBalarm . Insert_Zone_Alarm ( ( ( Vehicle_Data ) MainForm . VehList [ radioID . ToString ( ) ] ) . sc_id , time , obj2 . zone_id , obj2 . action , true ) ;
2024-06-07 13:20:57 +00:00
// 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}" ;
2024-02-22 16:43:59 +00:00
2024-06-06 10:05:24 +00:00
Task . Factory . StartNew ( ( ) = >
2024-02-22 16:43:59 +00:00
{
2024-06-06 10:05:24 +00:00
sendAlarmMail ( title , message , mailAdr ) ;
} ) ;
2024-02-22 16:43:59 +00:00
}
2024-06-06 10:05:24 +00:00
2024-02-22 16:43:59 +00:00
String test = "" ;
if ( sendOnMsgBus )
{
//send alarm on message buss
test = "#136#" + radioID . ToString ( ) + "#" + tmpresp + "#" ;
2024-07-01 14:39:01 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0" + test ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
2024-06-07 13:20:57 +00:00
2024-02-22 16:43:59 +00:00
String date = DateTime . Now . ToUniversalTime ( ) . DateTo70Format ( ) . ToString ( ) ;
///send SMS
UnitSysPosition tmpX = null ;
if ( obj2 . sentmsg )
{
String listOfUnits = obj2 . unitids ;
String listOfImeis = obj2 . imeilist ;
2024-06-06 10:05:24 +00:00
String [ ] tmpunits = listOfUnits . Split ( "," . ToCharArray ( ) ) ;
String [ ] tmpimeis = listOfImeis . Split ( "," . ToCharArray ( ) ) ;
2024-02-22 16:43:59 +00:00
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 ] ) ;
}
2024-06-06 10:05:24 +00:00
2024-02-22 16:43:59 +00:00
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 + "#" ;
2024-07-01 14:39:01 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0." + date + test ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-06-07 13:20:57 +00:00
Thread . Sleep ( 100 ) ;
2024-02-22 16:43:59 +00:00
Utils . WriteLine ( $"Zone alert sms request [{obj2.msgbody}] for unit {(String)tmpHashName[keyobj]} on gw [{(tmpX.Gw_id + " . " + tmpX.R_gw_id)}]" ) ;
}
}
}
2024-06-06 10:05:24 +00:00
2024-02-22 16:43:59 +00:00
if ( obj2 . sentmsg2 & & sendOnMsgBus )
{
tmpX = dbvehs . getSystemPositionIMEI ( radioID ) ;
2024-07-01 14:39:01 +00:00
test = "#142#" + tmpX . Gw_id + "." + tmpX . R_gw_id + "." + radioID + "#" + obj2 . msgbody2 + "#" + DateTime . Now . ToUniversalTime ( ) . DateTo70Format ( ) . ToString ( ) + "#" ;
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0." + date + test ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
Utils . WriteLine ( $"Zone alert sms request [{obj2.msgbody2}] for unit {radioID} on gw [{(tmpX.Gw_id + " . " + tmpX.R_gw_id)}]" ) ;
}
2024-06-06 10:05:24 +00:00
2024-02-22 16:43:59 +00:00
//send Callout
if ( obj2 . callout & & tmpresp . ToString ( ) . Contains ( "IN " ) )
{
tmpX = dbvehs . getSystemPositionIMEI ( radioID ) ;
test = "#177#" + radioID . ToString ( ) + "#" + obj2 . calloutSeverity + "#" + obj2 . name + "#" ;
2024-07-01 14:39:01 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0." + test ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
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)}]" ) ;
}
2024-06-06 10:05:24 +00:00
2024-06-07 13:20:57 +00:00
// send by email if the emailServer is configured
if ( Program . cfg . enableEmailService & & obj2 . sentemail )
2024-02-22 16:43:59 +00:00
{
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 )
{
2024-06-06 10:05:24 +00:00
2024-06-07 13:20:57 +00:00
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 ) )
2024-02-22 16:43:59 +00:00
{
2024-06-07 13:20:57 +00:00
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}" ;
2024-06-06 10:05:24 +00:00
Task . Factory . StartNew ( ( ) = >
2024-02-22 16:43:59 +00:00
{
2024-06-06 10:05:24 +00:00
sendAlarmMail ( title , message , mailAdr ) ;
} ) ;
2024-02-22 16:43:59 +00:00
}
2024-06-07 13:20:57 +00:00
//send Alert on message buss
2024-02-22 16:43:59 +00:00
if ( sendOnMsgBus )
{
//send alarm on message buss
string test = "#137#" + radioID . ToString ( ) + "#" + tmpresp + "#" ;
2024-07-01 14:39:01 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0" + test ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
2024-06-07 13:20:57 +00:00
2024-02-22 16:43:59 +00:00
//send CallOut
if ( obj2 . callout & & tmpresp . ToString ( ) . Contains ( "IN " ) )
{
string test = "#177#" + radioID + "#" + obj2 . calloutSeverity + "#" + obj2 . name + "#" ;
2024-07-01 14:39:01 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0" + test ) ;
MainForm . udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
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 ) ;
2024-06-06 10:40:08 +00:00
int treshold = ( int ) Convert . ToDouble ( speedTreshold ) ;
if ( speedUnits = = "m" )
treshold = ( int ) ( treshold * 1.609 ) ;
2024-06-07 13:20:57 +00:00
int speed = ( int ) Convert . ToDouble ( cell . spd ) ;
if ( speed > = treshold )
2024-02-22 16:43:59 +00:00
{
2024-06-07 13:20:57 +00:00
uint time = DateTo70Format ( cell . location_time ) ;
// insert alert into database
DBalarm . Insert_Speed_Alarm ( radioID , time , speed , cell . lat , cell . lng ) ;
2024-06-06 10:05:24 +00:00
2024-06-07 13:20:57 +00:00
//send Alert by email if EmailServer si configured
if ( Program . cfg . enableEmailService & & ! String . IsNullOrEmpty ( mailAdr ) )
{
2024-06-06 10:05:24 +00:00
2024-06-07 13:20:57 +00:00
int speedMiles = ( int ) Math . Round ( speed * 0.621371192 ) ;
string veh_name = ( ( Vehicle_Data ) MainForm . VehList [ radioID . ToString ( ) ] ) . Name ;
2024-06-06 10:40:08 +00:00
string speed_km_or_mph = ( speedUnits ! = "m" ) ? $"{speed} km/h" : $"{speedMiles} mph" ;
2024-06-07 13:20:57 +00:00
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}" ;
2024-02-22 16:43:59 +00:00
2024-06-07 13:20:57 +00:00
Task . Factory . StartNew ( ( ) = >
2024-02-22 16:43:59 +00:00
{
2024-06-07 13:20:57 +00:00
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 + "#" ;
2024-07-01 14:39:01 +00:00
2024-06-13 11:03:34 +00:00
MainForm . udp . Send ( Utils . Convert_text_For_multicast ( "#0.0" + test ) , Utils . Convert_text_For_multicast ( "#0.0" + test ) . Length ) ;
2024-02-22 16:43:59 +00:00
}
}
2024-06-07 13:20:57 +00:00
2024-02-22 16:43:59 +00:00
}
#endregion
}
}