1369 lines
67 KiB
PHP
1369 lines
67 KiB
PHP
<?php
|
|
/** \file comet_statusupdates.php
|
|
* \brief Server-side part of the COMET/JSON status updater.
|
|
* \author Bart van Hest, Core|Vision
|
|
* \version $Revision: 26247 $
|
|
* \date $Date: 2016-02-29 10:40:22 +0100 (Mon, 29 Feb 2016) $
|
|
* \todo
|
|
*
|
|
* This file contains the server-side functionality needed to perform 'real-time' status updates for the ZKLs
|
|
* through a COMET/JSON link.
|
|
*
|
|
* The client-side JavaScript functions open a connection to this script. This script should
|
|
* block until a statusupdate must be sent to the client. This mechanism is called COMET or slow-loading.
|
|
*
|
|
* Status updates must be sent as pieces of JavaScript which creates/updates an array of objects
|
|
* named ZKL_Status, with members of the object named s_<name>. For more details, see comet_statusupdates.js
|
|
*/
|
|
|
|
// Extra login check
|
|
if ((db_ver_right_user($_SESSION[$_PAGE_INFO['id']]['login']['user']['id'], "login")) &&
|
|
(db_ver_rights_user_one_valid($_SESSION[$_PAGE_INFO['id']]['login']['user']['id'], "menu:realtime_status"))) {
|
|
// Get start time
|
|
// This to set a script boundary, do not exceed the 10 secs which will result in a "connection with server timeout"
|
|
$start = microtime(TRUE);
|
|
|
|
// Get rtstatus_datapump info
|
|
$_PAGE_INFO['file'] = session_save_path() . "/";
|
|
$_PAGE_INFO['file'] .= (isset($_GET['extended_info'])) ? $_PAGE_INFO['id'] . "_rt_extended" : $_PAGE_INFO['id'] . "_rt";
|
|
|
|
if (file_exists($_PAGE_INFO['file'])) {
|
|
// Open handle
|
|
$handle = fopen($_PAGE_INFO['file'], "r");
|
|
|
|
// Read file and unserialize
|
|
if ((filesize($_PAGE_INFO['file'])) > 0) {
|
|
$_PAGE_INFO['rtstatus_datapump'] = unserialize(fread($handle, filesize($_PAGE_INFO['file'])));
|
|
}
|
|
|
|
// Close handle
|
|
fclose($handle);
|
|
}
|
|
|
|
// Get device type capabilities:
|
|
$_PAGE_INFO['devices_can_switch'] = array();
|
|
$_PAGE_INFO['devices_can_measure'] = array();
|
|
$_PAGE_INFO['devices_can_temp_onboard'] = array();
|
|
$_PAGE_INFO['devices_can_temp_external'] = array();
|
|
$_PAGE_INFO['devices_can_switch'] = db_check_system_device_capabilities(NULL, array("kortsluiting schakelen") , TRUE);
|
|
$_PAGE_INFO['devices_can_measure'] = db_check_system_device_capabilities(NULL, array("meting") , TRUE);
|
|
$_PAGE_INFO['devices_can_temp_onboard'] = db_check_system_device_capabilities(NULL, array("temperatuursensor on-board"), TRUE);
|
|
$_PAGE_INFO['devices_can_temp_external'] = db_check_system_device_capabilities(NULL, array("temperatuursensor extern") , TRUE);
|
|
|
|
// Get device type rt status display capabilities
|
|
$_PAGE_INFO['devices_rt_status'] = db_fetch_set("device","realtime_status");
|
|
|
|
if (is_array($_PAGE_INFO['devices_rt_status'])) {
|
|
foreach($_PAGE_INFO['devices_rt_status'] as $item) {
|
|
// Create array
|
|
$_PAGE_INFO['devices_rt_capabilities'][$item] = array();
|
|
|
|
// Check capability
|
|
$_PAGE_INFO['devices_rt_capabilities'][$item] = db_check_system_device_capabilities(NULL, array($item), TRUE, "realtime_status");
|
|
}
|
|
}
|
|
|
|
//
|
|
// do a debug print to syslog (when enabled)
|
|
//
|
|
function DbgPrint($dbgstring, $type = "info") {
|
|
GLOBAL $_PAGE_INFO;
|
|
|
|
if ((isset($_SESSION[$_PAGE_INFO['id']]['dbg']['mask'])) && ($_SESSION[$_PAGE_INFO['id']]['dbg']['mask'] & 0x02)) {
|
|
DBG("rt-status " . $type . " (session: " . $_PAGE_INFO['id'] . ") " . $dbgstring);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Our custom error handler. Throw away warnings; we cannot produce text that's not valid JavaScript.
|
|
//
|
|
function errorhandler($errno, $errstr, $errfile, $errline) {
|
|
switch ($errno) {
|
|
case E_NOTICE:
|
|
break;
|
|
case E_WARNING:
|
|
case E_CORE_WARNING:
|
|
DbgPrint("PHP Warning: [$errno] $errstr in file $errfile on line $errline<br />\n", "warning");
|
|
break;
|
|
default:
|
|
DbgPrint("PHP Error: [$errno] $errstr in file $errfile on line $errline<br />\n", "error");
|
|
break;
|
|
}
|
|
// don't execute PHP error handler
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Get coordinates from database
|
|
//
|
|
function GetDBCoordinates($dbid, &$gps_info) {
|
|
GLOBAL $_PAGE_INFO;
|
|
|
|
// Initial values
|
|
$valid_gps = FALSE;
|
|
|
|
// Get coodinates from cache
|
|
$tmp = db_fetch_cache($dbid, 'gps');
|
|
// Fallback to log_realtime
|
|
if (!is_array($tmp)) {
|
|
$db_gps = db_fetch_lance_log_gps_info($dbid);
|
|
|
|
// Parse result
|
|
$tmp = $db_gps[0];
|
|
}
|
|
|
|
if (is_array($tmp)) {
|
|
$gps_info = $tmp;
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['gps_db'] = $tmp;
|
|
}
|
|
|
|
// Valid GPS?
|
|
if( is_array($gps_info) && !($gps_info['longitude'] == 0.0 && $gps_info['latitude'] == 0.0) ) {
|
|
// Set flag
|
|
$valid_gps = TRUE;
|
|
}
|
|
|
|
return $valid_gps;
|
|
}
|
|
|
|
//
|
|
// Get last log_rt
|
|
//
|
|
function GetLastLogRT($dbid) {
|
|
GLOBAL $_PAGE_INFO;
|
|
|
|
// Initial values
|
|
$log_rt = "";
|
|
|
|
// Valid coordinates stored during this session?
|
|
if (isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt'])) {
|
|
$log_rt = $_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt'];
|
|
}
|
|
else {
|
|
// Get coodinates from database
|
|
$tmp = db_fetch_lance_logrt($dbid);
|
|
|
|
if (is_array($tmp)) {
|
|
// Workaround to support both cache and log_realtime
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']['t'] = $tmp[0]['t'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']['mcu']['status'] = $tmp[0]['mcu_state'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']['batt'][0]['V'] = $tmp[0]['batt1_niveau'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']['batt'][1]['V'] = $tmp[0]['batt2_niveau'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']['temp']['on-board']['C'] = $tmp[0]['temp_onboard'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']['temp']['ext1']['C'] = $tmp[0]['temp_ntc'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']['wcpu']['status'] = $tmp[0]['wcpu_state'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']['gsm']['received signal strength'] = $tmp[0]['gsm_rssi'];
|
|
$log_rt = $_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt'];
|
|
}
|
|
else {
|
|
// Get logrt from cache
|
|
$tmp = db_fetch_cache($dbid, "status");
|
|
|
|
if (is_array($tmp)) {
|
|
$log_rt = $tmp;
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt'] = $tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $log_rt;
|
|
}
|
|
|
|
|
|
//
|
|
// Get last Detection OK from log_rt
|
|
//
|
|
function GetLastDetectionOk($dbid) {
|
|
GLOBAL $_PAGE_INFO;
|
|
|
|
// Initial values
|
|
$det_ok = "";
|
|
|
|
// Valid coordinates stored during this session?
|
|
if (isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok'])) {
|
|
$det_ok = $_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok'];
|
|
}
|
|
else {
|
|
// Get coodinates from cache
|
|
$tmp = db_fetch_cache($dbid, 'det ok');
|
|
|
|
if (is_array($tmp)) {
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok']['b/a'] = $tmp['b_a'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok']['b/a limit'] = $tmp['b_a_autocal'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok']['time'] = $tmp['t'];
|
|
|
|
// Parse result
|
|
$det_ok = $_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok'];
|
|
}
|
|
}
|
|
|
|
return $det_ok;
|
|
}
|
|
|
|
|
|
//
|
|
// Create runlevel_0 entry in zkl_status
|
|
//
|
|
function CreateRunlevel0Entry($devdata, &$zkl_status, $sleepmode_detection = TRUE) {
|
|
GLOBAL $_PAGE_INFO;
|
|
|
|
// Valid GPS?
|
|
$valid_gps = FALSE;
|
|
|
|
// Get last known log_realtime entry
|
|
$log_rt = GetLastLogRT($devdata['id']);
|
|
|
|
$zkl_status .= '{s_serialnr:"'.addslashes(htmlspecialchars($devdata['id'])).'",';
|
|
$zkl_status .= 's_devtype:"type_'.$devdata['device_type'].'",';
|
|
$zkl_status .= 's_devname:"'.$devdata['name'].'",';
|
|
$zkl_status .= 's_idcode:"'.addslashes(htmlspecialchars($devdata['idcode'])).'",';
|
|
|
|
// Last update time
|
|
if (is_array($log_rt)) {
|
|
$zkl_status .= "s_time:\"".$info.convert_datetime($log_rt['t'],TRUE)."\",";
|
|
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities']["meting kwaliteit"])) && (in_array($devdata['device_type'], $_PAGE_INFO['devices_rt_capabilities']["meting kwaliteit"]))) {
|
|
// Get last detection ok value
|
|
$det_ok = GetLastDetectionOk($devdata['id']);
|
|
|
|
// Valid value?
|
|
if (is_array($det_ok)) {
|
|
$zkl_status .= 's_shortquality:"' . $info . sprintf("%.2f", CalcShortCircuitQuality($det_ok['b/a limit'], $det_ok['b/a'])) . '%",';
|
|
$zkl_status .= 's_shortquality_time:"' . $info . convert_datetime($det_ok['time'], TRUE) . '",';
|
|
}
|
|
else {
|
|
// No valid value
|
|
$zkl_status .= 's_shortquality:"!-",';
|
|
}
|
|
}
|
|
|
|
// Battery status
|
|
for($i=0; $i<($devdata['capabilities']['nr_batterijen']); $i++) {
|
|
$batstatus = "";
|
|
|
|
switch($i) {
|
|
case 0:
|
|
$mask = 0x0F00;
|
|
$shift = 8;
|
|
break;
|
|
case 1:
|
|
$mask = 0xF000;
|
|
$shift = 12;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch(($log_rt['mcu']['status'] & $mask) >> $shift) {
|
|
case 7:
|
|
$batstatus = "removed";
|
|
break;
|
|
case 3:
|
|
$batstatus = "empty";
|
|
break;
|
|
case 1:
|
|
$batstatus = "alarm";
|
|
break;
|
|
case 0:
|
|
$batstatus = "ok";
|
|
break;
|
|
default:
|
|
$batstatus = "Unknown";
|
|
break;
|
|
}
|
|
|
|
if (strlen($batstatus)) {
|
|
// Display in rt status?
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities']["batterij"])) && (in_array($devdata['device_type'], $_PAGE_INFO['devices_rt_capabilities']["batterij"]))) {
|
|
$v_batt = ""; // by default, don't show the battery level
|
|
if( isset($_SESSION[$_PAGE_INFO['id']]['search']['lances']['show_voltage']) ) {
|
|
$v_batt = sprintf("%.3f V: ", $log_rt['batt'][$i]['V']);
|
|
}
|
|
$zkl_status .= 's_batt'.($i+1).':"!'.$v_batt.ucfirst(_($batstatus)).'",';
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($devdata['capabilities']['nr_batterijen'] > 0) {
|
|
// Display in rt status?
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities']["batterij"])) && (in_array($devdata['device_type'], $_PAGE_INFO['devices_rt_capabilities']["batterij"]))) {
|
|
if (is_array($log_rt)) {
|
|
$zkl_status .= "s_batt_timestamp:\"!".convert_datetime($log_rt['t'],TRUE)."\",";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Temperature
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities']["temperatuur"])) && (in_array($devdata['device_type'], $_PAGE_INFO['devices_rt_capabilities']["temperatuur"]))) {
|
|
if (in_array($devdata['device_type'], $_PAGE_INFO['devices_can_temp_onboard']) || $devdata['capabilities']['nr_tempsensors'] > 1) {
|
|
$status_onboard = "";
|
|
$status_external = "";
|
|
if (((int)$log_rt['temp']['on-board']['C'] > -50) && ((int)$log_rt['temp']['on-board']['C'] < 100)) {
|
|
// Alarm available? (on-board uses ext2 alarm)
|
|
$alarm_info = "";
|
|
$alarm = "";
|
|
if ($devdata['thresholds']['t_ext2']) {
|
|
list($max,$min) = explode(",", $devdata['thresholds']['t_ext2']);
|
|
if( $min == -128 ) unset($min);
|
|
if( $max == -128 ) unset($max);
|
|
}
|
|
if( is_numeric($min) || is_numeric($max) ) {
|
|
if ($log_rt['wcpu']['status'] & WCPUERR_TEMP_EXT2) {
|
|
if( is_numeric($min) && is_numeric($max) )
|
|
$temp_format = ___("outside {0} and {1} °C", $min, $max);
|
|
else if( is_numeric($max) )
|
|
$temp_format = ___("above {0} °C", $max);
|
|
else if( is_numeric($min) )
|
|
$temp_format = ___("below {0} °C", $min);
|
|
else
|
|
$temp_format = _("INTERNAL ERROR"); // huh? shouldn't happen
|
|
$alarm = "!";
|
|
$alarm_info = ": ". ucfirst(_("temperature alarm")) . ", " . $temp_format;
|
|
}
|
|
else {
|
|
if( is_numeric($min) && is_numeric($max) )
|
|
$temp_format = ___("between {0} and {1} °C", $min, $max);
|
|
else if( is_numeric($max) )
|
|
$temp_format = ___("below {0} °C", $max);
|
|
else if( is_numeric($min) )
|
|
$temp_format = ___("above {0} °C", $min);
|
|
else
|
|
$temp_format = _("INTERNAL ERROR"); // huh? shouldn't happen
|
|
$alarm_info = ": ". ucfirst(_("ok")) . ", " . $temp_format;
|
|
}
|
|
}
|
|
|
|
// Check for NULL values
|
|
if (!is_null($log_rt['temp']['on-board']['C'])) {
|
|
$temp_value = $alarm . "" . sprintf("%.1f", $log_rt['temp']['on-board']['C']) . " °C" . $alarm_info;
|
|
}
|
|
else {
|
|
$temp_value = _("Missed");
|
|
}
|
|
|
|
$status_onboard .= "s_temp_onboard:\"" . $temp_value . "\",";
|
|
$str = db_fetch_system_device_status($devdata['device_type'], $_SESSION[$_PAGE_INFO['id']]['i18n'], '', 'on-board');
|
|
$status_onboard .= "nm_temp_onboard:\"" . $str['display'] . "\",";
|
|
}
|
|
}
|
|
if (in_array($devdata['device_type'], $_PAGE_INFO['devices_can_temp_external'])) {
|
|
if (((int)$log_rt['temp']['ext1']['C'] > -50) && ((int)$log_rt['temp']['ext1']['C'] < 100)) {
|
|
// Alarm available?
|
|
$alarm_info = "";
|
|
$alarm = "";
|
|
if ($devdata['thresholds']['t_ext1']) {
|
|
list($max,$min) = explode(",", $devdata['thresholds']['t_ext1']);
|
|
if( $min == -128 ) unset($min);
|
|
if( $max == -128 ) unset($max);
|
|
}
|
|
if( is_numeric($min) || is_numeric($max) ) {
|
|
if ($log_rt['wcpu']['status'] & WCPUERR_TEMP_EXT1) {
|
|
if( is_numeric($min) && is_numeric($max) )
|
|
$temp_format = ___("outside {0} and {1} °C", $min, $max);
|
|
else if( is_numeric($max) )
|
|
$temp_format = ___("above {0} °C", $max);
|
|
else if( is_numeric($min) )
|
|
$temp_format = ___("below {0} °C", $min);
|
|
else
|
|
$temp_format = _("INTERNAL ERROR"); // huh? shouldn't happen
|
|
$alarm = "!";
|
|
$alarm_info = ": ". ucfirst(_("temperature alarm")) . ", " . $temp_format;
|
|
}
|
|
else {
|
|
if( is_numeric($min) && is_numeric($max) )
|
|
$temp_format = ___("between {0} and {1} °C", $min, $max);
|
|
else if( is_numeric($max) )
|
|
$temp_format = ___("below {0} °C", $max);
|
|
else if( is_numeric($min) )
|
|
$temp_format = ___("above {0} °C", $min);
|
|
else
|
|
$temp_format = _("INTERNAL ERROR"); // huh? shouldn't happen
|
|
$alarm_info = ": ". ucfirst(_("ok")) . ", " . $temp_format;
|
|
}
|
|
}
|
|
|
|
// Check for NULL values
|
|
if (!is_null($log_rt['temp']['ext1']['C'])) {
|
|
$temp_value = $alarm . "" . sprintf("%.1f", $log_rt['temp']['ext1']['C']) . " °C" . $alarm_info;
|
|
}
|
|
else {
|
|
$temp_value = _("Missed");
|
|
}
|
|
|
|
$status_external .= "s_temp_extern:\"" . $temp_value . "\",";
|
|
$str = db_fetch_system_device_status($devdata['device_type'], $_SESSION[$_PAGE_INFO['id']]['i18n'], '', 'extern');
|
|
$status_external .= "nm_temp_extern:\"" . $str['display'] . "\",";
|
|
}
|
|
}
|
|
if (in_array($devdata['device_type'], $_PAGE_INFO['devices_can_temp_onboard'])) {
|
|
$zkl_status .= $status_onboard . $status_external;
|
|
}
|
|
else {
|
|
$zkl_status .= $status_external . $status_onboard;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fetch gps coordinates from "database"
|
|
$valid_gps = GetDBCoordinates($devdata['id'], $gps_db);
|
|
|
|
if ($valid_gps) {
|
|
$zkl_status .= "position:\"".$gps_db['latitude'].", ".$gps_db['longitude']."\",";
|
|
$zkl_status .= "s_gps:\"!".$gps_db['latitude'].", ".$gps_db['longitude']."\",";
|
|
|
|
// don't show time stamp when the 'gps-fixed' capability is set
|
|
if (strstr($devdata['capabilities']['capabilities'], "gps-fixed") === FALSE) {
|
|
$zkl_status .= "s_gps_timestamp:\"!".convert_datetime($gps_db['t_gps'],TRUE)."\",";
|
|
}
|
|
}
|
|
|
|
// Show signal strength of the radio signal?
|
|
// This is an option (not a capability) that is only available for users with the 'production' right
|
|
if (is_array($log_rt)) {
|
|
if( isset($_SESSION[$_PAGE_INFO['id']]['search']['lances']['show_rssi']) ) {
|
|
$zkl_status .= "s_rssi:\"" . $log_rt['gsm']['received signal strength'] . " dBm\",";
|
|
}
|
|
}
|
|
|
|
// Add project remark?
|
|
if (isset($devdata['remark'])) {
|
|
$zkl_status .= 's_remark:"!'.$devdata['remark'].'",';
|
|
}
|
|
$idcode = "";
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities']["id-code"])) && (in_array($devdata['device_type'], $_PAGE_INFO['devices_rt_capabilities']["id-code"]))) {
|
|
$idcode = "&idcode=" . $devdata['idcode'];
|
|
|
|
// Add extra remark to ID code icon
|
|
if ((isset($devdata['rtstatus'])) && (strlen($devdata['rtstatus']))) {
|
|
$idcode .= "&rtremark=" . $devdata['rtstatus'];
|
|
}
|
|
}
|
|
|
|
// Sleepmode active?
|
|
// Released on project and last connection longer dan PM_TIMEOUT ago?
|
|
// Check also who is the user, could be rented
|
|
if (($sleepmode_detection) &&
|
|
(in_array($devdata['device_type'], $_PAGE_INFO['devices_can_switch'])) &&
|
|
(is_array($log_rt)) &&
|
|
(!(abs(convert_datetime(date("Y-m-d H:i:s")) - $log_rt['t']) > (1.2 * PM_TIMEOUT))) &&
|
|
(!(is_array(db_fetch_lance_released_projects($devdata['id'], ((is_null($devdata['gebruiker'])) ? $devdata['eigenaar'] : $devdata['gebruiker'])))))) {
|
|
$zkl_status .= 's_icon:"error&warning=sleepmode';
|
|
if( isset($_SESSION[$_PAGE_INFO['id']]['search']['lances']['show_rssi']) ) $zkl_status .= ',gsm_none';
|
|
$zkl_status .= $idcode . '"';
|
|
}
|
|
else {
|
|
$zkl_status .= 's_icon:"error';
|
|
if( isset($_SESSION[$_PAGE_INFO['id']]['search']['lances']['show_rssi']) ) $zkl_status .= '&warning=gsm_none';
|
|
$zkl_status .= $idcode . '"';
|
|
}
|
|
$zkl_status .= '}';
|
|
|
|
// to be sure the heartbeat will be called when the device is accesible => "Reset" timer
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$devdata['id']]['heartbeat']['timer']);
|
|
|
|
return $valid_gps;
|
|
}
|
|
|
|
// For debugging: send info to syslog (when enabled)
|
|
if ((isset($_SESSION[$_PAGE_INFO['id']]['dbg']['mask'])) && ($_SESSION[$_PAGE_INFO['id']]['dbg']['mask'] & 0x02)) {
|
|
set_error_handler("errorhandler");
|
|
}
|
|
|
|
DbgPrint("************** rtstatus_datapump ****************\n");
|
|
|
|
// In this array we will store all the data for the various devices. The key into this
|
|
// array is the devices' serial number. The value is an associative array with the information.
|
|
$devdata = array();
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// Find out for which lances we should gather information
|
|
//---------------------------------------------------------------------------------------------
|
|
// Retrieve device info
|
|
$info_devices = array();
|
|
// Get single device info (used by the status tooling)
|
|
if (isset($_GET['device_id'])) {
|
|
array_push($info_devices, db_fetch_lance($_GET['device_id'], "", 1));
|
|
}
|
|
else if (isset($_PAGE_INFO['login']['project']['id'])) {
|
|
// Project selected => All lances on this selected project (hide rented equipment, and show active equipment)
|
|
$info_devices = db_fetch_project_lances($_PAGE_INFO['login']['project']['id'], "", array(array("gprs","gsm"),array("gps","gps-fixed")), 1, array("actief"), array("actief"));
|
|
}
|
|
else if (!is_valid_action("lance_rt")) {
|
|
// Main menu use equipment selected => single device (see all include rented equipment) => status selection already done by search
|
|
array_push($info_devices, db_fetch_lance($_SESSION[$_PAGE_INFO['id']]['search']['lance']['id'], "", 1));
|
|
}
|
|
// rt status shortcuts used?
|
|
else if (isset($_SESSION[$_PAGE_INFO['id']]['rt_dev_shortcut'])) {
|
|
$info_devices = $_SESSION[$_PAGE_INFO['id']]['rt_dev_shortcut'];
|
|
}
|
|
else {
|
|
// Main menu realtime status selected => multiple devices (include rented equipment) => status selection already done by search
|
|
$devices = explode(",", $_SESSION[$_PAGE_INFO['id']]['search']['lances']['id']);
|
|
if (is_array($devices)) {
|
|
foreach($devices as $device) {
|
|
array_push($info_devices, db_fetch_lance($device, "", 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Visible in rt status?
|
|
if (is_array($info_devices)) {
|
|
for ($i=0; $i<sizeof($info_devices); $i++) {
|
|
if (stristr($info_devices[$i]['capabilities'], "rtstatus") === FALSE) {
|
|
unset($info_devices[$i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sort array
|
|
$info_devices = array_sort($info_devices, "idcode");
|
|
|
|
// Fetch device names & last gps coordinates
|
|
if (is_array($info_devices)) {
|
|
for ($i=0; $i<sizeof($info_devices); $i++) {
|
|
$info_devices[$i]['naam'] = db_fetch_system_device_name($_PAGE_INFO['i18n'], $info_devices[$i]['device']);
|
|
}
|
|
}
|
|
|
|
// Fetch project remarks
|
|
if (isset($_PAGE_INFO['login']['project']['id'])) {
|
|
if (is_array($info_devices)) {
|
|
for ($i=0; $i<sizeof($info_devices); $i++) {
|
|
// Get remarks from all periods (comment has been attached to period)
|
|
$equip_remark = db_fetch_project_lances_remark($_PAGE_INFO['login']['project']['id'], $info_devices[$i]['id'], 1);
|
|
|
|
if (is_array($equip_remark)) {
|
|
$info_devices[$i]['remark'] = $equip_remark[0]['opmerking'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_array($info_devices)) {
|
|
//---------------------------------------------------------------------------------------------
|
|
// See if we need to restart the datapump.
|
|
// This is needed when requested (blocking != true), or when the session is destroyed somehow.
|
|
//---------------------------------------------------------------------------------------------
|
|
if ($_GET["blocking"] != 'true' || // manual reset of the state machine
|
|
!is_array($_PAGE_INFO['rtstatus_datapump']) // Session destroyed?
|
|
) {
|
|
// Reset state machine and data in session
|
|
if (is_array($_PAGE_INFO['rtstatus_datapump'])) {
|
|
array_splice($_PAGE_INFO['rtstatus_datapump'], 0);
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// We can used cached data now, so we don't store our entire dataset into the session anymore.
|
|
// However, for now we do create a duplicate which we fill in from DB-data and (later) fetched data.
|
|
//---------------------------------------------------------------------------------------------
|
|
foreach($info_devices as $device_index=>$device_properties) {
|
|
// We want a serial of at least 1 character. Otherwise it is definitely a false one coming from RS testdata
|
|
if (strlen($device_properties['serienr']) > 0) {
|
|
// Fill in some basic information. Copy only what's needed.
|
|
$idx = $device_properties['id'];
|
|
$devdata[$idx]['serial'] = $device_properties['serienr'];
|
|
$devdata[$idx]['idcode'] = $device_properties['idcode'];
|
|
$devdata[$idx]['id'] = $device_properties['id'];
|
|
$devdata[$idx]['device_type'] = $device_properties['device'];
|
|
$devdata[$idx]['rtstatus'] = $device_properties['rtstatus'];
|
|
$devdata[$idx]['name'] = addslashes(htmlspecialchars($device_properties['naam']));
|
|
$devdata[$idx]['tcp_server'] = $device_properties['tcp_server'];
|
|
$devdata[$idx]['gebruiker'] = $device_properties['gebruiker'];
|
|
$devdata[$idx]['eigenaar'] = $device_properties['eigenaar'];
|
|
if (isset($device_properties['remark'])) {
|
|
$devdata[$idx]['remark'] = $device_properties['remark'];
|
|
}
|
|
// device capabilities
|
|
$cap = db_fetch_system_devices($_PAGE_INFO['i18n'],$device_properties['device']);
|
|
$devdata[$idx]['capabilities'] = $cap[0];
|
|
// temperature thresholds
|
|
// NB: threshold for the on-board sensor is set in that for "external sensor #2", for historical reason
|
|
// (this may change...)
|
|
// $devdata[$idx]['thresholds']['t_onboard'] = db_fetch_config($device_properties['id'], $device_properties['device'], 'threshold[t_onboard]');
|
|
$data = db_fetch_config($device_properties['id'], $device_properties['device'], 'threshold[t_ext1]');
|
|
if( is_array($data) ) $devdata[$idx]['thresholds']['t_ext1'] = $data[0];
|
|
$data = db_fetch_config($device_properties['id'], $device_properties['device'], 'threshold[t_ext2]');
|
|
if( is_array($data) ) $devdata[$idx]['thresholds']['t_ext2'] = $data[0];
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// Clear old data from previous sessions (only at startup)
|
|
//---------------------------------------------------------------------------------------------
|
|
if ($_GET['blocking'] != 'true') {
|
|
foreach($devdata as $dbid=>$properties) {
|
|
// Clear old gps info
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$devdata['id']]['gps_db']);
|
|
// Clear old log_realtime info
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$devdata['id']]['log_rt']);
|
|
// Clear old detection ok info
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$devdata['id']]['det_ok']);
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// Remove old equipment which is not selected anymore, this to reduce read/write action
|
|
//---------------------------------------------------------------------------------------------
|
|
if (isset($_PAGE_INFO['rtstatus_datapump'])) {
|
|
foreach($_PAGE_INFO['rtstatus_datapump'] as $dbid=>$properties) {
|
|
// Device unknown?
|
|
if (!isset($devdata[$dbid])) {
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$dbid]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// Login to the TCP servers
|
|
//---------------------------------------------------------------------------------------------
|
|
// Walk over all devices, create an entry in the device_data structure, and create a connection
|
|
// with the TCP server for this device
|
|
foreach($devdata as $dbid=>$properties) {
|
|
// Retrieve tcp server
|
|
$tcp_server = db_fetch("server", "adres","id='" . $properties['tcp_server'] . "'");
|
|
|
|
if (is_array($tcp_server)) {
|
|
// Log in.
|
|
$socket = zkl_tcplogin($dbid, $tcp_server[0]['adres'], NULL, NULL, ZKL_SHMEM, TCP_TIMEOUT, TRUE);
|
|
// Store server (needed for GPS/HEARTBEAT on)
|
|
$devdata[$dbid]['server'] = $tcp_server[0]['adres'];
|
|
|
|
if( $socket !== FALSE ) {
|
|
$devdata[$dbid]['tcp_channel'] = $socket;
|
|
$devdata[$dbid]['is_tcp'] = zkl_via_tcp($socket);
|
|
}
|
|
else {
|
|
$devdata[$dbid]['tcp_channel'] = 0;
|
|
$devdata[$dbid]['is_tcp'] = FALSE;
|
|
}
|
|
DbgPrint("DBID: " . $properties['id'] . ", Login in on server " . $tcp_server[0]['adres'] . ": " . (($devdata[$dbid]['tcp_channel']) ? "Successful" : "Unsuccessful"));
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// Send periodic HEARTBEAT on commands
|
|
//---------------------------------------------------------------------------------------------
|
|
// Only applicable for the rtstatus and the track and trace, not for the extended view!
|
|
if (!isset($_GET['extended_info'])) {
|
|
// See if we must send 'HEARTBEAT ON' commands.
|
|
// We must send these commands when we are in realtime status mode, this will reduce the GPRS costs, and when the previous command was sent
|
|
// more than 15 seconds ago (actually the heartbeat is switched on for 90 seconds, but we keep a safety margin)
|
|
foreach($devdata as $dbid=>$properties) {
|
|
// Timeout?
|
|
if ((microtime(TIME) - $start) < TCP_TIMEOUT) {
|
|
// Last time timed out? => Give the rest some space
|
|
if (!isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['heartbeat']['timed_out'])) {
|
|
// Device available?
|
|
if (isset($properties['tcp_channel'])) {
|
|
// New device or timeout?
|
|
if ((!isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['heartbeat']['timer'])) ||
|
|
((microtime(TRUE) - $_PAGE_INFO['rtstatus_datapump'][$dbid]['heartbeat']['timer']) >= 15)) {
|
|
// Get start time
|
|
$start_sync = microtime(TRUE);
|
|
|
|
// Debug info
|
|
DbgPrint("DBID: " . $properties['id'] . ", Sending HEARTBEAT ON command...\n");
|
|
|
|
// Socket or shared mem?
|
|
if ($properties['is_tcp']) {
|
|
$hbsocket = $properties['tcp_channel'];
|
|
}
|
|
else {
|
|
// Shared mem => Syncdb setup socket => timeout 1 second
|
|
$hbsocket = zkl_tcplogin($dbid, $properties['server'], NULL, NULL, ZKL_NORMAL, 1, TRUE);
|
|
}
|
|
|
|
// Do we have an open channel to the server?
|
|
if ($hbsocket) {
|
|
// Send the Heartbeat ON command (but skip storage in zkl table).
|
|
tcpclient_sync($dbid, $hbsocket, "heartbeat", FALSE);
|
|
|
|
// Logout?
|
|
if (!$properties['is_tcp']) {
|
|
zkl_tcplogout($hbsocket);
|
|
}
|
|
else {
|
|
// Wait for result of the syncdb (This to be sure we read away the result of the syncdb)
|
|
zkl_read_result($hbsocket, $dummy, TCP_TIMEOUT);
|
|
}
|
|
|
|
// Reset timer
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['heartbeat']['timer'] = microtime(TRUE);
|
|
}
|
|
else {
|
|
// Does this device took to long => Skip next time (for once)
|
|
if ((microtime(TRUE) - $start_sync) >= TCP_TIMEOUT) {
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['heartbeat']['timed_out'] = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// Clear flag
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$dbid]['heartbeat']['timer']);
|
|
}
|
|
}
|
|
else {
|
|
// Clear flag
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$dbid]['heartbeat']['timed_out']);
|
|
}
|
|
}
|
|
else {
|
|
// Break up the loop
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// Send periodic GPS on commands
|
|
//---------------------------------------------------------------------------------------------
|
|
// Only applicable for the track and trace (not for the rtstatus), not for the extended view!
|
|
if ((!isset($_GET['extended_info'])) && (is_valid_action("lance_track_trace"))) {
|
|
// See if we must send 'GPS on' commands.
|
|
// We must send these commands when we are in track&trace mode, and when the previous command was sent
|
|
// more than 180 seconds ago (actually the GPS is switched on for 5 minutes, but we keep a safety margin)
|
|
foreach($devdata as $dbid=>$properties) {
|
|
// Timeout?
|
|
if ((microtime(TRUE) - $start) < TCP_TIMEOUT) {
|
|
// Last time timed out? => Give the rest some space
|
|
if (!isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['gps']['timed_out'])) {
|
|
// Device available?
|
|
if (isset($properties['tcp_channel'])) {
|
|
// New device or timeout?
|
|
if ($devdata[$dbid]['tcp_channel'] &&
|
|
((!isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['gps']['timer'])) ||
|
|
((microtime(TRUE) - $_PAGE_INFO['rtstatus_datapump'][$dbid]['gps']['timer']) > 180))) {
|
|
// Get start time
|
|
$start_sync = microtime(TRUE);
|
|
|
|
DbgPrint("DBID: " . $properties['id'] . ", Sending GPS ON command...\n");
|
|
|
|
// Init result array
|
|
$data = array();
|
|
|
|
// execute wi using the secure server (This action is per device)! The project should not bothered at all because we send equip array!
|
|
if (sc_wi($_PAGE_INFO['login']['project']['id'], FALSE, $data, "", "gps aan", "", array(db_fetch_lance($dbid, "", 1))) == TCPSTAT_OK) {
|
|
// Reset timer
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['gps']['timer'] = microtime(TRUE);
|
|
}
|
|
else {
|
|
// Does this device took to long => Skip next time (for once)
|
|
if ((microtime(TRUE) - $start_sync) >= TCP_TIMEOUT) {
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['gps']['timed_out'] = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// Clear flag
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$dbid]['gps']['timer']);
|
|
}
|
|
}
|
|
else {
|
|
// Clear flag
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$dbid]['gps']['timed_out']);
|
|
}
|
|
}
|
|
else {
|
|
// Break up the loop
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// Get cached status
|
|
//---------------------------------------------------------------------------------------------
|
|
// Fetch the cached data from the TCP servers, fill in the ['stat'] section and see if we have a change.
|
|
// OK, we logged into the servers if possible. Now, see if we must aquire data. Do this on a per-lance basis
|
|
foreach ($devdata as $dbid=>$properties) {
|
|
// Do we have an open channel to the server?
|
|
if ($devdata[$dbid]['tcp_channel']) {
|
|
// Yup. Ask the server for a status update (with timeout)
|
|
$server_result = zkl_get_cached_status($properties['tcp_channel'], TCP_TIMEOUT);
|
|
|
|
if ($server_result !== FALSE) {
|
|
// We have data back. Parse/store.
|
|
$devdata[$dbid]['stat'] = $server_result;
|
|
|
|
// Store age
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['stat']['age'] = abs(microtime(TRUE) - $devdata[$dbid]['stat']['time']);
|
|
|
|
// See if we have a change in data
|
|
if ((!isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['stat']['seqnr'])) || ($_PAGE_INFO['rtstatus_datapump'][$dbid]['stat']['seqnr'] != $devdata[$dbid]['stat']['seqnr'])) {
|
|
// Store sequence
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['stat']['seqnr'] = $devdata[$dbid]['stat']['seqnr'];
|
|
DbgPrint("DBID: " . $properties['id'] . ", Sending \$STAT command: Succesful, Data: Changed (Seqnr: " . $devdata[$dbid]['stat']['seqnr'] . ")");
|
|
}
|
|
else {
|
|
DbgPrint("DBID: " . $properties['id'] . ", Sending \$STAT command: Succesful, Data: Unchanged");
|
|
}
|
|
}
|
|
else {
|
|
|
|
DbgPrint("DBID: " . $properties['id'] . ", Sending \$STAT command: Unsuccesful");
|
|
}
|
|
|
|
// Logout
|
|
zkl_tcplogout($properties['tcp_channel']);
|
|
$devdata[$dbid]['tcp_channel'] = 0;
|
|
}
|
|
else if( !$devdata[$dbid]['tcp_server'] ) {
|
|
// device does not have a direct connection via the TCP server; always use the caches
|
|
$devdata[$dbid]['stat'] = db_fetch_cache($devdata[$dbid]['id'], "status");
|
|
// Store age
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['stat']['age'] = abs(microtime(TRUE) - $devdata[$dbid]['stat']['time']);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Assemble the ZKL_Status array based on the data fetched from the servers.
|
|
// We do this by walking over the devdata structure (in session) and parsing the data found there
|
|
$zkl_status = '/*ZKLsu1.0*/ZKL_Status=[';
|
|
|
|
foreach ($devdata as $dbid=>$properties) {
|
|
// Valid stat?
|
|
if (isset($properties['stat'])) {
|
|
$this_device_data = $properties['stat'];
|
|
DbgPrint("DBID: " . $properties['id'] . ", Last update " . $_PAGE_INFO['rtstatus_datapump'][$dbid]['stat']['age'] . " seconds ago\n");
|
|
}
|
|
|
|
// Initial values
|
|
$display_alert_icons = 0;
|
|
$display_idcode_icon = 0;
|
|
$valid_gps = FALSE;
|
|
$temp_zkl_status = "";
|
|
|
|
// See if we have valid server-data for this device
|
|
|
|
// Pre-gather measurement capability
|
|
$devcap_can_measure = (in_array($properties['device_type'], $_PAGE_INFO['devices_can_measure']));
|
|
|
|
// Pre-gather switch shortcircuit capability
|
|
$devcap_has_switch = (in_array($properties['device_type'], $_PAGE_INFO['devices_can_switch']));
|
|
|
|
// Valid stat?
|
|
if (!isset($properties['stat'])) {
|
|
// Nope. Create a runlevel 0 entry (only basic info)
|
|
DbgPrint("DBID: " . $dbid . ", No stat array: create runlevel 0 entry");
|
|
$valid_gps = CreateRunlevel0Entry($properties, $temp_zkl_status);
|
|
}
|
|
// Mcu error bit has been set??
|
|
// Or is this a gateway device, then the network could be out of sync?
|
|
else if (($this_device_data['system']['error']['mcu']) && (!db_check_system_device_capabilities($properties['device_type'], array("gateway")))) {
|
|
// Create a runlevel 0 entry (only basic info)
|
|
DbgPrint("DBID: " . $dbid . ", Mcu error: create runlevel 0 entry");
|
|
$valid_gps = CreateRunlevel0Entry($properties, $temp_zkl_status, FALSE);
|
|
}
|
|
// See if the server-data is young enough when the device is measuring, then we should have a heartbeat
|
|
else if ($_PAGE_INFO['rtstatus_datapump'][$dbid]['stat']['age'] > 10 && ($devcap_can_measure ? $this_device_data['detection']['active'] : FALSE)) {
|
|
// Server data is more than 10 seconds old. Possibly the connection from device to tcp server has failed.
|
|
// Create a runlevel 0 entry to reflect this.
|
|
DbgPrint("DBID: " . $dbid . ", Measure active timeout: create runlevel 0 entry");
|
|
$valid_gps = CreateRunlevel0Entry($properties, $temp_zkl_status, FALSE);
|
|
}
|
|
// See if the server-data is young enough, this to check the connections
|
|
else if ($properties['capabilities']['realtime_timeout'] && ($_PAGE_INFO['rtstatus_datapump'][$dbid]['stat']['age'] > $properties['capabilities']['realtime_timeout'])) {
|
|
// Server data is more than 90 seconds old. Possibly the connection from device to tcp server has failed.
|
|
// Create a runlevel 0 entry to reflect this.
|
|
DbgPrint("DBID: " . $dbid . ", Data to old (90 secs): create runlevel 0 entry");
|
|
$valid_gps = CreateRunlevel0Entry($properties, $temp_zkl_status);
|
|
}
|
|
else {
|
|
// We should have valid server data. Parse it.
|
|
// Our error flag. If the ZKL data indicates an unhealthy situation such as an empty battery, we set this flag to TRUE.
|
|
// Later on we will use this flag to choose the correct icon for the device instance.
|
|
$error_flag = FALSE;
|
|
// --> serialnr
|
|
$temp_zkl_status .= '{s_serialnr:"'.addslashes(htmlspecialchars($dbid)).'",';
|
|
$temp_zkl_status .= 's_devtype:"type_'.$properties['device_type'].'",';
|
|
// --> ID Code
|
|
$temp_zkl_status .= 's_idcode:"'.addslashes(htmlspecialchars($properties['idcode'])).'",';
|
|
// Pre-gather battery info; we need it during display and during icon determination
|
|
$nr_batts_OK = 0;
|
|
$zkl_batt_status = "";
|
|
for ($i=0;$i<($properties['capabilities']['nr_batterijen']);$i++) {
|
|
$battdata = $this_device_data['batt'][$i];
|
|
$v_batt = ""; // by default, don't show the level
|
|
// Filter out the battery numbers only. We are not interested in the currently selected battery'
|
|
DbgPrint("DBID: " . $dbid . ", Battery: " . $i . ", Status: " . $battdata['status']);
|
|
// If batt is OK, increment the OK counter.
|
|
if ($battdata['status'] == 'ok') { $nr_batts_OK++; }
|
|
if( isset($_SESSION[$_PAGE_INFO['id']]['search']['lances']['show_voltage']) ) {
|
|
$v_batt = sprintf("%.3f V: ", $battdata['V']);
|
|
}
|
|
// When the status is not OK or removed, add an exclamation mark to indicate that this battery is not completely healthy.
|
|
if ($battdata['status'] != 'ok' && $battdata['status'] != 'removed') {
|
|
$zkl_batt_status .= 's_batt'.($i+1).':"!'.$v_batt.ucfirst(_($battdata['status'])).'",';
|
|
}
|
|
else {
|
|
$zkl_batt_status .= 's_batt'.($i+1).':"'.$v_batt.ucfirst(_($battdata['status'])).'",';
|
|
}
|
|
}
|
|
|
|
// Do we have GPS co-ordinates? This determines whether we can display the device or not
|
|
if ($this_device_data['gps']['fix']) {
|
|
$valid_gps = TRUE;
|
|
$temp_zkl_status .= "position:\"".sprintf("%.7f",$this_device_data['gps']['latitude']).",".sprintf("%.7f",$this_device_data['gps']['longitude'])."\",";
|
|
|
|
// Clear gps history
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$dbid]['gps_db']);
|
|
}
|
|
else {
|
|
// Fetch gps coordinates from "database"
|
|
$valid_gps = GetDBCoordinates($dbid, $gps_db);
|
|
$temp_zkl_status .= "position:\"".sprintf("%.7f",$gps_db['latitude']).", ".sprintf("%.7f",$gps_db['longitude'])."\",";
|
|
}
|
|
|
|
// Pre-gather device status
|
|
$device_status = "";
|
|
if (in_array($properties['device_type'], $_PAGE_INFO['devices_can_measure'])) {
|
|
$condition = array();
|
|
|
|
// Check capability
|
|
if (in_array($properties['device_type'], $_PAGE_INFO['devices_can_switch'])) {
|
|
// Check switch status
|
|
if (!is_array($this_device_data['switch3000'])) {
|
|
// ZKL 3000
|
|
array_push($condition, array("condition" => "relais", "value" => !$this_device_data['relay']['enabled']));
|
|
}
|
|
else {
|
|
// ZKL 3000 + SWITCH 3000 (Check also the communication)
|
|
array_push($condition, array("condition" => "relais", "value" => $this_device_data['switch3000']['on']));
|
|
}
|
|
}
|
|
|
|
// Check short circuit (measurement)
|
|
if (!is_array($this_device_data['switch3000'])) {
|
|
// ZKL 3000
|
|
array_push($condition, array("condition" => "kortsluiting", "value" => $this_device_data['detection']['ok']));
|
|
}
|
|
else {
|
|
// ZKL 3000 + SWITCH 3000
|
|
array_push($condition, array("condition" => "kortsluiting", "value" => $this_device_data['detection']['ok']));
|
|
}
|
|
|
|
// Get device status
|
|
$device_status = db_fetch_system_device_status($properties['device_type'], $_SESSION[$_PAGE_INFO['id']]['i18n'], $condition, "");
|
|
} else {
|
|
// We have a device which cannot measure. These devices are always 'OK';
|
|
$device_status['status'] = "ok";
|
|
}
|
|
|
|
// Initial values
|
|
$warnings = array();
|
|
$det_handled = FALSE;
|
|
|
|
// Parse realtime status set
|
|
if (is_array($_PAGE_INFO['devices_rt_status'])) {
|
|
foreach ($_PAGE_INFO['devices_rt_status'] as $item) {
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities'][$item])) && (in_array($properties['device_type'], $_PAGE_INFO['devices_rt_capabilities'][$item]))) {
|
|
DbgPrint("DBID: " . $dbid . ", Visible popup item: " . $item);
|
|
switch($item)
|
|
{
|
|
case "type":
|
|
// Display device type (name? We need the type always to grab the correct icon)
|
|
$temp_zkl_status .= 's_devname:"'.$properties['name'].'",';
|
|
break;
|
|
case "tijd":
|
|
$temp_zkl_status .= 's_time:"'.date("Y-m-d H:i:s", $properties['stat']['time']).'",';
|
|
break;
|
|
case "meting":
|
|
// See if we have a measurement capability
|
|
DbgPrint("DBID: " . $dbid . ", Device can measure: " . ($devcap_can_measure ? "Yes" : "No"));
|
|
if ($devcap_can_measure) {
|
|
// --> Measurement switched on/off
|
|
DbgPrint("DBID: " . $dbid . ", Measurement active: " . (($this_device_data['detection']['active']) ? "Yes" : "No"));
|
|
if ($this_device_data['detection']['active']) {
|
|
$temp_zkl_status .= 's_active:"ACTIVE",';
|
|
}
|
|
else {
|
|
$temp_zkl_status .= 's_active:"!INACTIVE",';
|
|
$error_flag = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
case "meting kwaliteit":
|
|
case "detectie":
|
|
// Already handled?
|
|
if (!$det_handled) {
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities']["detectie"])) && (in_array($properties['device_type'], $_PAGE_INFO['devices_rt_capabilities']["detectie"]))) {
|
|
if (is_array($device_status)) {
|
|
if ($device_status['status'] == "ok") {
|
|
$temp_zkl_status .= 's_detection:"'.$device_status['display'].'",';
|
|
} else {
|
|
$temp_zkl_status .= 's_detection:"!'.$device_status['display'].'",';
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$temp_zkl_status .= 's_detection:"!INTERNALERROR_DEVSTATUS_IS_NO_ARRAY",';
|
|
}
|
|
|
|
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities']["meting kwaliteit"])) && (in_array($properties['device_type'], $_PAGE_INFO['devices_rt_capabilities']["meting kwaliteit"]))) {
|
|
if ($devcap_can_measure) {
|
|
// Initial value
|
|
$db_quality = TRUE;
|
|
|
|
if ($this_device_data['detection']['active']) {
|
|
// Calculate quality of detection
|
|
if (($device_status['status'] == "ok") && (isset($this_device_data['detection']['b/a limit'])) && ($this_device_data['detection']['b/a limit'] > 0.125)) {
|
|
$temp_zkl_status .= 's_shortquality:"' . sprintf("%.2f", CalcShortCircuitQuality($this_device_data['detection']['b/a limit'], $this_device_data['detection']['b/a'])) . '%",';
|
|
|
|
// Update last detection ok value
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok']['b/a'] = $this_device_data['detection']['b/a'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok']['b/a limit'] = $this_device_data['detection']['b/a limit'];
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['det_ok']['time'] = $this_device_data['time'];
|
|
|
|
// Clear flag
|
|
$db_quality = FALSE;
|
|
}
|
|
}
|
|
|
|
// Retrieve last detection ok from database?
|
|
if ($db_quality) {
|
|
$det_ok = GetLastDetectionOk($dbid);
|
|
|
|
// Valid value?
|
|
if (is_array($det_ok)) {
|
|
$temp_zkl_status .= 's_shortquality:"!' . sprintf("%.2f", CalcShortCircuitQuality($det_ok['b/a limit'], $det_ok['b/a'])) . '%",';
|
|
$temp_zkl_status .= 's_shortquality_time:"!' . convert_datetime($det_ok['time'], TRUE) . '",';
|
|
}
|
|
else {
|
|
// No valid value
|
|
$temp_zkl_status .= 's_shortquality:"!-",';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((is_array($_PAGE_INFO['devices_rt_capabilities']["detectie"])) && (in_array($properties['device_type'], $_PAGE_INFO['devices_rt_capabilities']["detectie"]))) {
|
|
if (is_array($device_status)) {
|
|
// Support old & new zkl 3000 RC
|
|
if ($devcap_has_switch) {
|
|
if (!is_array($this_device_data['switch3000'])) {
|
|
$temp_zkl_status .= 's_switch:"';
|
|
$temp_zkl_status .= ($this_device_data['relay']['enabled']) ? "!INACTIVE" : "ACTIVE";
|
|
$temp_zkl_status .= '",';
|
|
}
|
|
else {
|
|
// initial value
|
|
$switch300_comm_err = FALSE;
|
|
|
|
// Error flag set
|
|
if ($this_device_data['system']['error']['sw1w']) {
|
|
// Was the error flag already set?
|
|
if (!isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['switch3000_comm'])) {
|
|
$_PAGE_INFO['rtstatus_datapump'][$dbid]['switch3000_comm'] = $devdata[$dbid]['stat']['time'];
|
|
}
|
|
|
|
// This flag has been set for longer than 3 secs?
|
|
if (isset($_PAGE_INFO['rtstatus_datapump'][$dbid]['switch3000_comm'])) {
|
|
if (abs(microtime(TRUE) - $_PAGE_INFO['rtstatus_datapump'][$dbid]['switch3000_comm']) > 3) {
|
|
// Set error flag
|
|
$switch300_comm_err = TRUE;
|
|
|
|
// Add warning
|
|
$warnings[] = "switch";
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// Remove start time
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$dbid]['switch3000_comm']);
|
|
}
|
|
|
|
$temp_zkl_status .= 's_switch:"';
|
|
$temp_zkl_status .= (!$switch300_comm_err) ? (($this_device_data['switch3000']['on']) ? "ACTIVE" : "!INACTIVE") : "!" . _("Unknown");
|
|
$temp_zkl_status .= '",';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clear flag
|
|
$det_handled = TRUE;
|
|
break;
|
|
case "sleutelschakelaar":
|
|
$temp_zkl_status .= 's_sleutelschakelaar:"';
|
|
|
|
// Key switch on?
|
|
if ($this_device_data['switch3000']['key']['on']) {
|
|
$temp_zkl_status .= "!SW_ACTIVE";
|
|
}
|
|
// Key switch off?
|
|
else if ($this_device_data['switch3000']['key']['off']) {
|
|
$temp_zkl_status .= "!SW_INACTIVE";
|
|
}
|
|
// Key switch operational
|
|
else {
|
|
$temp_zkl_status .= "SW_OPER";
|
|
}
|
|
$temp_zkl_status .= '",';
|
|
break;
|
|
case "batterij":
|
|
$temp_zkl_status .= $zkl_batt_status;
|
|
break;
|
|
case "temperatuur":
|
|
$status_onboard = "";
|
|
$status_external = "";
|
|
if (in_array($properties['device_type'], $_PAGE_INFO['devices_can_temp_onboard']) || $properties['capabilities']['nr_tempsensors'] > 1) {
|
|
if (((int)$this_device_data['temp']['on-board']['C'] > -50) && ((int)$this_device_data['temp']['on-board']['C'] < 100)) {
|
|
// Alarm available? (on-board uses ext2 alarm)
|
|
$alarm_info = "";
|
|
$alarm = "";
|
|
if ($properties['thresholds']['t_ext2']) {
|
|
list($max,$min) = explode(",", $properties['thresholds']['t_ext2']);
|
|
// a bit of a hack, but this disables the thresholds when either one is not set
|
|
if( $min == -128 ) unset($min);
|
|
if( $max == -128 ) unset($max);
|
|
}
|
|
if( is_numeric($min) || is_numeric($max) ) {
|
|
if (!$this_device_data['temp']['ext2']['ok']) {
|
|
if( is_numeric($min) && is_numeric($max) )
|
|
$temp_format = ___("outside {0} and {1} °C", $min, $max);
|
|
else if( is_numeric($max) )
|
|
$temp_format = ___("above {0} °C", $max);
|
|
else if( is_numeric($min) )
|
|
$temp_format = ___("below {0} °C", $min);
|
|
else
|
|
$temp_format = _("INTERNAL ERROR"); // huh? shouldn't happen
|
|
$alarm = "!";
|
|
$warnings[] = "temp_ext2";
|
|
$alarm_info = ": ". ucfirst(_("temperature alarm")) . ", " . $temp_format;
|
|
}
|
|
else {
|
|
if( is_numeric($min) && is_numeric($max) )
|
|
$temp_format = ___("between {0} and {1} °C", $min, $max);
|
|
else if( is_numeric($max) )
|
|
$temp_format = ___("below {0} °C", $max);
|
|
else if( is_numeric($min) )
|
|
$temp_format = ___("above {0} °C", $min);
|
|
else
|
|
$temp_format = _("INTERNAL ERROR"); // huh? shouldn't happen
|
|
$alarm_info = ": ". ucfirst(_("ok")) . ", " . $temp_format;
|
|
}
|
|
}
|
|
|
|
// Check for NULL values
|
|
if (!is_null($this_device_data['temp']['on-board']['C'])) {
|
|
$temp_value = $alarm . "" . sprintf("%.1f", $this_device_data['temp']['on-board']['C']) . " °C" . $alarm_info;
|
|
}
|
|
else {
|
|
$temp_value = _("Missed");
|
|
}
|
|
|
|
$status_onboard .= "s_temp_onboard:\"" . $temp_value . "\",";
|
|
$str = db_fetch_system_device_status($properties['device_type'], $_SESSION[$_PAGE_INFO['id']]['i18n'], '', 'on-board');
|
|
$status_onboard .= "nm_temp_onboard:\"" . $str['display'] . "\",";
|
|
}
|
|
}
|
|
if (in_array($properties['device_type'], $_PAGE_INFO['devices_can_temp_external'])) {
|
|
if (((int)$this_device_data['temp']['ext1']['C'] > -50) && ((int)$this_device_data['temp']['ext1']['C'] < 100)) {
|
|
// Alarm available?
|
|
$alarm_info = "";
|
|
$alarm = "";
|
|
if ($properties['thresholds']['t_ext1']) {
|
|
list($max,$min) = explode(",", $properties['thresholds']['t_ext1']);
|
|
// a bit of a hack, but this disables the thresholds when either one is not set
|
|
if( $min == -128 ) unset($min);
|
|
if( $max == -128 ) unset($max);
|
|
}
|
|
if( is_numeric($min) || is_numeric($max) ) {
|
|
if (!$this_device_data['temp']['ext1']['ok']) {
|
|
if( is_numeric($min) && is_numeric($max) )
|
|
$temp_format = ___("outside {0} and {1} °C", $min, $max);
|
|
else if( is_numeric($max) )
|
|
$temp_format = ___("above {0} °C", $max);
|
|
else if( is_numeric($min) )
|
|
$temp_format = ___("below {0} °C", $min);
|
|
else
|
|
$temp_format = _("INTERNAL ERROR"); // huh? shouldn't happen
|
|
$alarm = "!";
|
|
$warnings[] = "temp_ext1";
|
|
$alarm_info = ": ". ucfirst(_("temperature alarm")) . ", " . $temp_format;
|
|
}
|
|
else {
|
|
if( is_numeric($min) && is_numeric($max) )
|
|
$temp_format = ___("between {0} and {1} °C", $min, $max);
|
|
else if( is_numeric($max) )
|
|
$temp_format = ___("below {0} °C", $max);
|
|
else if( is_numeric($min) )
|
|
$temp_format = ___("above {0} °C", $min);
|
|
else
|
|
$temp_format = _("INTERNAL ERROR"); // huh? shouldn't happen
|
|
$alarm_info = ": ". ucfirst(_("ok")) . ", " . $temp_format;
|
|
}
|
|
}
|
|
|
|
// Check for NULL values
|
|
if (!is_null($this_device_data['temp']['ext1']['C'])) {
|
|
$temp_value = $alarm . "" . sprintf("%.1f", $this_device_data['temp']['ext1']['C']) . " °C" . $alarm_info;
|
|
}
|
|
else {
|
|
$temp_value = _("Missed");
|
|
}
|
|
|
|
$status_external .= "s_temp_extern:\"" . $temp_value . "\",";
|
|
$str = db_fetch_system_device_status($properties['device_type'], $_SESSION[$_PAGE_INFO['id']]['i18n'], '', 'extern');
|
|
$status_external .= "nm_temp_extern:\"" . $str['display'] . "\",";
|
|
}
|
|
}
|
|
if (in_array($devdata['device_type'], $_PAGE_INFO['devices_can_temp_onboard'])) {
|
|
$temp_zkl_status .= $status_onboard . $status_external;
|
|
}
|
|
else {
|
|
$temp_zkl_status .= "sw_temp:\"1\"," . $status_external . $status_onboard;
|
|
}
|
|
break;
|
|
case "gps":
|
|
// Display gps position
|
|
if ($this_device_data['gps']['fix']) {
|
|
DbgPrint("DBID: " . $dbid . ", GPS coordinates lon: " . $this_device_data['gps']['longitude'] . ", lat: " . $this_device_data['gps']['latitude']);
|
|
$temp_zkl_status .= "s_gps:\"".sprintf("%.7f",$this_device_data['gps']['latitude']).",".sprintf("%.7f",$this_device_data['gps']['longitude'])."\",";
|
|
}
|
|
else if( $gps_db ) {
|
|
DbgPrint("DBID: " . $dbid . ", GPS coordinates: -, use db coordinates");
|
|
// Fetch gps coordinates from "database"
|
|
if (strstr($properties['capabilities']['capabilities'], "gps-fixed") === FALSE) {
|
|
$temp_zkl_status .= "s_gps:\"!".sprintf("%.7f",$gps_db['latitude']).", ".sprintf("%.7f",$gps_db['longitude'])."\",";
|
|
$temp_zkl_status .= "s_gps_timestamp:\"!".convert_datetime($gps_db['t_gps'],TRUE)."\",";
|
|
$warnings[] = "gps";
|
|
}
|
|
else {
|
|
// fixed co-ordinates (never in error)
|
|
$temp_zkl_status .= "s_gps:\"".sprintf("%.7f",$gps_db['latitude']).", ".sprintf("%.7f",$gps_db['longitude'])."\",";
|
|
}
|
|
}
|
|
break;
|
|
case "speed":
|
|
if ($this_device_data['gps']['fix']) {
|
|
$temp_zkl_status .= "s_speed:\"" . $this_device_data['gps']['speed'] . " km\/h\",";
|
|
}
|
|
break;
|
|
case "id-code":
|
|
$display_idcode_icon = 1;
|
|
break;
|
|
case "alert icons":
|
|
$display_alert_icons = 1;
|
|
break;
|
|
|
|
default:
|
|
$temp_zkl_status .= 's_'.$item.':"Unknown parameter",';
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
DbgPrint("DBID: " . $dbid . ", Invisible popup item: " . $item);
|
|
}
|
|
}
|
|
|
|
// Show signal strength of the radio signal?
|
|
// This is an option (not a capability) that is only available for users with the 'production' right
|
|
if( isset($_SESSION[$_PAGE_INFO['id']]['search']['lances']['show_rssi']) ) {
|
|
$temp_zkl_status .= "s_rssi:\"" . $this_device_data['gsm']['received signal strength'] . " dBm\",";
|
|
if( $this_device_data['gsm']['received signal strength'] == 0 )
|
|
$warnings[] = "gsm_unknown";
|
|
else if( $this_device_data['gsm']['received signal strength'] >= -75 )
|
|
$warnings[] = "gsm100";
|
|
else if( $this_device_data['gsm']['received signal strength'] >= -83 )
|
|
$warnings[] = "gsm75";
|
|
else if( $this_device_data['gsm']['received signal strength'] >= -95 )
|
|
$warnings[] = "gsm50";
|
|
else if( $this_device_data['gsm']['received signal strength'] >= -105 )
|
|
$warnings[] = "gsm25";
|
|
else if( $this_device_data['gsm']['received signal strength'] >= -110 )
|
|
$warnings[] = "gsm10";
|
|
else
|
|
$warnings[] = "gsm0";
|
|
}
|
|
|
|
// Add project remark?
|
|
if (isset($properties['remark'])) {
|
|
$temp_zkl_status .= 's_remark:"'.$properties['remark'].'",';
|
|
}
|
|
}
|
|
|
|
// --> icon
|
|
// Add the icon and closing curly bracket
|
|
if (!is_array($device_status)) {
|
|
$temp_zkl_status .= 's_internalerror:"!INTERNALERROR_DEVSTATUS_IS_NO_ARRAY",';
|
|
DbgPrint("DBID: " . $device_properties['id'] . ", Device status: " . (is_array($device_status) ? print_r($device_status, TRUE) : "-"));
|
|
}
|
|
|
|
$icon = (is_array($device_status)) ? $device_status['status'] : "nok";
|
|
if ($device_status['status'] != "error") {
|
|
// Battery warning?
|
|
if ($nr_batts_OK<1 && $properties['capabilities']['nr_batterijen']>0) {
|
|
$warnings[] = "batt";
|
|
}
|
|
}
|
|
|
|
// Handle warnings
|
|
$warning = "";
|
|
if ($display_alert_icons) {
|
|
if( count($warnings) > 0 ) {
|
|
// build comma separated string with all the warnings
|
|
$sep = "&warning=";
|
|
foreach( $warnings as $this_warning ) {
|
|
$warning .= $sep . $this_warning;
|
|
$sep = ",";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle ID code icon
|
|
$idcode = "";
|
|
if ($display_idcode_icon) {
|
|
$idcode = "&idcode=" . $properties['idcode'];
|
|
|
|
// Add extra remark to ID code icon
|
|
if ((isset($properties['rtstatus'])) && (strlen($properties['rtstatus']))) {
|
|
$idcode .= "&rtremark=" . $properties['rtstatus'];
|
|
}
|
|
}
|
|
|
|
$temp_zkl_status .= 's_icon:"' . $icon . $warning . $idcode . '"';
|
|
$temp_zkl_status .= '}';
|
|
|
|
// Clear log_rt history
|
|
unset($_PAGE_INFO['rtstatus_datapump'][$dbid]['log_rt']);
|
|
}
|
|
|
|
// Add temp status to zkl_status when valid coordinates
|
|
if ($valid_gps) {
|
|
$zkl_status .= $temp_zkl_status;
|
|
}
|
|
}
|
|
|
|
$zkl_status .= "];";
|
|
// Add comma's between different ZKL instances
|
|
$zkl_status = str_replace ('}{', '},{', $zkl_status);
|
|
echo $zkl_status;
|
|
DbgPrint($zkl_status);
|
|
DbgPrint("\n============== rtstatus_datapump END ============\n\n");
|
|
|
|
// Open handle
|
|
$handle = fopen($_PAGE_INFO['file'], "w");
|
|
|
|
// Write file and serialize
|
|
fwrite($handle, serialize($_PAGE_INFO['rtstatus_datapump']));
|
|
|
|
// Close handle
|
|
fclose($handle);
|
|
}
|
|
else {
|
|
// Display logout message
|
|
$_SESSION[$_PAGE_INFO['id']]['login_info']['errormsg'] = _("No valid rights");
|
|
|
|
// Redirect page back to login page
|
|
echo "<script type=\"text/javascript\">\n";
|
|
echo "location.href='/?id=" . $_PAGE_INFO['id'] . "&href=" . PAGE_LOGIN. "'\n";
|
|
echo "</script>\n";
|
|
}
|
|
?>
|