0059AC0000160010138121624c5267bbe002e905001db214d0000c302013d00000000000000aa60024e3833510059AC01-57.00000014.0000007G0LC52FF010119051.8968585.085886FF0101190-57.00000014.000000-57.169544080E024B0-111.0000005.500000-112.078331100006259{"alr":{"pro":"SMTC/LoRaMote","ver":"1"}}014000DFC'
n1cx_data geo position: 7CC6C40114002573140025730059AC01002018-01-13T19:10:57.560+01:0052.2629516.8103450.0000000.0000000.0000000.000000100006259
cgps_tcp_data
Binary data in the same format that a conventional TraceME with IMEI/GSM modem uses for the "%b" marker in the TCP data format. So you can feed this binary data to the SetTcpData() method of the CGPS class.
// JUST SOME THOUGHTS FROM PIETER
// Imagine you received N1Cx data that contains properties with
// accel(erometer)-sensor and temperature values and automatic
// conversion above generates a SV_PositionAcceleration record with
// g-forces but can not hold temperature.
// But if you specifically want an SV_Position record instead because
// that can, you could do something like this:
$Switch = -1; // This is the automatically determine mode.
if ($cN1Cx_data->CanGetProperty(’temp’)) // Has temperature property?
$Switch = SV_Position; // Specifically this one, not automatic.
$CgpsDataBytes = $cN1Cx_data->ConvertCGPS($Switch);
// You could even use ConvertCGPS() multiple times if you want to.
// And should you want to generate a single HTTP compatible data string
// from the resulting ones, then simple trim all digits from the
// beginning of
*/
// Set logging TRUE or FALSE:
$Logging = TRUE;
//DEFINE LOGFILE
$LogFileName = "lora_decode_example.dat";
//cgps_class
require 'cgps.php';
//n1cx_class
require 'N1Cx_data.php';
if(!defined('PHP_EOL')) define('PHP_EOL', "\r\n");
function LogMessage($LogInfo)
{
global $LogFileName, $Logging;
if ($Logging == TRUE){
//This function writes messages to the error log file of which you can set the file name above.
//Notice the usage of the @ character in this function and throughout the source code
//(and the rest of this script) to suppress any possible HTML error/warning output,
//because otherwise it will be sent to a transmitting module and not appear on some screen.
for($Retries=0;$Retries<5;$Retries++) //Do some retries if the file is already in use
{
$hFile=@fopen($LogFileName, 'a'); //Create new file, or append to existing one
if($hFile)
{
$Log='###' . date('r', time()) . '### ' . $LogInfo . PHP_EOL;
@fwrite($hFile, $Log);
@fclose($hFile);
return true;
}
}
return false;
}
}
function fakeimei($device,$decode_type)
{
//if decode_type = 1 deveui
//if decode_type = 2 devaddr
// Generate fake IMEI of the hexadecimal text.
if ($decode_type == 1)
{
$fakeIMEI = N1Cx_data::GenerateFakeIMEI($DevEUI);
}
if ($decode_type == 2)
{
$fakeIMEI = N1Cx_data::GenerateFakeIMEI($DevAddr, "999", 2);
}
return;
}
function getcgpsinfo($cCGPS)
{
Global $HttpCompatibleDataString;
Global $cgps_Timestamp;
Global $cgps_Latitude;
Global $cgps_Longitude;
Global $cgps_Heading;
Global $cgps_Speed;
Global $cgps_IO;
Global $cgps_Temperature;
Global $cgps_Battery;
Global $cgps_Accelx;
Global $cgps_Accely;
Global $cgps_Accelz;
Global $cgps_UserCounter0;
Global $cgps_UserCounter1;
Global $cgps_UserCounter2;
Global $cgps_UserCounter3;
Global $cgps_UserCounter4;
//http datastring
$HttpCompatibleDataString = $cCGPS->GetHttpData();
//timestamp
$cgps_Timestamp = $cCGPS->GetUtcTime();
//latlong
if ($cCGPS->CanGetLatLong())
{
$cgps_Latitude = $cCGPS->GetLatitudeFloat();
$cgps_Longitude =$cCGPS->GetLongitudeFloat();
}
//heading
if ($cCGPS->CanGetHeading())
{
$cgps_Heading = $cCGPS->GetHeading();
}
//speed
if ($cCGPS->CanGetSpeed())
{
$cgps_Speed = $cCGPS->GetSpeedKPH();
}
//io
if ($cCGPS->CanGetIO())
{
$cgps_SIO = $cCGPS->GetIO();
}
//temperature
if ($cCGPS->CanGetTemperature())
{
$cgps_Temperature = round($cCGPS->GetTemperatureCelcius(),1);
}
//battery
if ($cCGPS->CanGetAccu())
{
$cgps_Battery = round($cCGPS->GetAccu(),2);
}
//acceleration
if ($cCGPS->CanGetAccelerationX())
{
$cgps_Accelx = $cCGPS->GetAccelerationX();
$cgps_Accely = $cCGPS->GetAccelerationY();
$cgps_Accelz = $cCGPS->GetAccelerationZ();
}
//usercounter
/* - CounterNumber: The number value of the counter from which you
want to retrieve the value from the current record of which
the following counters can be retrieved:
-1: "Block offset" of the record (see notes for detailed info).
0: Reading of the first 32bit counter in the record.
1: Reading of the second 32bit counter in the record.
2: Reading of the third 32bit counter in the record.
3: Reading of the fourth 32bit counter in the record.
4: Reading of the fifth 32bit counter in the record.
*/
if ($cCGPS->CanGetUserCounter())
{
$cgps_UserCounter0 = $cCGPS->GetUserCounter(0);
$cgps_UserCounter1 = $cCGPS->GetUserCounter(1);
$cgps_UserCounter2 = $cCGPS->GetUserCounter(2);
$cgps_UserCounter3 = $cCGPS->GetUserCounter(3);
$cgps_UserCounter4 = $cCGPS->GetUserCounter(4);
}
return;
}
function getn1cxinfo($cN1cx_data)
{
Global $Payload_Identifier;
Global $Payload_Timestamp;
Global $Payload_Latitude;
Global $Payload_Longitude;
Global $Payload_Heading;
Global $Payload_Speed;
Global $Payload_Battery;
Global $Payload_IO;
Global $Payload_Temperature;
Global $Payload_Accelx;
Global $Payload_Accely;
Global $Payload_Accelz;
Global $SW1;
Global $RXDpin;
Global $MovingStatus;
Global $IO31;
Global $Bit4;
Global $RF_Position;
Global $Gps5SecOld;
Global $LastFrameAck;
Global $Payload_Compassx;
Global $Payload_Compassy;
Global $Payload_Compassz;
Global $bit0;
Global $bit1;
Global $bit2;
Global $bit3;
Global $bit4;
Global $bit5;
Global $bit6;
Global $bit7;
//getidentifier
if ($cN1cx_data->CanGetProperty("identifier"))
{
$Payload_Identifier = $cN1cx_data->GetProperty("identifier", null);
}
//gettimestap
if ($cN1cx_data->CanGetProperty("timestamp"))
{
$Payload_Timestamp = $cN1cx_data->GetProperty("timestamp", null);
}
//getlatlon
if ($cN1cx_data->CanGetProperty("latitude"))
{
$Payload_Latitude = $cN1cx_data->GetProperty("latitude", null);
$Payload_Longitude = $cN1cx_data->GetProperty("longitude", null);
}
//getio
if ($cN1cx_data->CanGetProperty("IO"))
{
$Payload_IO = $cN1cx_data->GetProperty("IO", null);
//LogMessage("Payload_IO: ".$Payload_IO);
//>>> status of IO of board and internal flags.
//>>> bit0 = SW1;
//>>> bit1 = UART RXD pin;
//>>> bit2 = unit is moving (copy of IO0)
//>>> bit3 = copy of IO31
//>>> bit4 = undefined
//>>> bit5 = RF position
//>>> bit6 = GPS info are older than 5s
//>>> bit7 = last frame was acked by network;
$bit0 = ($Payload_IO & 1)/1;
$bit1 = ($Payload_IO & 2)/2;
$bit2 = ($Payload_IO & 4)/4;
$bit3 = ($Payload_IO & 8)/8;
$bit4 = ($Payload_IO & 16)/16;
$bit5 = ($Payload_IO & 32)/32;
$bit6 = ($Payload_IO & 64)/64;
$bit7 = ($Payload_IO & 128)/128;
$SW1 = $bit0;
$RXDpin = $bit1;
$MovingStatus = $bit2;
$IO31 = $bit3;
$Bit4 = $bit4;
$RF_Position = $bit5;
$Gps5SecOld = $bit6;
$LastFrameAck = $bit7;
}
//getspeed
if ($cN1cx_data->CanGetProperty("speed"))
{
$Payload_Speed = $cN1cx_data->GetProperty("speed", null);
}
//getheading
if ($cN1cx_data->CanGetProperty("heading"))
{
$Payload_Heading = $cN1cx_data->GetProperty("heading", null);
}
//get accel_x,y,z
if ($cN1cx_data->CanGetProperty("accelX"))
{
$Payload_Accelx = $cN1cx_data->GetProperty("accelX", null);
$Payload_Accely = $cN1cx_data->GetProperty("accelY", null);
$Payload_Accelz = $cN1cx_data->GetProperty("accelZ", null);
}
//get compas,x,y,z
if ($cN1cx_data->CanGetProperty("compassX"))
{
$Payload_Compassx = $cN1cx_data->GetProperty("compassX", null);
$Payload_Compassy = $cN1cx_data->GetProperty("compassY", null);
$Payload_Compassz = $cN1cx_data->GetProperty("compassZ", null);
}
//temperature
if ($cN1cx_data->CanGetProperty("temp"))
{
$Payload_Temperature = $cN1cx_data->GetProperty("temp", null);
}
//battery
if ($cN1cx_data->CanGetProperty("battery"))
{
$Payload_Battery = $cN1cx_data->GetProperty("battery", null);
}
return;
}
function showinfo($label,$screendata)
{
if(isset($_GET['showinfo']) && $_GET['showinfo'] == 1)
{
echo $label.": ".$screendata." ";
}
return;
}
function hextobin($hexstr)
{
$n = strlen($hexstr);
$sbin="";
$i=0;
while($i<$n)
{
$a =substr($hexstr,$i,2);
$c = pack("H*",$a);
if ($i==0){$sbin=$c;}
else {$sbin.=$c;}
$i+=2;
}
return $sbin;
}
$Data = file_get_contents('php://input');
//LogMessage("Data :".$Data);
$recordtype=0;
//explode xml datastring to array
//lorawan data: DevEUI_uplink = data from tag
//lorawan geo: DevEUI_location
$datajson = json_decode($Data,true);
if (array_key_exists('DevEUI_location', $datajson))
{
//LogMessage($Data);
$LoraLatitude = $datajson['DevEUI_location']['DevLAT'];
$LoraLongitude = $datajson['DevEUI_location']['DevLON'];
$LoraRadius = $datajson['DevEUI_location']['DevLocRadius'];
$DevEUI = $datajson['DevEUI_location']['DevEUI'];
$DevAddr = $datajson['DevEUI_location']['DevAddr'];
//LogMessage("location2: ".$LoraLatitude." ".$LoraLongitude." ".$LoraRadius." ".$DevEUI." ".$DevAddr);
}
else
{
//LogMessage("nothing");
}
if (array_key_exists('DevEUI_uplink', $datajson))
{
//LogMessage($Data);
$LoraLrrLatitude = $datajson['DevEUI_uplink']['LrrLAT'];
$LoraLrrLongitude = $datajson['DevEUI_uplink']['LrrLON'];
$LoraLrcid = $datajson['DevEUI_uplink']['Lrcid'];
$DevEUI = $datajson['DevEUI_uplink']['DevEUI'];
$DevAddr = $datajson['DevEUI_uplink']['DevAddr'];
$Payload_hex = $datajson['DevEUI_uplink']['payload_hex'];
//LogMessage("uplink2: ".$LoraLrrLatitude." ".$LoraLrrLongitude." ".$LoraLrcid." ".$DevEUI." ".$DevAddr." ".$Payload_hex);
//now that payload is known, the payload type can be n1cx_data or tm_data.
//decode the payload and put variables in where possible
//check if data is standard n1cx
$cN1cx_data = new N1Cx_data();
$BinaryPayload = hextobin($Payload_hex);
//check if it is standard n1cx record
if ($cN1cx_data->SetData($BinaryPayload))
{
getn1cxinfo($cN1cx_data);
//LogMessage("IO DATA: ".$bit7.$bit6.$bit5.$bit4.$bit3.$bit2.$bit1.$bit0);
//LogMessage("Identifier: ".$Payload_Identifier);
//LogMessage("accel: ".$Payload_Accelx." ".$Payload_Accely." ".$Payload_Accelz);
//LogMessage("compass: ".$Payload_Compassx." ".$Payload_Compassy." ".$Payload_Compassz);
//identifier D0=208 TM-record , D2=210 TM-record, 36 = N1cX record.
//if not 36, then it is a TM record layout. put it in the cgps class after convert.
//data can be converted if needed to cgps.. but only if you need it in cgps format with imei.. also requires fake imei
//$CgpsData = $cN1cx_data->ConvertCGPS();
}
//check if data is tm_data (user counter / serial data / tm_record ), then create fake imei and load in class
//if deveui exists, generate fakeimei from that.. otherwise from devaddr
if ($Payload_Identifier == 208 OR $Payload_Identifier == 210)
{
//LogMessage("DATA is TM compatible");
if (isset($DevEUI))
{
//LogMessage("deveui tm is SET >>>>>>>>>>>>>>>".$DevEUI);
// if needed create fakeimei based upon deveui
$imei = $cN1cx_data->GenerateFakeIMEI($DevEUI);
//LogMessage("DevEUI FakeImei is ".$imei);
}
else
{
if (isset($DevAddr))
{
//LogMessage("devaddr tm is SET >>>>>>>>>>>>>>>".$DevAddr);
// if needed create fakeimei based upon devaddr
$imei = $cN1cx_data->GenerateFakeIMEI($DevAddr, "999", 2);
//LogMessage("Devaddr FakeImei is".$imei);
}
}
//create an instance of the cgps class
$cCGPS = new CGPS();
$CgpsDataBytes = $cN1cx_data->ConvertCGPS();
//Conversion successful?
if (strlen($CgpsDataBytes) != 0)
{
if ($cCGPS->SetBinaryData($imei, $CgpsDataBytes))
{
//CGPS class accepted the data, so now you can use its methods as usual to inspect it and retrieve info like:
//get the variables
$ValidOrNot = $cCGPS->IsValid();
getcgpsinfo($cCGPS);
//LogMessage("HTTP: ".$HttpCompatibleDataString);
//LogMessage("Time: ".$cgps_Timestamp);
//LogMessage("Lat: ".$cgps_Latitude);
//LogMessage("Lon: ".$cgps_Longitude);
//LogMessage("Head: ".$cgps_Heading);
//LogMessage("Speed: ".$cgps_Speed);
//LogMessage("IO: ".$cgps_IO);
//LogMessage("Temp: ".$cgps_Temperature);
//LogMessage("Bat: ".$cgps_Battery);
//LogMessage("Accelx: ".$cgps_Accelx);
//LogMessage("Accely: ".$cgps_Accely);
//LogMessage("Accelz: ".$cgps_Accelz);
//LogMessage("CTR0: ".$cgps_UserCounter0);
//LogMessage("CTR1: ".$cgps_UserCounter1);
//LogMessage("CTR2: ".$cgps_UserCounter2);
//LogMessage("CTR3: ".$cgps_UserCounter3);
//LogMessage("CTR4: ".$cgps_UserCounter4);
}
else
{
//CGPS class rejected the data, so get the problem
//description text that was set.
LogMessage("CGPS class rejection: " . $cCGPS->GetLastError());
}
}
else
{
LogMessage("datastring error");
}
}
}
else
{
//LogMessage("nothing");
}
LogMessage("DevEui: ".$DevEUI." DevAddr: ".$DevAddr." Imei: ".$imei." Data: ".$Data);
?>