<?php /** * Observium * * This file is part of Observium. * * @package observium * @subpackage graphs * @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2016 Observium Limited * */ if (is_numeric($vars['id'])) { $sensor = dbFetchRow("SELECT * FROM `sensors` WHERE `sensor_id` = ?", array($vars['id'])); if (is_numeric($sensor['device_id']) && ($auth || is_entity_permitted($sensor['sensor_id'], 'sensor') || device_permitted($sensor['device_id']))) { $device = device_by_id_cache($sensor['device_id']); $rrd_filename = get_rrd_path($device, get_sensor_rrd($device, $sensor)); $title = generate_device_link($device); $title .= " :: Sensors :: "; $auth = TRUE; } } // EOF
$colour = '008C00'; break; case '3': $colour = '4096EE'; break; case '4': $colour = '73880A'; break; case '5': $colour = 'D01F3C'; break; case '6': $colour = '36393D'; break; case '7': default: $colour = 'FF0084'; unset($iter); break; } //end switch $sensor['sensor_descr_fixed'] = substr(str_pad($sensor['sensor_descr'], $descr_len), 0, $descr_len); $rrd_file = get_sensor_rrd($device, $sensor); $rrd_options .= ' DEF:sensor' . $sensor['sensor_id'] . "={$rrd_file}:sensor:AVERAGE "; $rrd_options .= ' LINE1:sensor' . $sensor['sensor_id'] . '#' . $colour . ":'" . str_replace(':', '\\:', str_replace('\\*', '*', $sensor['sensor_descr_fixed'])) . "'"; $rrd_options .= ' GPRINT:sensor' . $sensor['sensor_id'] . ':LAST:%4.1lf' . $unit . ' '; $rrd_options .= ' GPRINT:sensor' . $sensor['sensor_id'] . ':MIN:%4.1lf' . $unit . ' '; $rrd_options .= ' GPRINT:sensor' . $sensor['sensor_id'] . ':MAX:%4.1lf' . $unit . '\\\\l '; $iter++; } //end foreach
function poll_sensor($device, $class, $unit) { global $config, $memcache, $agent_sensors; foreach (dbFetchRows('SELECT * FROM `sensors` WHERE `sensor_class` = ? AND `device_id` = ?', array($class, $device['device_id'])) as $sensor) { echo 'Checking (' . $sensor['poller_type'] . ") {$class} " . $sensor['sensor_descr'] . '... '; $sensor_value = ''; if ($sensor['poller_type'] == 'snmp') { if ($device['os'] == 'siklu') { $mib = ':RADIO-BRIDGE-MIB'; } else { $mib = ''; } if ($class == 'temperature') { if ($device['os'] == 'netapp') { include 'includes/polling/temperatures/netapp.inc.php'; } else { // Try 5 times to get a valid temp reading for ($i = 0; $i < 5; $i++) { d_echo("Attempt {$i} "); $sensor_value = trim(str_replace('"', '', snmp_get($device, $sensor['sensor_oid'], '-OUqnv', "SNMPv2-MIB{$mib}"))); preg_match('/[\\d\\.]+/', $sensor_value, $temp_response); if (!empty($temp_response[0])) { $sensor_value = $temp_response[0]; } if (is_numeric($sensor_value) && $sensor_value != 9999) { break; // TME sometimes sends 999.9 when it is right in the middle of an update; } sleep(1); // end if } } //end if } else { if ($class == 'state') { $sensor_value = trim(str_replace('"', '', snmp_walk($device, $sensor['sensor_oid'], '-Oevq', 'SNMPv2-MIB'))); } else { if ($class == 'dbm') { $sensor_value = trim(str_replace('"', '', snmp_get($device, $sensor['sensor_oid'], '-OUqnv', "SNMPv2-MIB{$mib}"))); //iosxr does not expose dbm values through SNMP so we convert Watts to dbm to have a nice graph to show if ($device['os'] == "iosxr") { $sensor_value = round(10 * log10($sensor_value / 1000), 3); } } else { if ($sensor['sensor_type'] == 'apc') { $sensor_value = trim(str_replace('"', '', snmp_walk($device, $sensor['sensor_oid'], '-OUqnv', "SNMPv2-MIB:PowerNet-MIB{$mib}"))); } else { $sensor_value = trim(str_replace('"', '', snmp_get($device, $sensor['sensor_oid'], '-OUqnv', "SNMPv2-MIB{$mib}"))); } } } } //end if unset($mib); } else { if ($sensor['poller_type'] == 'agent') { if (isset($agent_sensors)) { $sensor_value = $agent_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current']; } else { echo "no agent data!\n"; continue; } } else { if ($sensor['poller_type'] == 'ipmi') { echo " already polled.\n"; // ipmi should probably move here from the ipmi poller file (FIXME) continue; } else { echo "unknown poller type!\n"; continue; } } } //end if if ($sensor_value == -32768) { echo 'Invalid (-32768) '; $sensor_value = 0; } if ($sensor['sensor_divisor']) { $sensor_value = $sensor_value / $sensor['sensor_divisor']; } if ($sensor['sensor_multiplier']) { $sensor_value = $sensor_value * $sensor['sensor_multiplier']; } $rrd_file = get_sensor_rrd($device, $sensor); if (!is_file($rrd_file)) { rrdtool_create($rrd_file, '--step 300 DS:sensor:GAUGE:600:-20000:20000 ' . $config['rrd_rra']); } echo "{$sensor_value} {$unit}\n"; $fields = array('sensor' => $sensor_value); rrdtool_update($rrd_file, $fields); // FIXME also warn when crossing WARN level!! if ($sensor['sensor_limit_low'] != '' && $sensor['sensor_current'] > $sensor['sensor_limit_low'] && $sensor_value <= $sensor['sensor_limit_low'] && $sensor['sensor_alert'] == 1) { echo 'Alerting for ' . $device['hostname'] . ' ' . $sensor['sensor_descr'] . "\n"; log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . ' under threshold: ' . $sensor_value . " {$unit} (< " . $sensor['sensor_limit_low'] . " {$unit})", $device, $class, $sensor['sensor_id']); } else { if ($sensor['sensor_limit'] != '' && $sensor['sensor_current'] < $sensor['sensor_limit'] && $sensor_value >= $sensor['sensor_limit'] && $sensor['sensor_alert'] == 1) { echo 'Alerting for ' . $device['hostname'] . ' ' . $sensor['sensor_descr'] . "\n"; log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . ' above threshold: ' . $sensor_value . " {$unit} (> " . $sensor['sensor_limit'] . " {$unit})", $device, $class, $sensor['sensor_id']); } } dbUpdate(array('sensor_current' => $sensor_value, 'lastupdate' => array('NOW()')), 'sensors', '`sensor_class` = ? AND `sensor_id` = ?', array($class, $sensor['sensor_id'])); } //end foreach }
function poll_sensor($device, $class, $unit, &$oid_cache) { global $config, $agent_sensors, $ipmi_sensors, $graphs, $table_rows; $sql = "SELECT * FROM `sensors`"; $sql .= " LEFT JOIN `sensors-state` USING(`sensor_id`)"; $sql .= " WHERE `sensor_class` = ? AND `device_id` = ?"; foreach (dbFetchRows($sql, array($class, $device['device_id'])) as $sensor_db) { $sensor_poll = array(); //print_cli_heading("Sensor: ".$sensor_db['sensor_descr'], 3); if (OBS_DEBUG) { echo "Checking (" . $sensor_db['poller_type'] . ") {$class} " . $sensor_db['sensor_descr'] . " "; print_r($sensor_db); } if ($sensor_db['poller_type'] == "snmp") { # if ($class == "temperature" && $device['os'] == "papouch") // Why all temperature? if ($class == "temperature") { for ($i = 0; $i < 5; $i++) { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$sensor_db['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_poll['sensor_value'] = $oid_cache[$sensor_db['sensor_oid']]; } else { $sensor_poll['sensor_value'] = snmp_get($device, $sensor_db['sensor_oid'], "-OUqnv", "SNMPv2-MIB"); } $sensor_poll['sensor_value'] = snmp_fix_numeric($sensor_poll['sensor_value']); if (is_numeric($sensor_poll['sensor_value']) && $sensor_poll['sensor_value'] != 9999) { break; } // Papouch TME sometimes sends 999.9 when it is right in the middle of an update; sleep(1); // Give the TME some time to reset } // If we received 999.9 degrees still, reset to Unknown. if ($sensor_poll['sensor_value'] == 9999) { $sensor_poll['sensor_value'] = "U"; } } else { if ($class == "runtime") { if (isset($oid_cache[$sensor_db['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_poll['sensor_value'] = $oid_cache[$sensor_db['sensor_oid']]; } else { $sensor_poll['sensor_value'] = snmp_get($device, $sensor_db['sensor_oid'], "-OUqnv", "SNMPv2-MIB"); } if (strpos($sensor_poll['sensor_value'], ':') !== FALSE) { // Use timetick conversion only when snmpdata is formatted as timetick 0:0:21:00.00 $sensor_poll['sensor_value'] = timeticks_to_sec($sensor_poll['sensor_value']); } } else { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$sensor_db['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_poll['sensor_value'] = $oid_cache[$sensor_db['sensor_oid']]; } else { $sensor_poll['sensor_value'] = snmp_get($device, $sensor_db['sensor_oid'], "-OUqnv", "SNMPv2-MIB"); } $sensor_poll['sensor_value'] = snmp_fix_numeric($sensor_poll['sensor_value']); } } } else { if ($sensor_db['poller_type'] == "agent") { if (isset($agent_sensors)) { $sensor_poll['sensor_value'] = $agent_sensors[$class][$sensor_db['sensor_type']][$sensor_db['sensor_index']]['current']; // FIXME pass unit? } else { print_warning("No agent sensor data available."); continue; } } else { if ($sensor_db['poller_type'] == "ipmi") { if (isset($ipmi_sensors)) { $sensor_poll['sensor_value'] = $ipmi_sensors[$class][$sensor_db['sensor_type']][$sensor_db['sensor_index']]['current']; $unit = $ipmi_sensors[$class][$sensor_db['sensor_type']][$sensor_db['sensor_index']]['unit']; } else { print_warning("No IPMI sensor data available."); continue; } } else { print_warning("Unknown sensor poller type."); continue; } } } $sensor_polled_time = time(); // Store polled time for current sensor if (OBS_DEBUG) { print_r($sensor_poll); } if ($sensor_poll['sensor_value'] == -32768) { print_debug("Invalid (-32768) "); $sensor_poll['sensor_value'] = 0; } // Scale if (isset($sensor_db['sensor_multiplier']) && $sensor_db['sensor_multiplier'] != 0) { $sensor_poll['sensor_value'] *= $sensor_db['sensor_multiplier']; } // Unit conversion to SI (if required) $sensor_poll['sensor_value'] = value_to_si($sensor_poll['sensor_value'], $sensor_db['sensor_unit'], $class); //print_cli_data("Value", $sensor_poll['sensor_value'] . "$unit ", 3); // FIXME this block and the other block below it are kinda retarded. They should be merged and simplified. if ($sensor_poll['sensor_ignore'] || $sensor_poll['sensor_disable']) { $sensor_poll['sensor_event'] = 'ignore'; } else { if ($sensor_db['sensor_limit_low'] != '' && $sensor_poll['sensor_value'] < $sensor_db['sensor_limit_low'] || $sensor_db['sensor_limit'] != '' && $sensor_poll['sensor_value'] > $sensor_db['sensor_limit']) { $sensor_poll['sensor_event'] = 'alert'; $sensor_poll['sensor_status'] = 'Sensor critical thresholds exceeded.'; // FIXME - be more specific } else { if ($sensor_db['sensor_limit_low_warn'] != '' && $sensor_poll['sensor_value'] < $sensor_db['sensor_limit_low_warn'] || $sensor_db['sensor_limit_warn'] != '' && $sensor_poll['sensor_value'] > $sensor_db['sensor_limit_warn']) { $sensor_poll['sensor_event'] = 'warning'; $sensor_poll['sensor_status'] = 'Sensor warning thresholds exceeded.'; // FIXME - be more specific } else { $sensor_poll['sensor_event'] = 'ok'; $sensor_poll['sensor_status'] = ''; //if ($sensor_db['sensor_event'] != 'up' && $sensor_db['sensor_event'] != '') //{ // $sensor_poll['sensor_status'] = 'Sensor thresholds cleared.'; // FIXME - be more specific //} } } } // If last change never set, use current time if (empty($sensor_db['sensor_last_change'])) { $sensor_db['sensor_last_change'] = $sensor_polled_time; } if ($sensor_poll['sensor_event'] != $sensor_db['sensor_event']) { // Sensor event changed, log and set sensor_last_change $sensor_poll['status_last_change'] = $sensor_polled_time; if ($sensor_db['sensor_event'] == 'ignore') { print_message("[%ySensor Ignored%n]", 'color'); } else { if ($sensor_db['sensor_limit_low'] != "" && $sensor_db['sensor_value'] >= $sensor_db['sensor_limit_low'] && $sensor_poll['sensor_value'] < $sensor_db['sensor_limit_low']) { // If old value greater than low limit and new value less than low limit $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor_db['sensor_descr'] . " is under threshold: " . $sensor_poll['sensor_value'] . "{$unit} (< " . $sensor_db['sensor_limit_low'] . "{$unit})"; log_event(ucfirst($class) . ' ' . $sensor_db['sensor_descr'] . " under threshold: " . $sensor_poll['sensor_value'] . " {$unit} (< " . $sensor_db['sensor_limit_low'] . " {$unit})", $device, 'sensor', $sensor_db['sensor_id'], 'warning'); } else { if ($sensor_db['sensor_limit'] != "" && $sensor_db['sensor_value'] <= $sensor_db['sensor_limit'] && $sensor_poll['sensor_value'] > $sensor_db['sensor_limit']) { // If old value less than high limit and new value greater than high limit $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor_db['sensor_descr'] . " is over threshold: " . $sensor_poll['sensor_value'] . "{$unit} (> " . $sensor_db['sensor_limit'] . "{$unit})"; log_event(ucfirst($class) . ' ' . $sensor_db['sensor_descr'] . " above threshold: " . $sensor_poll['sensor_value'] . " {$unit} (> " . $sensor_db['sensor_limit'] . " {$unit})", $device, 'sensor', $sensor_db['sensor_id'], 'warning'); } } } } else { // If sensor not changed, leave old last_change $sensor_poll['sensor_last_change'] = $sensor_db['sensor_last_change']; } // Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['sensors']) { $json_data = array('value' => $sensor_poll['sensor_value']); messagebus_send(array('attribs' => array('t' => time(), 'device' => $device['hostname'], 'device_id' => $device['device_id'], 'e_type' => 'sensor', 'e_class' => $sensor_db['sensor_class'], 'e_type' => $sensor_db['sensor_type'], 'e_index' => $sensor_db['sensor_index']), 'data' => $json_data)); } // Add table row $table_rows[] = array($sensor_db['sensor_descr'], $sensor_db['sensor_class'], $sensor_db['sensor_type'], $sensor_db['poller_type'], $sensor_poll['sensor_value'] . $unit, $sensor_poll['sensor_event'], format_unixtime($sensor_poll['sensor_last_change'])); // Update StatsD/Carbon if ($config['statsd']['enable'] == TRUE) { StatsD::gauge(str_replace(".", "_", $device['hostname']) . '.' . 'sensor' . '.' . $sensor_db['sensor_class'] . '.' . $sensor_db['sensor_type'] . '.' . $sensor_db['sensor_index'], $sensor_poll['sensor_value']); } // Update RRD - FIXME - can't convert to NG because filename is dynamic! new function should return index instead of filename. $rrd_file = get_sensor_rrd($device, $sensor_db); rrdtool_create($device, $rrd_file, "DS:sensor:GAUGE:600:-20000:U"); rrdtool_update($device, $rrd_file, "N:" . $sensor_poll['sensor_value']); // Enable graph $graphs[$sensor_db['sensor_class']] = TRUE; // Check alerts $metrics = array(); $metrics['sensor_value'] = $sensor_poll['sensor_value']; $metrics['sensor_event'] = $sensor_poll['sensor_event']; $metrics['sensor_event_uptime'] = $sensor_polled_time - $sensor_poll['sensor_last_change']; $metrics['sensor_status'] = $sensor_poll['sensor_status']; check_entity('sensor', $sensor_db, $metrics); // Update SQL State if (is_numeric($sensor_db['sensor_polled'])) { dbUpdate(array('sensor_value' => $sensor_poll['sensor_value'], 'sensor_event' => $sensor_poll['sensor_event'], 'sensor_status' => $sensor_poll['sensor_status'], 'sensor_last_change' => $sensor_poll['sensor_last_change'], 'sensor_polled' => $sensor_polled_time), 'sensors-state', '`sensor_id` = ?', array($sensor_db['sensor_id'])); } else { dbInsert(array('sensor_id' => $sensor_db['sensor_id'], 'sensor_value' => $sensor_poll['sensor_value'], 'sensor_event' => $sensor_poll['sensor_event'], 'sensor_status' => $sensor_poll['sensor_status'], 'sensor_last_change' => $sensor_poll['sensor_last_change'], 'sensor_polled' => $sensor_polled_time), 'sensors-state'); } } }
/** * @dataProvider providerGetSensorRrd */ public function testGetSensorRrd($device, $sensor, $config, $result) { $GLOBAL['config'] = $config; $this->assertSame($result, get_sensor_rrd($device, $sensor)); }
echo 'Fetching IPMI sensor data...'; if ($config['own_hostname'] != $device['hostname'] || $ipmi['host'] != 'localhost') { $remote = ' -H ' . $ipmi['host'] . ' -U ' . $ipmi['user'] . ' -P ' . $ipmi['password']; } $results = external_exec($config['ipmitool'] . ' -I ' . $ipmi['type'] . ' -c ' . $remote . ' sdr 2>/dev/null'); echo " done.\n"; foreach (explode("\n", $results) as $row) { list($desc, $value, $type, $status) = explode(',', $row); $ipmi_sensor[$desc][$config['ipmi_unit'][$type]]['value'] = $value; $ipmi_sensor[$desc][$config['ipmi_unit'][$type]]['unit'] = $type; } foreach ($ipmi_rows as $ipmisensors) { echo 'Updating IPMI sensor ' . $ipmisensors['sensor_descr'] . '... '; $sensor = $ipmi_sensor[$ipmisensors['sensor_descr']][$ipmisensors['sensor_class']]['value']; $unit = $ipmi_sensor[$ipmisensors['sensor_descr']][$ipmisensors['sensor_class']]['unit']; $rrd_file = get_sensor_rrd($device, $ipmisensors); if (is_file($old_rrd_file)) { rename($old_rrd_file, $rrd_file); } if (!is_file($rrd_file)) { rrdtool_create($rrd_file, '--step 300 DS:sensor:GAUGE:600:-20000:20000 ' . $config['rrd_rra']); } echo $sensor . " {$unit}\n"; $fields = array('sensor' => $sensor); rrdtool_update($rrd_file, $fields); // FIXME warnings in event & mail not done here yet! dbUpdate(array('sensor_current' => $sensor, 'lastupdate' => array('NOW()')), 'sensors', 'poller_type = ? AND sensor_class = ? AND sensor_id = ?', array('ipmi', $ipmisensors['sensor_class'], $ipmisensors['sensor_id'])); } unset($ipmi_sensor); }
function poll_sensor($device, $class, $unit) { global $config, $agent_sensors, $ipmi_sensors; $sql = "SELECT *, `sensors`.`sensor_id` AS `sensor_id`"; $sql .= " FROM `sensors`"; $sql .= " LEFT JOIN `sensors-state` ON `sensors`.sensor_id = `sensors-state`.sensor_id"; $sql .= " WHERE `sensor_class` = ? AND `device_id` = ?"; foreach (dbFetchRows($sql, array($class, $device['device_id'])) as $sensor) { echo "Checking (" . $sensor['poller_type'] . ") {$class} " . $sensor['sensor_descr'] . " "; if ($sensor['poller_type'] == "snmp") { # if ($class == "temperature" && $device['os'] == "papouch") if ($class == "temperature") { for ($i = 0; $i < 5; $i++) { if ($debug) { echo "Attempt {$i} "; } $sensor_value = preg_replace("/[^0-9.]/", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB")); if (is_numeric($sensor_value) && $sensor_value != 9999) { break; } # TME sometimes sends 999.9 when it is right in the middle of an update; sleep(1); # Give the TME some time to reset } } else { $sensor_value = trim(str_replace("\"", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB"))); } } else { if ($sensor['poller_type'] == "agent") { if (isset($agent_sensors)) { $sensor_value = $agent_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current']; # FIXME pass unit? } else { echo "no agent data!\n"; continue; } } else { if ($sensor['poller_type'] == "ipmi") { if (isset($ipmi_sensors)) { $sensor_value = $ipmi_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current']; $unit = $ipmi_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['unit']; } else { echo "no IPMI data!\n"; continue; } } else { echo "unknown poller type!\n"; continue; } } } if ($sensor_value == -32768) { echo "Invalid (-32768) "; $sensor_value = 0; } if ($sensor['sensor_divisor']) { $sensor_value = $sensor_value / $sensor['sensor_divisor']; } if ($sensor['sensor_multiplier']) { $sensor_value = $sensor_value * $sensor['sensor_multiplier']; } $rrd_file = get_sensor_rrd($device, $sensor); if (!is_file($rrd_file)) { rrdtool_create($rrd_file, "--step 300 \\\n DS:sensor:GAUGE:600:-20000:U " . $config['rrd_rra']); //DS:sensor:GAUGE:600:-20000:20000 ".$config['rrd_rra']); } echo "{$sensor_value} {$unit} "; // FIXME also warn when crossing WARN level!! if ($sensor['sensor_ignore'] != "1") { if ($sensor['sensor_limit_low'] != "" && $sensor['sensor_value'] >= $sensor['sensor_limit_low'] && $sensor_value < $sensor['sensor_limit_low']) { $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is under threshold: " . $sensor_value . "{$unit} (< " . $sensor['sensor_limit_low'] . "{$unit})"; notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); print Console_Color::convert("[%rAlerting for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n"); log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . " under threshold: " . $sensor_value . " {$unit} (< " . $sensor['sensor_limit_low'] . " {$unit})", $device, $class, $sensor['sensor_id']); } else { if ($sensor['sensor_limit'] != "" && $sensor['sensor_value'] <= $sensor['sensor_limit'] && $sensor_value > $sensor['sensor_limit']) { $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is over threshold: " . $sensor_value . "{$unit} (> " . $sensor['sensor_limit'] . "{$unit})"; notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); print Console_Color::convert("[%rAlerting for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n"); log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . " above threshold: " . $sensor_value . " {$unit} (> " . $sensor['sensor_limit'] . " {$unit})", $device, $class, $sensor['sensor_id']); } } } else { print Console_Color::convert("[%ySensor Ignored%n]"); } echo "\n"; // Update RRD rrdtool_update($rrd_file, "N:{$sensor_value}"); // Update SQL State if (is_numeric($sensor['sensor_polled'])) { dbUpdate(array('sensor_value' => $sensor_value, 'sensor_polled' => time()), 'sensors-state', '`sensor_id` = ?', array($sensor['sensor_id'])); } else { dbInsert(array('sensor_id' => $sensor['sensor_id'], 'sensor_value' => $sensor_value, 'sensor_polled' => time()), 'sensors-state'); } } }
function poll_sensor($device, $class, $unit) { global $config, $memcache, $agent_sensors; foreach (dbFetchRows("SELECT * FROM `sensors` WHERE `sensor_class` = ? AND `device_id` = ?", array($class, $device['device_id'])) as $sensor) { echo "Checking (" . $sensor['poller_type'] . ") {$class} " . $sensor['sensor_descr'] . "... "; if ($sensor['poller_type'] == "snmp") { if ($class == "temperature") { for ($i = 0; $i < 5; $i++) { if ($debug) { echo "Attempt {$i} "; } $sensor_value = trim(str_replace("\"", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB"))); if (is_numeric($sensor_value) && $sensor_value != 9999) { break; } # TME sometimes sends 999.9 when it is right in the middle of an update; sleep(1); # Give the TME some time to reset } } else { $sensor_value = trim(str_replace("\"", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB"))); } } else { if ($sensor['poller_type'] == "agent") { if (isset($agent_sensors)) { $sensor_value = $agent_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current']; } else { echo "no agent data!\n"; continue; } } else { if ($sensor['poller_type'] == "ipmi") { echo " already polled.\n"; # ipmi should probably move here from the ipmi poller file (FIXME) continue; } else { echo "unknown poller type!\n"; continue; } } } if ($sensor_value == -32768) { echo "Invalid (-32768) "; $sensor_value = 0; } if ($sensor['sensor_divisor']) { $sensor_value = $sensor_value / $sensor['sensor_divisor']; } if ($sensor['sensor_multiplier']) { $sensor_value = $sensor_value * $sensor['sensor_multiplier']; } $rrd_file = get_sensor_rrd($device, $sensor); if (!is_file($rrd_file)) { rrdtool_create($rrd_file, "--step 300 \\\n DS:sensor:GAUGE:600:-20000:20000 " . $config['rrd_rra']); } echo "{$sensor_value} {$unit}\n"; rrdtool_update($rrd_file, "N:{$sensor_value}"); // FIXME also warn when crossing WARN level!! if ($sensor['sensor_limit_low'] != "" && $sensor['sensor_current'] > $sensor['sensor_limit_low'] && $sensor_value <= $sensor['sensor_limit_low'] && $sensor['sensor_alert'] == 1) { $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is under threshold: " . $sensor_value . "{$unit} (< " . $sensor['sensor_limit'] . "{$unit})"; notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); echo "Alerting for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "\n"; log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . " under threshold: " . $sensor_value . " {$unit} (< " . $sensor['sensor_limit_low'] . " {$unit})", $device, $class, $sensor['sensor_id']); } else { if ($sensor['sensor_limit'] != "" && $sensor['sensor_current'] < $sensor['sensor_limit'] && $sensor_value >= $sensor['sensor_limit'] && $sensor['sensor_alert'] == 1) { $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is over threshold: " . $sensor_value . "{$unit} (> " . $sensor['sensor_limit'] . "{$unit})"; notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); echo "Alerting for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "\n"; log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . " above threshold: " . $sensor_value . " {$unit} (> " . $sensor['sensor_limit'] . " {$unit})", $device, $class, $sensor['sensor_id']); } } if ($config['memcached']['enable']) { $memcache->set('sensor-' . $sensor['sensor_id'] . '-value', $sensor_value); } else { dbUpdate(array('sensor_current' => $sensor_value), 'sensors', '`sensor_class` = ? AND `sensor_id` = ?', array($class, $sensor['sensor_id'])); } } }
function poll_sensor($device, $class, $unit, &$oid_cache) { global $config, $agent_sensors, $ipmi_sensors; $sql = "SELECT *, `sensors`.`sensor_id` AS `sensor_id`"; $sql .= " FROM `sensors`"; $sql .= " LEFT JOIN `sensors-state` ON `sensors`.sensor_id = `sensors-state`.sensor_id"; $sql .= " WHERE `sensor_class` = ? AND `device_id` = ?"; foreach (dbFetchRows($sql, array($class, $device['device_id'])) as $sensor) { echo "Checking (" . $sensor['poller_type'] . ") {$class} " . $sensor['sensor_descr'] . " "; $sensor_new = $sensor; // Cache non-humanized sensor array humanize_sensor($sensor); if ($sensor['poller_type'] == "snmp") { # if ($class == "temperature" && $device['os'] == "papouch") // Why all temperature? if ($class == "temperature" && !$sensor['sensor_state']) { for ($i = 0; $i < 5; $i++) { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$sensor['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_value = $oid_cache[$sensor['sensor_oid']]; } else { $sensor_value = preg_replace("/[^0-9\\-\\.]/", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs())); } if (is_numeric($sensor_value) && $sensor_value != 9999) { break; } // TME sometimes sends 999.9 when it is right in the middle of an update; sleep(1); # Give the TME some time to reset } // Also reduce value by 32 if sensor in Fahrenheit unit if ($sensor['sensor_divisor'] == 9 && $sensor['sensor_multiplier'] == 5) { $sensor_value -= 32; } } else { if ($class == "runtime" && !$sensor['sensor_state']) { if (isset($oid_cache[$sensor['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_value = timeticks_to_sec($oid_cache[$sensor['sensor_oid']]); } else { $sensor_value = trim(str_replace("\"", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs()))); $sensor_value = timeticks_to_sec($sensor_value); } } else { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$sensor['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_value = $oid_cache[$sensor['sensor_oid']]; } else { $sensor_value = trim(str_replace("\"", "", snmp_get($device, $sensor['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs()))); } } } } else { if ($sensor['poller_type'] == "agent") { if (isset($agent_sensors)) { $sensor_value = $agent_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current']; # FIXME pass unit? } else { print_warning("No agent sensor data."); continue; } } else { if ($sensor['poller_type'] == "ipmi") { if (isset($ipmi_sensors)) { $sensor_value = $ipmi_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current']; $unit = $ipmi_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['unit']; } else { print_warning("No IPMI sensor data."); continue; } } else { print_warning("Unknown sensor poller type."); continue; } } } if (!$sensor['sensor_state']) { if ($sensor_value == -32768) { echo "Invalid (-32768) "; $sensor_value = 0; } if ($sensor['sensor_divisor']) { $sensor_value = $sensor_value / $sensor['sensor_divisor']; } if ($sensor['sensor_multiplier']) { $sensor_value = $sensor_value * $sensor['sensor_multiplier']; } } $rrd_file = get_sensor_rrd($device, $sensor); if (!is_file($rrd_file)) { rrdtool_create($rrd_file, "DS:sensor:GAUGE:600:-20000:U"); //DS:sensor:GAUGE:600:-20000:20000 "); } echo "{$sensor_value} {$unit} "; // Write new value and humanize (for alert checks) $sensor_new['sensor_value'] = $sensor_value; humanize_sensor($sensor_new); // FIXME also warn when crossing WARN level!! if ($sensor['state_event'] != 'ignore') { if (!$sensor['sensor_state']) { if ($sensor['sensor_limit_low'] != "" && $sensor['sensor_value'] >= $sensor['sensor_limit_low'] && $sensor_value < $sensor['sensor_limit_low']) { $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is under threshold: " . $sensor_value . "{$unit} (< " . $sensor['sensor_limit_low'] . "{$unit})"; notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); print_message("[%rAlerting for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . " under threshold: " . $sensor_value . " {$unit} (< " . $sensor['sensor_limit_low'] . " {$unit})", $device, $class, $sensor['sensor_id']); } else { if ($sensor['sensor_limit'] != "" && $sensor['sensor_value'] <= $sensor['sensor_limit'] && $sensor_value > $sensor['sensor_limit']) { $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is over threshold: " . $sensor_value . "{$unit} (> " . $sensor['sensor_limit'] . "{$unit})"; notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); print_message("[%rAlerting for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); log_event(ucfirst($class) . ' ' . $sensor['sensor_descr'] . " above threshold: " . $sensor_value . " {$unit} (> " . $sensor['sensor_limit'] . " {$unit})", $device, $class, $sensor['sensor_id']); } } } else { if ($sensor_value != $sensor['sensor_value'] && $sensor['state_value'] != '') { $sensor_state_name = $sensor_new['state_name']; $sensor_state_event = $sensor_new['state_event']; switch ($sensor_state_event) { case 'alert': $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " is under ALERT state: " . $sensor_state_name . " (previous state: " . $sensor['state_name'] . ")"; print_message("[%rSensor ALARM for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); notify($device, ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); log_event($msg, $device, $class, $sensor['sensor_id']); break; case 'warning': $msg = ucfirst($class) . " Warning: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " in WARNING state: " . $sensor_state_name . " (previous state: " . $sensor['state_name'] . ")"; print_message("[%rSensor WARNING for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); log_event($msg, $device, $class, $sensor['sensor_id']); break; case 'up': $msg = ucfirst($class) . " Up: " . $device['hostname'] . " " . $sensor['sensor_descr'] . " in NORMAL state: " . $sensor_state_name . " (previous state: " . $sensor['state_name'] . ")"; print_message("[%rSensor UP for " . $device['hostname'] . " " . $sensor['sensor_descr'] . "%n\n", 'color'); if ($sensor['state_event'] != 'warning') { notify($device, ucfirst($class) . " Up: " . $device['hostname'] . " " . $sensor['sensor_descr'], $msg); } log_event($msg, $device, $class, $sensor['sensor_id']); break; } } } } else { print_message("[%ySensor Ignored%n]", 'color'); } echo "\n"; // Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['sensors']) { $json_data = array('value' => $sensor_value); messagebus_send(array('attribs' => array('t' => time(), 'device' => $device['hostname'], 'device_id' => $device['device_id'], 'e_type' => 'sensor', 'e_class' => $sensor['sensor_class'], 'e_type' => $sensor['sensor_type'], 'e_index' => $sensor['sensor_index']), 'data' => $json_data)); } // Update StatsD/Carbon if ($config['statsd']['enable'] == TRUE) { StatsD::gauge(str_replace(".", "_", $device['hostname']) . '.' . 'sensor' . '.' . $sensor['sensor_class'] . '.' . $sensor['sensor_type'] . '.' . $sensor['sensor_index'], $sensor_value); } // Update RRD rrdtool_update($rrd_file, "N:{$sensor_value}"); // Check alerts if (!$sensor['sensor_state']) { check_entity('sensor', $sensor, array('sensor_value' => $sensor_new['sensor_value'])); } check_entity('sensor', $sensor, array('sensor_event' => $sensor_new['state_event'])); // Update SQL State if (is_numeric($sensor['sensor_polled'])) { dbUpdate(array('sensor_value' => $sensor_value, 'sensor_polled' => time()), 'sensors-state', '`sensor_id` = ?', array($sensor['sensor_id'])); } else { dbInsert(array('sensor_id' => $sensor['sensor_id'], 'sensor_value' => $sensor_value, 'sensor_polled' => time()), 'sensors-state'); } } }
function poll_sensor($device, $class, $unit, &$oid_cache) { global $config, $agent_sensors, $ipmi_sensors, $graphs; $sql = "SELECT *, `sensors`.`sensor_id` AS `sensor_id`"; $sql .= " FROM `sensors`"; $sql .= " LEFT JOIN `sensors-state` ON `sensors`.sensor_id = `sensors-state`.sensor_id"; $sql .= " WHERE `sensor_class` = ? AND `device_id` = ?"; foreach (dbFetchRows($sql, array($class, $device['device_id'])) as $sensor_db) { $sensor_poll = array(); if (OBS_DEBUG) { echo "检测中 (" . $sensor_db['poller_type'] . ") {$class} " . $sensor_db['sensor_descr'] . " "; print_r($sensor_db); } if ($sensor_db['poller_type'] == "snmp") { # if ($class == "temperature" && $device['os'] == "papouch") // Why all temperature? if ($class == "temperature") { for ($i = 0; $i < 5; $i++) { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$sensor_db['sensor_oid']])) { print_debug("取值来自 oid_cache"); $sensor_poll['sensor_value'] = $oid_cache[$sensor_db['sensor_oid']]; } else { $sensor_poll['sensor_value'] = snmp_fix_numeric(snmp_get($device, $sensor_db['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs())); } if (is_numeric($sensor_poll['sensor_value']) && $sensor_poll['sensor_value'] != 9999) { break; } // Papouch TME sometimes sends 999.9 when it is right in the middle of an update; sleep(1); // Give the TME some time to reset } // If we received 999.9 degrees still, reset to Unknown. if ($sensor_poll['sensor_value'] == 9999) { $sensor_poll['sensor_value'] = "U"; } } else { if ($class == "runtime") { if (isset($oid_cache[$sensor_db['sensor_oid']])) { print_debug("value taken from oid_cache"); $sensor_poll['sensor_value'] = $oid_cache[$sensor_db['sensor_oid']]; } else { $sensor_poll['sensor_value'] = snmp_get($device, $sensor_db['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs()); } if (strpos($sensor_poll['sensor_value'], ':') !== FALSE) { // Use timetick conversion only when snmpdata is formatted as timetick 0:0:21:00.00 $sensor_poll['sensor_value'] = timeticks_to_sec($sensor_poll['sensor_value']); } } else { // Take value from $oid_cache if we have it, else snmp_get it if (is_numeric($oid_cache[$sensor_db['sensor_oid']])) { print_debug("取值来自 oid_cache"); $sensor_poll['sensor_value'] = $oid_cache[$sensor_db['sensor_oid']]; } else { $sensor_poll['sensor_value'] = snmp_fix_numeric(snmp_get($device, $sensor_db['sensor_oid'], "-OUqnv", "SNMPv2-MIB", mib_dirs())); } } } } else { if ($sensor_db['poller_type'] == "agent") { if (isset($agent_sensors)) { $sensor_poll['sensor_value'] = $agent_sensors[$class][$sensor_db['sensor_type']][$sensor_db['sensor_index']]['current']; // FIXME pass unit? } else { print_warning("传感器中的数据无可用的代理."); continue; } } else { if ($sensor_db['poller_type'] == "ipmi") { if (isset($ipmi_sensors)) { $sensor_poll['sensor_value'] = $ipmi_sensors[$class][$sensor_db['sensor_type']][$sensor_db['sensor_index']]['current']; $unit = $ipmi_sensors[$class][$sensor_db['sensor_type']][$sensor_db['sensor_index']]['unit']; } else { print_warning("IPMI传感器数据不可用."); continue; } } else { print_warning("未知的系缆柱型传感器."); continue; } } } if (OBS_DEBUG) { print_r($sensor_poll); } if ($sensor_poll['sensor_value'] == -32768) { print_debug("Invalid (-32768) "); $sensor_poll['sensor_value'] = 0; } /// FIXME. This is old pre 'scale' method, remove in r7000 if (isset($sensor_db['sensor_divisor']) && $sensor_db['sensor_divisor'] > 1) { /// This is fix for r5351 if ($sensor_db['sensor_multiplier'] >= 1) { $sensor_poll['sensor_value'] = $sensor_poll['sensor_value'] / $sensor_db['sensor_divisor']; } } if (isset($sensor_db['sensor_multiplier']) && $sensor_db['sensor_multiplier'] != 0) { $f2c = FALSE; if ($class == "temperature") { // This is weird hardcode for convert Fahrenheit to Celsius foreach (array(1, 0.1) as $scale_tmp) { if (float_cmp($sensor_db['sensor_multiplier'], $scale_tmp * 5 / 9) === 0) { $sensor_db['sensor_multiplier'] = $scale_tmp; $f2c = TRUE; break; } } } $sensor_poll['sensor_value'] *= $sensor_db['sensor_multiplier']; if ($f2c) { $sensor_poll['sensor_value'] = f2c($sensor_poll['sensor_value']); print_debug('TEMPERATURE sensor: Fahrenheit -> Celsius'); } } $rrd_file = get_sensor_rrd($device, $sensor_db); rrdtool_create($device, $rrd_file, "DS:sensor:GAUGE:600:-20000:U"); echo $sensor_poll['sensor_value'] . "{$unit} "; // FIXME this block and the other block below it are kinda retarded. They should be merged and simplified. if ($sensor_poll['sensor_ignore'] || $sensor_poll['sensor_disable']) { $sensor_poll['sensor_event'] = 'ignore'; } else { if ($sensor_db['sensor_limit_low_warn'] != '' && $sensor_poll['sensor_value'] < $sensor_db['sensor_limit_low_warn'] || $sensor_db['sensor_limit_warn'] != '' && $sensor_poll['sensor_value'] > $sensor_db['sensor_limit_warn']) { $sensor_poll['sensor_event'] = 'warning'; $sensor_poll['sensor_status'] = 'Sensor warning thresholds exceeded.'; // FIXME - be more specific } else { if (($sensor_db['sensor_limit_low'] != '' && $sensor_poll['sensor_value'] < $sensor_db['sensor_limit_low'] || $sensor_db['sensor_limit'] != '' && $sensor_poll['sensor_value'] > $sensor_db['sensor_limit']) && $sensor_db['sensor_value'] != '') { $sensor_poll['sensor_event'] = 'alert'; $sensor_poll['sensor_status'] = 'Sensor critical thresholds exceeded.'; // FIXME - be more specific } else { $sensor_poll['sensor_event'] = 'up'; $sensor_poll['sensor_status'] = ''; //if ($sensor_db['sensor_event'] != 'up' && $sensor_db['sensor_event'] != '') //{ // $sensor_poll['sensor_status'] = 'Sensor thresholds cleared.'; // FIXME - be more specific //} } } } // FIXME I left the eventlog code for now, as soon as alerts send an entry to the eventlog this can go. if ($sensor_db['sensor_event'] != 'ignore') { if ($sensor_db['sensor_limit_low'] != "" && $sensor_db['sensor_value'] >= $sensor_db['sensor_limit_low'] && $sensor_poll['sensor_value'] < $sensor_db['sensor_limit_low']) { // If old value greater than low limit and new value less than low limit $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor_db['sensor_descr'] . " is under threshold: " . $sensor_poll['sensor_value'] . "{$unit} (< " . $sensor_db['sensor_limit_low'] . "{$unit})"; log_event(ucfirst($class) . ' ' . $sensor_db['sensor_descr'] . " under threshold: " . $sensor_poll['sensor_value'] . " {$unit} (< " . $sensor_db['sensor_limit_low'] . " {$unit})", $device, 'sensor', $sensor_db['sensor_id'], 'warning'); } else { if ($sensor_db['sensor_limit'] != "" && $sensor_db['sensor_value'] <= $sensor_db['sensor_limit'] && $sensor_poll['sensor_value'] > $sensor_db['sensor_limit']) { // If old value less than high limit and new value greater than high limit $msg = ucfirst($class) . " Alarm: " . $device['hostname'] . " " . $sensor_db['sensor_descr'] . " is over threshold: " . $sensor_poll['sensor_value'] . "{$unit} (> " . $sensor_db['sensor_limit'] . "{$unit})"; log_event(ucfirst($class) . ' ' . $sensor_db['sensor_descr'] . " above threshold: " . $sensor_poll['sensor_value'] . " {$unit} (> " . $sensor_db['sensor_limit'] . " {$unit})", $device, 'sensor', $sensor_db['sensor_id'], 'warning'); } } } else { print_message("[%ySensor Ignored%n]", 'color'); } echo PHP_EOL; // Send statistics array via AMQP/JSON if AMQP is enabled globally and for the ports module if ($config['amqp']['enable'] == TRUE && $config['amqp']['modules']['sensors']) { $json_data = array('value' => $sensor_poll['sensor_value']); messagebus_send(array('attribs' => array('t' => time(), 'device' => $device['hostname'], 'device_id' => $device['device_id'], 'e_type' => 'sensor', 'e_class' => $sensor_db['sensor_class'], 'e_type' => $sensor_db['sensor_type'], 'e_index' => $sensor_db['sensor_index']), 'data' => $json_data)); } // Update StatsD/Carbon if ($config['statsd']['enable'] == TRUE) { StatsD::gauge(str_replace(".", "_", $device['hostname']) . '.' . 'sensor' . '.' . $sensor_db['sensor_class'] . '.' . $sensor_db['sensor_type'] . '.' . $sensor_db['sensor_index'], $sensor_poll['sensor_value']); } // Update RRD rrdtool_update($device, $rrd_file, "N:" . $sensor_poll['sensor_value']); // Enable graph $graphs[$sensor_db['sensor_class']] = TRUE; // Check alerts $metrics = array(); $metrics['sensor_value'] = $sensor_poll['sensor_value']; $metrics['sensor_event'] = $sensor_poll['sensor_event']; $metrics['sensor_status'] = $sensor_poll['sensor_status']; check_entity('sensor', $sensor_db, $metrics); // Update SQL State if (is_numeric($sensor_db['sensor_polled'])) { dbUpdate(array('sensor_value' => $sensor_poll['sensor_value'], 'sensor_event' => $sensor_poll['sensor_event'], 'sensor_status' => $sensor_poll['sensor_status'], 'sensor_polled' => time()), 'sensors-state', '`sensor_id` = ?', array($sensor_db['sensor_id'])); } else { dbInsert(array('sensor_id' => $sensor_db['sensor_id'], 'sensor_value' => $sensor_poll['sensor_value'], 'sensor_event' => $sensor_poll['sensor_event'], 'sensor_status' => $sensor_poll['sensor_status'], 'sensor_polled' => time()), 'sensors-state'); } } }