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); ?>