-
Autor
Hi Leute,
ich hab mir mal die Mühe gemacht das Nagios Plugin für Shellys zu überarbeiten damit es auch mit Gen2 funktioniert.
Bitte verzeiht mir den "schrecklichen" Code. Ich bin halt kein Programmierer Wenn das jemand aufhübschen möchte dann gerne Ich denke mir halt, hauptsache es funktioniert
Falls jemand Fehler finden sollte dann bitte hier posten. Aber vorab zur Info, ich hatte gerade Urlaub und Zeit. Ansonsten ist meine Zeit begrenzt und je nach Umfang werd ich mich nicht zeitnah mit dem Problem auseinander setzen können.
Das Skript ist in php geschrieben und gedacht für den Einsatz mit CheckMK oder Nagios.
Aber bitte keine Anfragen wie man das ganze in CheckMK oder Nagios reinbekommt. Da fehlt mir aktuell die Zeit dazu und es gibt eigentlich auch genügend Tutorials bzw. bei CheckMK ist es in der Doku erklärt.
Original stammt von https://github.com/shelly-tools/check_shelly
Viel Spaß damit
#!/usr/bin/php
<?php
new ShellyDevice();
class ShellyDevice {
public $Device;
public function __construct() {
// define options for cli call
$options = getopt("h:u::p::w::c::H::", array("host:", "user::", "password::","warning::", "critical::" , "help"));
// If help or the shortcut H is set print the help message
if(isset($options['help']) || isset($options['H'])) {
echo "check_shelly is a nagios compatible check to monitor the health of shelly hardware.\n\n";
echo "You can run it for example with:\n";
echo "./check_shelly -h <SHELLY_IP>\n\n";
echo "If you have authentication enabled then you have to run:\n";
echo "./check_shelly -h <SHELLY_IP> -u <USER> -p <PASSWORD>\n\n";
echo "To change the warning or the critical value you can pass in -w or -c to change it\n";
echo "./check_shelly -h <SHELLY_IP> -w <WARNING> -c <CRITICAL>\n";
echo "\n\nThe critical or warning threshold refers to the cpu usage OR the filesystem usage.";
echo "Available flags:\n";
echo "\t--host\t\t-h\t(required flag) The hostname or IP-Adress of the shelly\n";
echo "\t--user\t\t-u\tThe username for the Shelly, when the shelly needs authentication\n";
echo "\t--password\t-p\tThe password for the Shelly, when the shelly needs authentication\n";
echo "\t--warning\t-w\tThe warning threshold. If the shelly has more RAM or disk usage then the check is warning\n";
echo "\t--critical\t-c\tThe critical threshold. If the shelly has more RAM or disk usage then the check is critical\n";
echo "\t--help\t\t-h\tprints this message\n";
exit(0);
}
// If no host is set print an error
if(!isset($options['host']) && !isset($options['h'])) {
echo "parameter -h || --host is missing \n";
exit(3);
}
$host = isset($options['host']) ? $options['host'] : $options['h'];
$user = isset($options['user']) ? $options['user'] : (isset($options['u']) ? $options['u'] : false);
$password = isset($options['password']) ? $options['password'] : (isset($options['p']) ? $options['p'] : false);
$this->Device['check']['warning'] = isset($options['warning']) ? $options['warning'] : (isset($options['w']) ? $options['w'] : 90);
$this->Device['check']['critical'] = isset($options['critical']) ? $options['critical'] : (isset($options['c']) ? $options['c'] : 95);
// check type of Shelly
list($typestatus) = get_headers("http://" . $host . '/status');
if (strpos($typestatus, '200') == TRUE) {
$Type = "old";
}
else {
$Type = "new";
}
if (($Type) == 'new') {
$this->_discoverShellynew($host, $user, $password);
$this->_renderOutputnew();
}
else {
$this->_discoverShellyold($host, $user, $password);
$this->_renderOutputold();
}
}
private function _discoverShellyold($host, $user = false, $password = false) {
// discover status and settings
$shellystatus = "http://" . $host . '/status';
$shellysettings = "http://" . $host . '/settings';
$shellyinfo = "http://" . $host . '/shelly';
//Initialize a Curl handler
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'curl');
curl_setopt($ch, CURLOPT_TIMEOUT, 5); //timeout after 5 seconds
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_URL, $shellystatus);
$this->Device['status'] = json_decode(curl_exec ($ch), true);
curl_setopt($ch, CURLOPT_URL, $shellyinfo);
$this->Device['info'] = json_decode(curl_exec ($ch), true);
// discovery failed, probably a username / password protected?
if (!is_array($this->Device['status']) && $this->Device['info']['auth'] == true) {
echo 'UNKNOWN: Shelly health is unkown. The device is protected with username and password.'. "\n";
exit(3);
}
// discovery failed but auth not set, probably a timeout?
if (!is_array($this->Device['status'])) {
echo 'UNKNOWN: Shelly health status is unknown. Got no response from device.'. "\n";
exit(3);
}
if (isset($this->Device['status']['meters']) && is_array($this->Device['status']['meters'])) {
$this->Device['meters'] = $this->Device['status']['meters'];
}
else
$this->Device['meters'] = '';
if (isset($this->Device['status']['temperature'])) {
$this->Device['temperature'] = $this->Device['status']['temperature'];
}
if (isset($this->Device['status']['emeters']) && is_array($this->Device['status']['emeters'])) {
$this->Device['emeters'] = $this->Device['status']['emeters'];
}
else
$this->Device['emeters'] = '';
// Discover Settings
curl_setopt($ch, CURLOPT_URL, $shellysettings);
$this->Device['settings'] = json_decode(curl_exec ($ch), true);
$this->Device['uptime'] = secondsToTime($this->Device['status']['uptime']);
$this->Device['uptime_ts'] = $this->Device['status']['uptime'];
$this->Device['check']['exit_code'] = 0;
// calculate ram usage
$this->Device['ram']['ram_total'] = $this->Device['status']['ram_total'];
$this->Device['ram']['ram_free'] = $this->Device['status']['ram_free'];
$this->Device['ram']['ram_used'] = $this->Device['status']['ram_total'] - $this->Device['status']['ram_free'];
$this->Device['ram']['usage'] = round($this->Device['ram']['ram_used'] * 100 / $this->Device['ram']['ram_total'], 2);
// calculate filesystem usage
$this->Device['fs']['fs_size'] = $this->Device['status']['fs_size'];
$this->Device['fs']['fs_free'] = $this->Device['status']['fs_free'];
$this->Device['fs']['fs_used'] = $this->Device['status']['fs_size'] - $this->Device['status']['fs_free'];
$this->Device['fs']['usage'] = round($this->Device['fs']['fs_used'] * 100 / $this->Device['fs']['fs_size'], 2);
if ($this->Device['ram']['usage'] > $this->Device['check']['warning'] || $this->Device['fs']['usage'] > $this->Device['check']['warning'] )
$this->Device['check']['exit_code'] = 1;
if ($this->Device['ram']['usage'] > $this->Device['check']['critical'] || $this->Device['fs']['usage'] > $this->Device['check']['critical'] )
$this->Device['check']['exit_code'] = 2;
}
private function _discoverShellynew($host, $user = false, $password = false) {
// discover status and settings
$shellystatus = "http://" . $host . '/rpc/Shelly.GetStatus';
$shellysettings = "http://" . $host . '/rpc/Shelly.GetDeviceInfo';
$shellyinfo = "http://" . $host . '/shelly';
//Initialize a Curl handler
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'curl');
curl_setopt($ch, CURLOPT_TIMEOUT, 5); //timeout after 5 seconds
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_URL, $shellystatus);
$this->Device['status'] = json_decode(curl_exec ($ch), true);
curl_setopt($ch, CURLOPT_URL, $shellyinfo);
$this->Device['info'] = json_decode(curl_exec ($ch), true);
// discovery failed, probably a username / password protected?
if (!is_array($this->Device['status']) && $this->Device['info']['auth'] == true) {
echo 'UNKNOWN: Shelly health is unkown. The device is protected with username and password.'. "\n";
exit(3);
}
// discovery failed but auth not set, probably a timeout?
if (!is_array($this->Device['status'])) {
echo 'UNKNOWN: Shelly health status is unknown. Got no response from device.'. "\n";
exit(3);
}
/* ???????????
if (isset($this->Device['status']['meters']) && is_array($this->Device['status']['meters'])) {
$this->Device['meters'] = $this->Device['status']['meters'];
}
else
$this->Device['meters'] = '';
*/
if (isset($this->Device['status']['switch:0']['temperature']['tC'])) {
$this->Device['temperature'] = $this->Device['status']['switch:0']['temperature']['tC'];
}
if (isset($this->Device['status']['cover:0']['temperature']['tC'])) {
$this->Device['temperature'] = $this->Device['status']['cover:0']['temperature']['tC'];
}
if (isset($this->Device['status']['emeters']) && is_array($this->Device['status']['emeters'])) {
$this->Device['emeters'] = $this->Device['status']['emeters'];
}
else
$this->Device['emeters'] = '';
// Discover Settings
curl_setopt($ch, CURLOPT_URL, $shellysettings);
$this->Device['settings'] = json_decode(curl_exec ($ch), true);
$this->Device['uptime'] = secondsToTime($this->Device['status']['sys']['uptime']);
$this->Device['uptime_ts'] = $this->Device['status']['sys']['uptime'];
$this->Device['check']['exit_code'] = 0;
// calculate ram usage
$this->Device['ram']['ram_total'] = $this->Device['status']['sys']['ram_size'];
$this->Device['ram']['ram_free'] = $this->Device['status']['sys']['ram_free'];
$this->Device['ram']['ram_used'] = $this->Device['status']['sys']['ram_size'] - $this->Device['status']['sys']['ram_free'];
$this->Device['ram']['usage'] = round($this->Device['ram']['ram_used'] * 100 / $this->Device['ram']['ram_total'], 2);
// calculate filesystem usage
$this->Device['fs']['fs_size'] = $this->Device['status']['sys']['fs_size'];
$this->Device['fs']['fs_free'] = $this->Device['status']['sys']['fs_free'];
$this->Device['fs']['fs_used'] = $this->Device['status']['sys']['fs_size'] - $this->Device['status']['sys']['fs_free'];
$this->Device['fs']['usage'] = round($this->Device['fs']['fs_used'] * 100 / $this->Device['fs']['fs_size'], 2);
if ($this->Device['ram']['usage'] > $this->Device['check']['warning'] || $this->Device['fs']['usage'] > $this->Device['check']['warning'] )
$this->Device['check']['exit_code'] = 1;
if ($this->Device['ram']['usage'] > $this->Device['check']['critical'] || $this->Device['fs']['usage'] > $this->Device['check']['critical'] )
$this->Device['check']['exit_code'] = 2;
}
// _renderOutput will generate the nagios default output with performance data
private function _renderOutputold() {
// generate the plugin output
if ($this->Device['check']['exit_code'] == 0)
echo 'OK: ' . $this->Device['settings']['name'] . ' - Type: ' . $this->Device['settings']['device']['type'] . ' - Mode: ' . $this->Device['settings']['mode'] . ' (Uptime: ' . $this->Device['uptime']. ') is healthy.';
if ($this->Device['check']['exit_code'] == 1)
echo 'WARNING: ' . $this->Device['settings']['name'] . ' - Type: ' . $this->Device['settings']['device']['type'] . ' - Mode: ' . $this->Device['settings']['mode'] . ' (Uptime: ' . $this->Device['uptime']. ') reported problems. Please check details...';
if ($this->Device['check']['exit_code'] == 2)
echo 'CRITICAL: ' . $this->Device['settings']['name'] . ' - Type: ' . $this->Device['settings']['device']['type'] . ' - Mode: ' . $this->Device['settings']['mode'] . ' (Uptime: ' . $this->Device['uptime']. ') reported problems. Please check details...';
if (isset($this->Device['status']['inputs'])) {
foreach ($this->Device['status']['inputs'] as $input => $state) {
echo "\n Input " .$input . ': ' . ($state == 1 ? "on" : "off");
}
}
if (isset($this->Device['status']['relays'])) {
foreach ($this->Device['status']['relays'] as $relay => $state) {
echo "\n Relay " .$relay . ': ' . ($state['ison'] == true ? "on" : "off");
}
}
if (isset($this->Device['status']['lights'])) {
foreach ($this->Device['status']['lights'] as $light => $state) {
echo "\n Light " .$light . ': ' . ($state['ison'] == true ? "on" : "off");
}
}
if (isset($this->Device['status']['rollers'])) {
foreach ($this->Device['status']['rollers'] as $rollers => $state) {
echo "\n Position " .$rollers . ': ' . ($state['current_pos']) . '%';
}
}
echo "\n WiFi: " . $this->Device['status']['wifi_sta']['ssid'];
// add default performance data => ramusage and fsusage
echo ' |';
echo ' uptime='. $this->Device['uptime_ts'] . ';;;;';
echo ' rssi='. $this->Device['status']['wifi_sta']['rssi'] . ';;;;';
if (isset($this->Device['status']['voltage'])) {
echo ' voltage=' . $this->Device['status']['voltage'] . ';;;;';
}
echo ' ram='. $this->Device['ram']['ram_used'] . ';;;0;'. $this->Device['ram']['ram_total'];
echo ' ramusage='. $this->Device['ram']['usage'] . '%;' . $this->Device['check']['warning'] . ';' . $this->Device['check']['critical'] . ';0;100';
echo ' fs='. $this->Device['fs']['fs_used'] . ';;;0;'. $this->Device['fs']['fs_size'];
echo ' fsusage='. $this->Device['fs']['usage'] . '%;' . $this->Device['check']['warning'] . ';' . $this->Device['check']['critical'] . ';0;100';
// if meters is set, then add the meters performance data to the output
if (is_array($this->Device['meters'])) {
foreach($this->Device['meters'] as $key => $value) {
echo ' power' . $key . '=' . $value['power'] . ';;;;';
}
}
// if emeters is set, then add the emeters performance data to the output
if (is_array($this->Device['emeters'])) {
foreach($this->Device['emeters'] as $key => $value) {
echo ' power' . $key . '=' . $value['power'] . ';;;;';
echo ' reactive' . $key . '=' . $value['reactive'] . ';;;;';
echo ' voltage' . $key . '=' . $value['voltage'] . ';;;;';
}
}
// if temperature is set, then add the temperature performance data to the output
if (isset($this->Device['temperature']))
echo ' temperature=' . $this->Device['temperature'] . ';;;;';
echo "\n";
}
private function _renderOutputnew() {
// generate the plugin output
if ($this->Device['check']['exit_code'] == 0)
echo 'OK: ' . $this->Device['settings']['name'] . ' - Type: ' . $this->Device['settings']['app'] . ' - Mode: ' . $this->Device['settings']['profile'] . ' (Uptime: ' . $this->Device['uptime']. ') is healthy.';
if ($this->Device['check']['exit_code'] == 1)
echo 'WARNING: ' . $this->Device['settings']['name'] . ' - Type: ' . $this->Device['settings']['app'] . ' - Mode: ' . $this->Device['settings']['profile'] . ' (Uptime: ' . $this->Device['uptime']. ') reported problems. Please check details...';
if ($this->Device['check']['exit_code'] == 2)
echo 'CRITICAL: ' . $this->Device['settings']['name'] . ' - Type: ' . $this->Device['settings']['app'] . ' - Mode: ' . $this->Device['settings']['profile'] . ' (Uptime: ' . $this->Device['uptime']. ') reported problems. Please check details...';
/* from old
if (isset($this->Device['status']['inputs'])) {
foreach ($this->Device['status']['inputs'] as $input => $state) {
echo "\n Input " .$input . ': ' . ($state == 1 ? "on" : "off");
}
}
*/
if (isset($this->Device['status']['input:0']))
echo "\n Input 0: " . ($this->Device['status']['input:0']['state'] == 1 ? "on" : "off");
if (isset($this->Device['status']['input:1']))
echo "\n Input 1: " . ($this->Device['status']['input:1']['state'] == 1 ? "on" : "off");
if (isset($this->Device['status']['input:2']))
echo "\n Input 2: " . ($this->Device['status']['input:2']['state'] == 1 ? "on" : "off");
if (isset($this->Device['status']['input:3']))
echo "\n Input 3: " . ($this->Device['status']['input:3']['state'] == 1 ? "on" : "off");
if (isset($this->Device['status']['switch:0']))
echo "\n Output 0: " .($this->Device['status']['switch:0']['output'] == 1 ? "on" : "off");
if (isset($this->Device['status']['switch:1']))
echo "\n Output 1: " .($this->Device['status']['switch:1']['output'] == 1 ? "on" : "off");
if (isset($this->Device['status']['switch:2']))
echo "\n Output 2: " .($this->Device['status']['switch:2']['output'] == 1 ? "on" : "off");
if (isset($this->Device['status']['switch:3']))
echo "\n Output 3: " .($this->Device['status']['switch:3']['output'] == 1 ? "on" : "off");
if (isset($this->Device['status']['cover:0']['current_pos']))
echo "\n Cover 0: Position " . $this->Device['status']['cover:0']['current_pos'] . "%" . " - Voltage " . $this->Device['status']['cover:0']['voltage'] . "V - Power " . $this->Device['status']['cover:0']['apower'] . "W - Current ". $this->Device['status']['cover:0']['current'] . "A";
if (isset($this->Device['status']['cover:1']['current_pos']))
echo "\n Cover 1: Position " . $this->Device['status']['cover:1']['current_pos'] . "%" . " - Voltage " . $this->Device['status']['cover:1']['voltage'] . "V - Power " . $this->Device['status']['cover:1']['apower'] . "W - Current ". $this->Device['status']['cover:1']['current'] . "A";
/* from old
if (isset($this->Device['status']['switch:0'])) {
foreach ($this->Device['status']['relays'] as $relay => $state) {
echo "\n Relay " .$relay . ': ' . ($state['ison'] == true ? "on" : "off");
}
}
*/
if (isset($this->Device['status']['lights'])) {
foreach ($this->Device['status']['lights'] as $light => $state) {
echo "\n Light " .$light . ': ' . ($state['ison'] == true ? "on" : "off");
}
}
echo "\n WiFi: " . $this->Device['status']['wifi']['ssid'];
// add default performance data => ramusage and fsusage
echo ' |';
echo ' uptime='. $this->Device['uptime_ts'] . ';;;;';
echo ' rssi='. $this->Device['status']['wifi']['rssi'] . ';;;;';
if (isset($this->Device['status']['switch:0']['voltage'])) {
echo ' voltage0=' . $this->Device['status']['switch:0']['voltage'] . ';;;;';
}
elseif (isset($this->Device['status']['cover:0']['voltage'])) {
echo ' voltage0=' . $this->Device['status']['cover:0']['voltage'] . ';;;;';
}
if (isset($this->Device['status']['switch:1']['voltage'])) {
echo ' voltage1=' . $this->Device['status']['switch:1']['voltage'] . ';;;;';
}
elseif (isset($this->Device['status']['cover:1']['voltage'])) {
echo ' voltage1=' . $this->Device['status']['cover:1']['voltage'] . ';;;;';
}
if (isset($this->Device['status']['switch:2']['voltage'])) {
echo ' voltage2=' . $this->Device['status']['switch:2']['voltage'] . ';;;;';
}
if (isset($this->Device['status']['switch:3']['voltage'])) {
echo ' voltage3=' . $this->Device['status']['switch:3']['voltage'] . ';;;;';
}
echo ' ram='. $this->Device['ram']['ram_used'] . ';;;0;'. $this->Device['ram']['ram_total'];
echo ' ramusage='. $this->Device['ram']['usage'] . '%;' . $this->Device['check']['warning'] . ';' . $this->Device['check']['critical'] . ';0;100';
echo ' fs='. $this->Device['fs']['fs_used'] . ';;;0;'. $this->Device['fs']['fs_size'];
echo ' fsusage='. $this->Device['fs']['usage'] . '%;' . $this->Device['check']['warning'] . ';' . $this->Device['check']['critical'] . ';0;100';
if (isset($this->Device['status']['switch:0']['current'])) {
echo ' energy0=' . $this->Device['status']['switch:0']['current'] . ';;;;';
}
elseif (isset($this->Device['status']['cover:0']['current'])) {
echo ' energy0=' . $this->Device['status']['cover:0']['current'] . ';;;;';
}
if (isset($this->Device['status']['switch:1']['current'])) {
echo ' energy1=' . $this->Device['status']['switch:1']['current'] . ';;;;';
}
elseif (isset($this->Device['status']['cover:1']['current'])) {
echo ' energy1=' . $this->Device['status']['cover:1']['current'] . ';;;;';
}
if (isset($this->Device['status']['switch:2']['current'])) {
echo ' energy2=' . $this->Device['status']['switch:2']['current'] . ';;;;';
}
if (isset($this->Device['status']['switch:3']['current'])) {
echo ' energy3=' . $this->Device['status']['switch:3']['current'] . ';;;;';
}
/*
// if meters is set, then add the meters performance data to the output
if (is_array($this->Device['meters'])) {
foreach($this->Device['meters'] as $key => $value) {
echo ' power' . $key . '=' . $value['power'] . ';;;;';
}
}
// if emeters is set, then add the emeters performance data to the output
if (is_array($this->Device['emeters'])) {
foreach($this->Device['emeters'] as $key => $value) {
echo ' power' . $key . '=' . $value['power'] . ';;;;';
echo ' reactive' . $key . '=' . $value['reactive'] . ';;;;';
echo ' voltage' . $key . '=' . $value['voltage'] . ';;;;';
}
}
*/
// if temperature is set, then add the temperature performance data to the output
if (isset($this->Device['temperature']))
echo ' temperature=' . $this->Device['temperature'] . ';;;;';
echo "\n";
}
}
// seconds to time parses an amount of seconds to a formatted output of days, hours, minutes and seconds
function secondsToTime($seconds)
{
$dtF = new \DateTime('@0');
$dtT = new \DateTime("@$seconds");
return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
}
Alles anzeigen