543 lines
21 KiB
PHP
543 lines
21 KiB
PHP
<?php
|
|
include("./connect_iot.php");
|
|
|
|
$methode = $_SERVER['REQUEST_METHOD'];
|
|
$debug = true;
|
|
$file = 'log_g2h_rs_'.date("Y-m-d").'.txt';
|
|
$seqNumber = getseqno();
|
|
|
|
$inputstream = file_get_contents('php://input');
|
|
|
|
if($debug) {
|
|
file_put_contents($file, $inputstream, FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
$daten = json_decode($inputstream, true);
|
|
|
|
switch ($methode) {
|
|
case 'GET':
|
|
$response = array(
|
|
'status' => 0,
|
|
'status_message' => 'Methode GET nicht erlaubt.'
|
|
);
|
|
break;
|
|
|
|
case 'POST':
|
|
$daten = json_decode(file_get_contents('php://input'), true);
|
|
|
|
if($debug) {
|
|
file_put_contents($file, "\n\nProcessing POST request\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
// Skip downlink confirmations - only process uplink messages with sensor data
|
|
if(!isset($daten['objectJSON']) && !isset($daten['object'])) {
|
|
if($debug) {
|
|
file_put_contents($file, "Skipping - no sensor data (likely downlink confirmation)\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
$response = array(
|
|
'status' => 200,
|
|
'status_message' => 'downlink confirmation processed'
|
|
);
|
|
break;
|
|
}
|
|
|
|
// Initialize variables
|
|
$heating = '';
|
|
$heatingFloor = '';
|
|
$airHumidity = '';
|
|
$switch = '';
|
|
|
|
// Extract data from decoded payload
|
|
$mesg = array();
|
|
if(isset($daten['object'])) {
|
|
$mesg = $daten['object'];
|
|
} elseif(isset($daten['objectJSON'])) {
|
|
$mesg = json_decode($daten['objectJSON'], true);
|
|
}
|
|
|
|
if(!empty($mesg)) {
|
|
if(isset($mesg['heating'])) {
|
|
$heating = $mesg['heating'];
|
|
}
|
|
|
|
if(isset($mesg['heatingFloor'])) {
|
|
$heatingFloor = $mesg['heatingFloor'];
|
|
}
|
|
|
|
if(isset($mesg['airHumidity'])) {
|
|
$airHumidity = $mesg['airHumidity'];
|
|
}
|
|
|
|
if(isset($mesg['switch'])) {
|
|
$switch = $mesg['switch'];
|
|
}
|
|
}
|
|
|
|
// Energy tracking fields (nur bei 15-Byte Payload vorhanden)
|
|
$relayOnTime = isset($mesg['relayOnTime']) ? (int)$mesg['relayOnTime'] : null;
|
|
$uptime = isset($mesg['uptime']) ? (int)$mesg['uptime'] : null;
|
|
$loadWatts = isset($mesg['loadWatts']) ? (int)$mesg['loadWatts'] : null;
|
|
|
|
// Verbrauchsberechnung via DB-Tabelle g2h_rs_energy_tracking
|
|
$powerConsumptionWh = null;
|
|
if($relayOnTime !== null && $uptime !== null && $loadWatts !== null) {
|
|
$dbiot2 = new iotdbObj();
|
|
$conn2 = $dbiot2->getConnstring_iot();
|
|
$devId = mysqli_real_escape_string($conn2, $daten['deviceName']);
|
|
$row = mysqli_fetch_assoc(mysqli_query($conn2,
|
|
"SELECT relay_on_time, power_consumption_wh, UNIX_TIMESTAMP(updated_at) AS last_ts
|
|
FROM g2h_rs_energy_tracking WHERE device_id = '$devId'"));
|
|
|
|
$prevOnTime = $row ? (int)$row['relay_on_time'] : 0;
|
|
$prevWh = $row ? (float)$row['power_consumption_wh'] : 0.0;
|
|
$elapsed = $row ? (time() - (int)$row['last_ts']) : 0;
|
|
|
|
// Reboot-Erkennung: Uptime kleiner als vergangene Realzeit (60s Toleranz)
|
|
$reboot = ($row && $uptime < $elapsed - 60);
|
|
if($reboot) {
|
|
$delta = $relayOnTime; // Counter läuft seit Neustart von 0
|
|
} else {
|
|
$delta = max(0, $relayOnTime - $prevOnTime);
|
|
}
|
|
$powerConsumptionWh = round($prevWh + ($delta * $loadWatts) / 3600.0, 4);
|
|
|
|
mysqli_query($conn2,
|
|
"INSERT INTO g2h_rs_energy_tracking
|
|
(device_id, relay_on_time, power_consumption_wh)
|
|
VALUES ('$devId', $relayOnTime, $powerConsumptionWh)
|
|
ON DUPLICATE KEY UPDATE
|
|
relay_on_time = $relayOnTime,
|
|
power_consumption_wh = $powerConsumptionWh,
|
|
updated_at = CURRENT_TIMESTAMP");
|
|
}
|
|
|
|
// Extract time information
|
|
$time = 'TIME:';
|
|
if(isset($daten['rxInfo']['0']['time'])) {
|
|
$time .= date("U", strtotime($daten['rxInfo']['0']['time']));
|
|
} elseif(isset($daten['rxInfo']['time'])) {
|
|
$time .= date("U", strtotime($daten['rxInfo']['time']));
|
|
}
|
|
|
|
// Extract location information
|
|
$computedLocation = array();
|
|
if(isset($daten['rxInfo']['0']['location'])) {
|
|
$location = $daten['rxInfo']['0']['location'];
|
|
if(isset($location['latitude']) && isset($location['longitude'])) {
|
|
$computedLocation['lat'] = (float)$location['latitude'];
|
|
$computedLocation['lng'] = (float)$location['longitude'];
|
|
$computedLocation['radius'] = 20;
|
|
$computedLocation['source'] = 2;
|
|
$computedLocation['status'] = 1;
|
|
}
|
|
} elseif(isset($daten['rxInfo']['location'])) {
|
|
$location = $daten['rxInfo']['location'];
|
|
if(isset($location['latitude']) && isset($location['longitude'])) {
|
|
$computedLocation['lat'] = (float)$location['latitude'];
|
|
$computedLocation['lng'] = (float)$location['longitude'];
|
|
$computedLocation['radius'] = 2000;
|
|
$computedLocation['source'] = 2;
|
|
$computedLocation['status'] = 1;
|
|
}
|
|
}
|
|
|
|
$response = array(
|
|
'status' => 400,
|
|
'status_message' => 'success'
|
|
);
|
|
|
|
// Build JSON payload for IoT portal
|
|
$json = array();
|
|
$json['id'] = $daten['deviceName'];
|
|
|
|
if(isset($daten['importtime'])) {
|
|
$json['time'] = $daten['importtime'];
|
|
} else {
|
|
$json['time'] = time();
|
|
}
|
|
|
|
$json['computedLocation'] = $computedLocation;
|
|
$json['data'] = "G2H-RS-HTGS-LoRA";
|
|
|
|
// Map G2H-RS sensor data to IoT portal format
|
|
if($heating !== '') {
|
|
$json['heating'] = $heating;
|
|
}
|
|
|
|
if($heatingFloor !== '') {
|
|
$json['heatingFloor'] = $heatingFloor;
|
|
}
|
|
|
|
if($airHumidity !== '') {
|
|
$json['airHumidity'] = $airHumidity;
|
|
}
|
|
|
|
if($switch !== '') {
|
|
$json['switch'] = $switch;
|
|
}
|
|
|
|
if($relayOnTime !== null) $json['relayOnTime'] = $relayOnTime;
|
|
if($uptime !== null) $json['uptime'] = $uptime;
|
|
if($loadWatts !== null) $json['loadWatts'] = $loadWatts;
|
|
if($powerConsumptionWh !== null) $json['electricity'] = round($powerConsumptionWh / 1000, 6);
|
|
|
|
// Handle sequence number - use fCnt from ChirpStack if available
|
|
$seqNumber_dev = 1; // Default
|
|
|
|
if(isset($daten['fCnt']) && $daten['fCnt'] != '') {
|
|
// Use LoRaWAN frame counter as sequence number
|
|
$seqNumber_dev = (int)$daten['fCnt'];
|
|
} elseif(isset($mesg['seqno'])) {
|
|
// Use sequence number from decoded payload if available
|
|
$seqNumber_dev = (int)$mesg['seqno'];
|
|
} else {
|
|
// Fallback to internal counter
|
|
if(isset($seqNumber[$daten['deviceName']])) {
|
|
$seqNumber_dev = $seqNumber[$daten['deviceName']];
|
|
$seqNumber_dev++;
|
|
} else {
|
|
$seqNumber_dev = isset($seqNumber['1']) ? $seqNumber['1'] : 1;
|
|
$seqNumber_dev++;
|
|
}
|
|
$seqNumber[$daten['deviceName']] = $seqNumber_dev;
|
|
}
|
|
|
|
$json['seqNumber'] = (int)$seqNumber_dev;
|
|
$json['lqi'] = "Good";
|
|
$json['decoderClass'] = "G2HRoomSensor";
|
|
$json['countrycode'] = "276";
|
|
|
|
// Skip sending if sequence number is 1 (initialization)
|
|
if($json['seqNumber'] == '1') {
|
|
if($debug) {
|
|
file_put_contents($file, "\n\nSkipping send - seqNumber is 1\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($file, json_encode($json), FILE_APPEND | LOCK_EX);
|
|
}
|
|
} else {
|
|
// Send to IoT portal
|
|
$json_encoded = json_encode($json);
|
|
|
|
if($debug) {
|
|
file_put_contents($file, "\n\nSending to IoT portal:\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($file, $json_encoded, FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
$url = 'https://iot.satspeed.com/api/public/message';
|
|
$headers = array(
|
|
'Accept: application/json',
|
|
'Content-Type: application/json'
|
|
);
|
|
|
|
$curl = curl_init();
|
|
curl_setopt($curl, CURLOPT_POST, true);
|
|
curl_setopt($curl, CURLOPT_POSTFIELDS, $json_encoded);
|
|
curl_setopt($curl, CURLOPT_URL, $url);
|
|
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
|
|
|
|
$response = curl_exec($curl);
|
|
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
|
curl_close($curl);
|
|
|
|
if($debug) {
|
|
file_put_contents($file, "\n\nResponse code: " . $code . "\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($file, "Response: " . $response . "\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
// AUTO-DOWNLINK: Send settings-based downlink after successful uplink processing
|
|
if($code == 200) {
|
|
sendAutomaticDownlink($daten['deviceName'], $daten['devEUI'], $file, $debug);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case 'PUT':
|
|
$response = array(
|
|
'status' => 0,
|
|
'status_message' => 'Methode PUT nicht erlaubt.'
|
|
);
|
|
break;
|
|
|
|
case 'DELETE':
|
|
$response = array(
|
|
'status' => 0,
|
|
'status_message' => 'Methode DELETE nicht erlaubt.'
|
|
);
|
|
break;
|
|
}
|
|
|
|
|
|
header('Content-Type: application/json');
|
|
echo json_encode(["ok" => true]);
|
|
|
|
|
|
// Database operations - store message data
|
|
sleep(1);
|
|
$dbiot = new iotdbObj();
|
|
$iotconnection = $dbiot->getConnstring_iot();
|
|
|
|
// Update last device message table
|
|
if(isset($daten['deviceName'])) {
|
|
$sql2 = "SELECT * FROM device_messages WHERE device_id = '".$daten['deviceName']."' ORDER BY id DESC LIMIT 1";
|
|
$result2 = mysqli_query($iotconnection, $sql2);
|
|
$row = mysqli_fetch_assoc($result2);
|
|
|
|
if($row && isset($row['id'])) {
|
|
// power_consumption in data_formatted nachträglich eintragen
|
|
if($powerConsumptionWh !== null) {
|
|
$df = json_decode($row['data_formatted'], true);
|
|
if($df !== null) {
|
|
$df['electricity'] = round($powerConsumptionWh / 1000, 6);
|
|
$newDf = mysqli_real_escape_string($iotconnection, json_encode($df));
|
|
mysqli_query($iotconnection,
|
|
"UPDATE device_messages SET data_formatted = '$newDf' WHERE id = '{$row['id']}'");
|
|
$row['data_formatted'] = $newDf;
|
|
}
|
|
}
|
|
|
|
$sql3 = "UPDATE last_device_message SET
|
|
id = '".$row['id']."',
|
|
time = '".$row['time']."',
|
|
data = '".$row['data']."',
|
|
seqNumber = '".$row['seqNumber']."',
|
|
created_at = '".$row['created_at']."',
|
|
updated_at = '".$row['updated_at']."',
|
|
atlas_location = '".$row['atlas_location']."',
|
|
data_formatted = '".$row['data_formatted']."',
|
|
lqi = '".$row['lqi']."',
|
|
decoderClass = '".$row['decoderClass']."'
|
|
WHERE device_id = '".$row['device_id']."'";
|
|
mysqli_query($iotconnection, $sql3);
|
|
}
|
|
}
|
|
|
|
// === AUTO-DOWNLINK FUNCTIONS ===
|
|
|
|
function sendAutomaticDownlink($deviceName, $devEUI, $logFile, $debug) {
|
|
if($debug) {
|
|
file_put_contents($logFile, "\n\n=== AUTO-DOWNLINK ===\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($logFile, "Device: $deviceName, DevEUI: $devEUI\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
// Convert Base64 DevEUI to Hex if needed
|
|
$hexDevEUI = $devEUI;
|
|
if(!ctype_xdigit($devEUI)) {
|
|
// DevEUI is Base64, decode to binary then to hex
|
|
$binaryDevEUI = base64_decode($devEUI);
|
|
$hexDevEUI = bin2hex($binaryDevEUI);
|
|
if($debug) {
|
|
file_put_contents($logFile, "Converted DevEUI: $devEUI -> $hexDevEUI\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
}
|
|
|
|
// Get current settings from database
|
|
$settings = getG2HSettings($deviceName, $debug, $logFile);
|
|
|
|
if(empty($settings)) {
|
|
if($debug) {
|
|
file_put_contents($logFile, "No settings found for device - skipping downlink\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Collect all settings for combined packet
|
|
$combinedSettings = [
|
|
'heating_enable' => true, // Default: heating enabled
|
|
'room_temp' => 20, // Default room temperature
|
|
'floor_temp' => 22 // Default floor temperature
|
|
];
|
|
|
|
foreach($settings as $setting) {
|
|
switch($setting['type']) {
|
|
case 'r1': // Relais control
|
|
$combinedSettings['heating_enable'] = ($setting['value'] == '1');
|
|
break;
|
|
case 't1': // Room temperature
|
|
$combinedSettings['room_temp'] = intval($setting['value']);
|
|
break;
|
|
case 't2': // Floor temperature
|
|
$combinedSettings['floor_temp'] = intval($setting['value']);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Send combined downlink packet
|
|
$jsonPayload = json_encode($combinedSettings);
|
|
|
|
if($debug) {
|
|
file_put_contents($logFile, "Preparing combined downlink packet\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($logFile, "Combined settings: " . $jsonPayload . "\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($logFile, "heating_enable: " . ($combinedSettings['heating_enable'] ? 'true' : 'false') . "\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($logFile, "room_temp: " . $combinedSettings['room_temp'] . "\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($logFile, "floor_temp: " . $combinedSettings['floor_temp'] . "\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
sendChirpStackJsonDownlink($hexDevEUI, $jsonPayload, $logFile, $debug);
|
|
}
|
|
|
|
function getG2HSettings($deviceName, $debug, $logFile) {
|
|
$dbiot = new iotdbObj();
|
|
$iotconnection = $dbiot->getConnstring_iot();
|
|
|
|
// Query for G2H-RS settings based on DB analysis (without settings_area for flexibility):
|
|
// - Relais: name='active' AND settings_type=32
|
|
// - Raumtemperatur: name='fixValue' AND settings_type=32
|
|
// - Bodentemperatur: name='fixValue' AND settings_type=31
|
|
$sql = "SELECT sf.value, sf.settings_type, sf.name, s.subject_id
|
|
FROM settings_fields sf, settings s
|
|
WHERE s.subject_id = '$deviceName'
|
|
AND s.user_type = 'user'
|
|
AND s.id = sf.settings
|
|
AND (
|
|
(sf.name = 'active' AND sf.settings_type = 32) OR
|
|
(sf.name = 'fixValue' AND sf.settings_type = 32) OR
|
|
(sf.name = 'fixValue' AND sf.settings_type = 31)
|
|
)";
|
|
|
|
if($debug) {
|
|
file_put_contents($logFile, "SQL: $sql\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
$result = mysqli_query($iotconnection, $sql);
|
|
$settings = array();
|
|
|
|
while($row = mysqli_fetch_assoc($result)) {
|
|
$setting = array();
|
|
|
|
if($row['name'] == 'active' && $row['settings_type'] == '32') {
|
|
$setting['type'] = 'r1'; // Relais control
|
|
$setting['value'] = ($row['value'] == 'true' || $row['value'] == '1') ? '1' : '0';
|
|
}
|
|
elseif($row['name'] == 'fixValue' && $row['settings_type'] == '32') {
|
|
$setting['type'] = 't1'; // Room temperature
|
|
$setting['value'] = $row['value'];
|
|
}
|
|
elseif($row['name'] == 'fixValue' && $row['settings_type'] == '31') {
|
|
$setting['type'] = 't2'; // Floor temperature
|
|
$setting['value'] = $row['value'];
|
|
}
|
|
|
|
if(!empty($setting)) {
|
|
$settings[] = $setting;
|
|
if($debug) {
|
|
file_put_contents($logFile, "Found setting: {$setting['type']} = {$setting['value']}\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $settings;
|
|
}
|
|
|
|
|
|
function clearChirpStackDeviceQueue($devEUI, $logFile = null, $debug = false) {
|
|
$CS_URL = 'http://172.17.13.42:8080';
|
|
$TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlfa2V5X2lkIjoiMDcxM2MyNzUtMWIyNy00YzQ4LTlkYjQtNjc3MDg1NTgzN2M2IiwiYXVkIjoiYXMiLCJpc3MiOiJhcyIsIm5iZiI6MTc1NTk1OTgxOSwic3ViIjoiYXBpX2tleSJ9.sFDgV0Sk5LvXD1KAq50pXP2dmzf6qVtwJP8hPkriHpY';
|
|
|
|
$url = "{$CS_URL}/api/devices/{$devEUI}/queue";
|
|
|
|
$curl = curl_init();
|
|
curl_setopt_array($curl, [
|
|
CURLOPT_URL => $url,
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_CUSTOMREQUEST => "DELETE",
|
|
CURLOPT_HTTPHEADER => [
|
|
"Grpc-Metadata-Authorization: Bearer {$TOKEN}",
|
|
"Content-Type: application/json"
|
|
],
|
|
CURLOPT_TIMEOUT => 15,
|
|
CURLOPT_FAILONERROR => false,
|
|
]);
|
|
|
|
$response = curl_exec($curl);
|
|
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
|
curl_close($curl);
|
|
|
|
if($debug && $logFile) {
|
|
file_put_contents($logFile, "Queue cleared for device {$devEUI}, HTTP {$httpCode}: {$response}\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
return $httpCode === 200;
|
|
}
|
|
|
|
function sendChirpStackJsonDownlink($devEUI, $jsonPayload, $logFile, $debug) {
|
|
$CS_URL = 'http://172.17.13.42:8080';
|
|
$TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlfa2V5X2lkIjoiMDcxM2MyNzUtMWIyNy00YzQ4LTlkYjQtNjc3MDg1NTgzN2M2IiwiYXVkIjoiYXMiLCJpc3MiOiJhcyIsIm5iZiI6MTc1NTk1OTgxOSwic3ViIjoiYXBpX2tleSJ9.sFDgV0Sk5LvXD1KAq50pXP2dmzf6qVtwJP8hPkriHpY';
|
|
|
|
// Clear the queue first to prevent queue overflows
|
|
// Wait 5 seconds to ensure old packets had opportunity to be sent during downlink windows
|
|
sleep(5);
|
|
clearChirpStackDeviceQueue($devEUI, $logFile, $debug);
|
|
|
|
// ChirpStack v3 format: we need to encode manually and send as base64 data
|
|
$jsonObject = json_decode($jsonPayload, true);
|
|
|
|
// Manual encoding like the ChirpStack encoder does
|
|
$bytes = [];
|
|
$bytes[0] = $jsonObject['heating_enable'] ? 1 : 0; // Byte 0: heating enable
|
|
$bytes[1] = intval($jsonObject['room_temp']); // Byte 1: room temp
|
|
$bytes[2] = intval($jsonObject['floor_temp']); // Byte 2: floor temp
|
|
|
|
$binaryPayload = pack('C*', ...$bytes);
|
|
$base64Payload = base64_encode($binaryPayload);
|
|
|
|
$queueItem = [
|
|
'deviceQueueItem' => [
|
|
'confirmed' => false,
|
|
'fPort' => 2,
|
|
'data' => $base64Payload, // Base64 data for ChirpStack v3
|
|
],
|
|
];
|
|
|
|
$url = "{$CS_URL}/api/devices/{$devEUI}/queue";
|
|
$headers = [
|
|
'Accept: application/json',
|
|
'Content-Type: application/json',
|
|
'Grpc-Metadata-Authorization: Bearer ' . $TOKEN,
|
|
];
|
|
|
|
if($debug) {
|
|
file_put_contents($logFile, "Sending JSON downlink: $jsonPayload\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_HTTPHEADER => $headers,
|
|
CURLOPT_POSTFIELDS => json_encode($queueItem, JSON_UNESCAPED_SLASHES),
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 15,
|
|
CURLOPT_FAILONERROR => false,
|
|
]);
|
|
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if($debug) {
|
|
file_put_contents($logFile, "Binary Downlink HTTP $httpCode: $response\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($logFile, "Encoded bytes: " . bin2hex($binaryPayload) . " (Base64: $base64Payload)\n", FILE_APPEND | LOCK_EX);
|
|
file_put_contents($logFile, "Full API Payload: " . json_encode($queueItem, JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND | LOCK_EX);
|
|
}
|
|
}
|
|
|
|
|
|
// Save sequence number changes
|
|
setarray($seqNumber);
|
|
|
|
function getseqno()
|
|
{
|
|
$testarray = unserialize(file_get_contents('/var/www/iot-dev/web/seqno.txt'));
|
|
return ($testarray);
|
|
}
|
|
|
|
function setarray($seqno)
|
|
{
|
|
file_put_contents('/var/www/iot-dev/web/seqno.txt', serialize($seqno));
|
|
return;
|
|
}
|
|
|
|
?>
|