resets += $monitor['reset']; db_query("UPDATE {logger_devices} SET access = %d, version = %d, upgrade = %d, resets = %d, uptime = %d, memtotal = %d, memfree = %d, memcached = %d, membuffers = %d, uart_oe = %d WHERE device = '%s'", time(), $monitor['version'], 0, $device->resets, $monitor['uptime'], $monitor['memtotal'], $monitor['memfree'], $monitor['memcached'], $monitor['membuffers'], $monitor['uart_oe'], $auth['device']); $action['upgrade'] = (int)$device->upgrade; if ($action['upgrade']) { $action['timestamp'] = time(); $action['signature'] = hash_hmac('sha1', $action['timestamp'] .':'. $action['upgrade'] .':'. $device->sha, $device->sha); } return $action; } else return xmlrpc_error(-31000, t('Authentication failed.')); } function _logger_measurement_add($auth, $logs) { if (_logger_authenticate_hmac_sha1($auth, $logs)) { $info = 'added 5min interval measurements to the log'; $path = new stdClass(); $path->root = XMLRPC_PATH . '/' . XMLRPC_MODULE; // need to hardcode drupal_get_path('module', 'logger'); $path->base = $path->root .'/data/base/'; $path->night = $path->root .'/data/night/'; foreach ($logs as $meter => $measurements) { //load the normalisation factor, relative to 1pulse = 1Wh $meterdata = db_fetch_object(db_query("SELECT device, night, factor FROM {logger_meters} WHERE meter = '%s'", $meter)); if ($meterdata->device == $auth['device']) { // extra security check $command = $path->root .'/rrdtool update '. $path->base . $meter .'.rrd '; ksort($measurements); // sort the key-value pairs in the associative array by key, i.e. the timestamp foreach ($measurements as $timestamp => $value) { if (is_numeric($timestamp) and is_numeric($value)) { $command .= $timestamp .':'. $value*$meterdata->factor .' '; } else { watchdog_xmlrpc('logger.measurementAdd', 'corrupted input data for %meter : %timestamp : %value', array('%meter' => $meter, '%timestamp' => $timestamp, '%value' => $value),WATCHDOG_ERROR); } } system($command, $return); if ($return == 0) { // update the night rrd every day at 6AM UTC if (time() > $meterdata->night) { $timestamp = floor(time()/86400)*86400; $start = $timestamp + 3600; $end = $start + 10800; //3h time interval $command = $path->root ."/rrdtool fetch ". $path->base . $meter .".rrd AVERAGE -r 900 -s ". $start ." -e ". $end ." | tail -n 12 | awk -F': ' '{SUM += $2} END {print SUM/12}'"; $night = (float)shell_exec($command); //test shell_exec iso system $command = $path->root .'/rrdtool update '. $path->night . $meter .'.rrd '. $timestamp .':'. $night; system($command, $return); if ($return == 0) { watchdog_xmlrpc('logger.measurementAdd', 'successful update for night rrd: %command', array('%command' => $command), WATCHDOG_NOTICE); //debugging } else { watchdog_xmlrpc('logger.measurementAdd', 'error updating night rrd: %command', array('%command' => $command), WATCHDOG_ERROR); //debugging } $meterdata->night = $timestamp + 104400; //add an offset of 29h, i.e. 5AM UTC next day } // {logger_meters} is updated with the true metervalue $value, NOT $value*$meterdata->factor since we're not normalising this entry! db_query("UPDATE {logger_meters} SET access = %d, night = %d, value = %d WHERE meter = '%s'", time(), $meterdata->night, $value, $meter); } else { watchdog_xmlrpc('logger.measurementAdd', 'shell command execution failed: %return %command', array('%command' => $command, '%return' => $return), WATCHDOG_ERROR); } } } return $command; //using $command for testing purposes, replace by $info afterwards } else return xmlrpc_error(-31000, t('Authentication failed.')); } function _logger_authenticate_hmac_sha1($auth, $message) { $auth['key'] = db_result(db_query("SELECT sha FROM {logger_devices} WHERE device = '%s'", $auth['device'])); if (hash_hmac('sha1', $auth['timestamp'] .':'. _logger_serialise($message) .':'. $auth['key'], $auth['key']) == $auth['signature'] && $auth['timestamp'] > time() - 300) { // debugging: watchdog_xmlrpc('logger.auth', 'HMAC-SHA1 authentication succeeded for device: %device', array('%device' => $auth['device']), WATCHDOG_NOTICE); return TRUE; } else { watchdog_xmlrpc('logger.auth', 'HMAC-SHA1 authentication failed for device: %device', array('%device' => $auth['device']), WATCHDOG_ERROR); return FALSE; } } function _logger_serialise($data) { if (is_array($data)) { $sequence = ''; foreach ($data as $key => $value) { $sequence .= (string)$key . _logger_serialise($value); } return $sequence; } else { return (string)$data; } }