add temps and fan reading to footer

add keys to sensors and event arrays
add function to get temps by name, sensor & event arrays
Fixed notification spam if ipmi communication fails
This commit is contained in:
Derek Macias 2016-01-28 01:27:22 -07:00
parent ce94394699
commit 6574d7e482
24 changed files with 676 additions and 166 deletions

View File

@ -0,0 +1,6 @@
Menu="NetworkServices"
Icon="ipmitool.png"
Title="IPMI tool"
Type="xmenu"
Tabs="true"
---

View File

@ -0,0 +1,28 @@
Menu="Buttons:2"
Link="nav-user"
---
<?PHP
/* Copyright 2015, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Plugin development contribution by gfjardim
*/
?>
<script>
function systemTemp() {
$.get('/plugins/ipmitool-plugin/include/ipmitool_temp.php',{unit:'<?=$display['unit']?>',dot:'<?=$display['number'][0]?>'},function(data) {
if (data) showFooter(data,'temps');
<?if ($display['refresh']>0 || ($display['refresh']<0 && $var['mdResync']==0)):?>
timers.systemTemp = setTimeout(systemTemp,<?=max(abs($display['refresh']),10000)?>);
<?endif;?>
});
}
systemTemp();
</script>

View File

@ -6,7 +6,7 @@ Title="Event Log"
<thead>
<tr>
<th class="sorter-false filter-false"> Status </th>
<th class="filter-false"> Event ID </th>
<th class="sorter-digit filter-false"> Event ID </th>
<th class="filter-time" data-placeholder="by time"> Time Stamp </th>
<th class="filter-name" data-placeholder="by name"> Sensor Name </th>
<th class="filter-desc" data-placeholder="Search..."> Description </th>

View File

@ -0,0 +1,113 @@
Menu="IPMI:2"
Title="Fan Control"
---
<?PHP
/* Copyright 2015, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Plugin development contribution by gfjardim
*/
?>
<?
$plugin = "ipmitool-plugin";
$cfg = parse_plugin_cfg($plugin);
$sName = "autofan";
$fName = "/usr/local/emhttp/plugins/$plugin/scripts/$sName";
function temp_val($val) {
global $display;
return $display['unit']=='C' ? $val : round(9/5*$val+32);
}
function scan_dir($dir, $type = "") {
$out = array();
foreach (array_slice(scandir($dir), 2) as $entry){
$sep = (preg_match("/\/$/", $dir)) ? "" : "/";
$out[] = $dir.$sep.$entry ;
}
return $out;
}
function list_pwm() {
$out = array();
exec("find /sys/devices -type f -iname 'pwm[0-9]' -exec dirname \"{}\" +|uniq", $chips);
foreach ($chips as $chip) {
$name = is_file("$chip/name") ? file_get_contents("$chip/name") : "";
foreach (preg_grep("/pwm\d+$/", scan_dir($chip)) as $pwm) {
$out[] = array('chip'=>$name, 'name'=>end(split('/',$pwm)), 'sensor'=>$pwm);
}
}
return $out;
}
?>
<script>
function detectFan() {
var pwm = $("select[name=controller] option:selected").val();
if (pwm) {
$("input[name=fan]").val('Please wait...');
$("#fan").val('Detecting ...');
$.get('/plugins/<?=$plugin;?>/include/SystemFan.php',{op:'detect', pwm:pwm},function(data) {
$("input[name=fan]").val(data);
$("#fan").val('Detect');
});
}
}
function detectFanLow() {
var pwm = $("select[name=controller] option:selected").val();
var fan = $("input[name=fan]").val();
if (pwm && fan) {
$("input[name=pwm]").val('Please wait...');
$("#pwm").val('Detecting ...');
$.get('/plugins/<?=$plugin;?>/include/SystemFan.php',{op:'pwm',pwm:pwm,fan:fan},function(data) {
$("input[name=pwm]").val(data);
$("#pwm").val('Detect');
});
}
}
$(function() {
showStatus('<?=$sName?>');
});
</script>
<form markdown="1" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#file" value="<?=$plugin?>/<?=$plugin?>.cfg">
<input type="hidden" name="#include" value="plugins/<?=$plugin?>/include/update.autofan.php">
<input type="hidden" name="#prefix" value="controller=c&fan=f&pwm=l&low=t&high=T&interval=m">
<span class="bitstream" style="float:right;margin-right:12px"><?=exec("$fName -V")?></span>
Fan control function:
: <select name="service" size="1">
<?=mk_option($cfg['service'], "0", "Disabled")?>
<?=mk_option($cfg['service'], "1", "Enabled")?>
</select>
PWM controller:
: <select name="controller" size="1">
<?=mk_option($cfg['controller'], "", "None")?>
<?foreach (list_pwm() as $pwm):?>
<?=mk_option($cfg['controller'], $pwm['sensor'], "{$pwm['chip']} - {$pwm['name']}")?>
<?endforeach;?>
</select>
PWM fan:
: <input type="text" name="fan" value="<?=$cfg['fan']?>" placeholder="Click DETECT"><input type="button" value="Detect" onclick="detectFan();" id="fan" style="margin-top:0">
Minimun PWM value:
: <input type="text" name="pwm" value="<?=$cfg['pwm']?>" placeholder="Click DETECT"><input type="button" value="Detect" onclick="detectFanLow();" id="pwm" style="margin-top:0">
Low temperature threshold (&deg;<?=$display['unit']?>):
: <input type="number" min="0" max="300" name="low" value="<?=temp_val($cfg['low'])?>" class="narrow">
High temperature threshold (&deg;<?=$display['unit']?>):
: <input type="number" min="0" max="300" name="high" value="<?=temp_val($cfg['high'])?>" class="narrow">
Refresh interval (minutes):
: <input type="text" name="interval" value="<?=$cfg['interval']?>" class="narrow">
<input type="submit" name="#default" value="Default">
: <input type="submit" name="#apply" value="Apply"><input type="button" value="Done" onclick="done()">
</form>

View File

@ -1,20 +1,10 @@
Menu="IPMItool:1"
Title="Sensors"
Icon="sensorspage.png"
---
<?php
$ipmitool_cfg = parse_plugin_cfg("ipmitool-plugin");
$ipmitool_password = "";
$ipmitool_options = "";
if($ipmitool_cfg['REMOTE'] == "enable") {
$ipmitool_options = " -I lanplus -H {$ipmitool_cfg['IPADDR']} -U {$ipmitool_cfg['USER']} -P ";
$ipmitool_password = $ipmitool_cfg['PASSWORD'];
}
$theme = $display["theme"];
?>
<link type="text/css" rel="stylesheet" href="/plugins/ipmitool-plugin/css/ipmitool-plugin.css">
<link type="text/css" rel="stylesheet" href="/plugins/tablesorter/css/tablesorter.css">
<link type="text/css" rel="stylesheet" href="/plugins/tablesorter/css/tablesorter-<?=$theme;?>.css">
<link type="text/css" rel="stylesheet" href="/plugins/tablesorter/css/tablesorter-<?=$display["theme"];?>.css">
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.switchbutton.css">
<div>
@ -44,8 +34,3 @@ $theme = $display["theme"];
<script type="text/javascript" src="/plugins/tablesorter/js/jquery.tablesorter.combined.min.js"></script>
<script type="text/javascript" src="/plugins/tablesorter/js/pager/jquery.tablesorter.pager.js"></script>
<script type="text/javascript" src="/webGui/javascript/jquery.switchbutton.js"></script>
<script type="text/javascript">
var Password = '<?=$ipmitool_password?>';
var Options = '<?=$ipmitool_options?>';
</script>

View File

@ -1,17 +1,9 @@
Icon="ipmitool.png"
Menu="NetworkServices"
Title="IPMI tool"
Menu="IPMI:1"
Title="Settings"
---
<?php
require_once '/usr/local/emhttp/plugins/ipmitool-plugin/include/ipmitool_helpers.php';
$sName = "ipmievd";
$ipmitool_cfg = parse_plugin_cfg("ipmitool-plugin");
$ipmitool_service = isset($ipmitool_cfg['SERVICE']) ? $ipmitool_cfg['SERVICE'] : "disable";
$ipmitool_remote = isset($ipmitool_cfg['REMOTE']) ? $ipmitool_cfg['REMOTE'] : "disable";
$ipmitool_lanip = trim(shell_exec("/usr/bin/ipmitool lan print | grep 'IP Address ' | sed -n -e 's/^.*: //p'"));
$ipmitool_ipaddr = preg_match('/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/', $ipmitool_cfg['IPADDR']) ? $ipmitool_cfg['IPADDR'] : $ipmitool_lanip;
$ipmitool_user = isset($ipmitool_cfg['USER']) ? $ipmitool_cfg['USER'] : "";
$ipmitool_password = isset($ipmitool_cfg['PASSWORD']) ? $ipmitool_cfg['PASSWORD'] : "";
$ipmitool_running = trim(shell_exec( "[ -f /proc/`cat /var/run/ipmievd.pid0 2> /dev/null`/exe ] && echo 'yes' || echo 'no' 2> /dev/null" ));
?>
<script type="text/javascript" src="/plugins/ipmitool-plugin/js/jquery.mask.js"></script>
@ -27,21 +19,36 @@ Enable Event Notifications:
</select>
Enable Remote Connection:
: <select id="REMOTE" class="ipmi_run" name="REMOTE" title="" size="1" onChange="checkREMOTE(this.form);">
: <select id="REMOTE" class="ipmitool-run" name="REMOTE" title="" size="1" onChange="checkREMOTE(this.form);">
<?=mk_option($ipmitool_remote, "disable", "No");?>
<?=mk_option($ipmitool_remote, "enable", "Yes");?>
</select>
<label class="ipmi_lan">IPMI IP Address:</label>
: <input id="IPADDR" type="text" class="ipmi_lan ipmi_address" name="IPADDR" maxlength="40" value="<?=$ipmitool_ipaddr;?>" title="IPMI IP address" placeholder="" >
<label class="ipmitool-lan">IPMI IP Address:</label>
: <input id="IPADDR" type="text" class="ipmitool-lan ipmitool-ipaddr" name="IPADDR" maxlength="40" value="<?=$ipmitool_ipaddr;?>" title="IPMI IP address" placeholder="" >
<label class="ipmi_lan">IPMI User Name:</label>
: <input id="USER" type="text" class="ipmi_lan" name="USER" maxlength="40" value="<?=$ipmitool_user;?>" title="username for remote access IPMI" placeholder="username for remote access" >
<label class="ipmitool-lan">IPMI User Name:</label>
: <input id="USER" type="text" class="ipmitool-lan" name="USER" maxlength="40" value="<?=$ipmitool_user;?>" title="username for remote access IPMI" placeholder="username for remote access" >
<label class="ipmi_lan">IPMI Password:</label>
: <input id="PASSWORD" type="password" class="ipmi_lan" name="PASSWORD" maxlength="40" value="<?=$ipmitool_password;?>" title="password for remote access IPMI" placeholder="password for remote access" >
<label class="ipmitool-lan">IPMI Password:</label>
: <input id="PASSWORD" type="password" class="ipmitool-lan" name="PASSWORD" maxlength="40" value="<?=$ipmitool_password;?>" title="password for remote access IPMI" placeholder="password for remote access" >
<input id="DEFAULT" class="ipmi_run" type="button" value="Default" onClick="resetDATA(this.form);">
Display CPU temperature:
: <select name="CPU_TEMP">
<?=ipmi_get_options($ipmitool_cpu, 'Temperature', $ipmitool_options);?>
</select>
Display Motherboard temperature:
: <select name="MB_TEMP">
<?=ipmi_get_options($ipmitool_mb, 'Temperature', $ipmitool_options);?>
</select>
Display Fan speed:
: <select name="IPMI_FAN">
<?=ipmi_get_options($ipmitool_fan, 'Fan', $ipmitool_options);?>
</select>
<input id="DEFAULT" class="ipmitool-run" type="button" value="Default" onClick="resetDATA(this.form);">
: <input id="btnApply" type="submit" value="Apply" onClick="verifyDATA(this.form)"><input type="button" value="Done" onClick="done()">
</form>
@ -52,7 +59,7 @@ $(function(){
checkREMOTE(document.ipmitool_settings);
decData(document.ipmitool_settings);
//ip address input mask
$('.ipmi_address').mask('0ZZ.0ZZ.0ZZ.0ZZ', {translation: {'Z': {pattern: /[0-9]/, optional: true}}});
$('.ipmitool-ipaddr').mask('0ZZ.0ZZ.0ZZ.0ZZ', {translation: {'Z': {pattern: /[0-9]/, optional: true}}});
});
function resetDATA(form) {
@ -66,10 +73,10 @@ function resetDATA(form) {
function checkRUNNING(form) {
if ("<?=$ipmitool_running;?>" == "yes")
{
$(".ipmi_run").prop("disabled", true);
$(".ipmitool-run").prop("disabled", true);
form.btnApply.disabled = "disabled";
}else{
$(".ipmi_run").prop("disabled", false);
$(".ipmitool-run").prop("disabled", false);
$("#btnApply").prop("disabled", false);
}
if (form.SERVICE.value == "enable")
@ -85,10 +92,10 @@ function decData(form) {
function checkREMOTE(form) {
if (form.REMOTE.selectedIndex < 1 )
$(".ipmi_lan").hide();
$(".ipmitool-lan").hide();
else
$(".ipmi_lan").show();
$(".ipmi_lan").prop("disabled", (form.SERVICE.value == "enable"));
$(".ipmitool-lan").show();
$(".ipmitool-lan").prop("disabled", (form.SERVICE.value == "enable"));
}
function verifyDATA(form) {
@ -97,5 +104,4 @@ function verifyDATA(form) {
form.USER.value = form.USER.value.replace(/ /g,"_");
form.PASSWORD.value = btoa(form.PASSWORD.value);
}
</script>

View File

@ -1,5 +1,5 @@
/* header */
table.tablesorter {
table.tablesorter{
margin-top:-21px;
}
.tablesorter td.reading{

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -1,4 +0,0 @@
<?php
$cmd = "/usr/bin/ipmitool sel ".$_POST["options"];
exec($cmd);
?>

View File

@ -0,0 +1,248 @@
#!/usr/bin/php
<?php
##############################
###### DEAMON SECTION ######
##############################
$cron = FALSE;
$DEBUG = FALSE;
# DO NOT TOUCH
set_time_limit(0);
$program_name = pathinfo(__FILE__, PATHINFO_FILENAME);
$lockfile = "/var/run/${program_name}.pid";
$service_file = __FILE__;
openlog($program_name, LOG_PID | LOG_PERROR, LOG_LOCAL0);
$usage = <<<EOT
Usage: $program_name = start the daemon
$program_name -q = quit the program if it is running
EOT;
function debug($m){
global $program_name, $DEBUG;
if($DEBUG){
$STDERR = fopen('php://stderr', 'w+');
fwrite($STDERR, $m."\n");
fclose($STDERR);
}
}
$background_args = "";
if(isset($argv)){
for ($i=0; $i <= count($argv); $i++) {
switch ($argv[$i]) {
case '-q':
$quit = TRUE;
break;
case '--background':
$background = TRUE;
break;
case '-c':
$cron = $argv[$i+1];
$background_args .= " ${argv[$i]} ${argv[$i+1]}";
break;
case '-d':
$DEBUG = TRUE;
$background_args .= " ${argv[$i]}";
break;
case '-h':
case '--help':
echo $usage;
exit(0);
# Especific switches:
}
}
}
# Deal with cron
if (isset($cron) && is_numeric($cron) && ! isset($quit)){
exec("crontab -l 2>/dev/null", $crontab);
$crontab = array_unique($crontab);
if (! isset($quit)){
$entry = sprintf("*/%s * * * * ${service_file}${background_args} 1> /dev/null 2>&1", $cron);
if (! preg_grep("#${service_file}#", $crontab)){
$crontab[] = $entry;
debug("\nCRONTAB\n".implode("\n", $crontab)."\n");
file_put_contents("/tmp/${program_name}.cron", implode(PHP_EOL, $crontab));
shell_exec("crontab /tmp/${program_name}.cron");
unlink("/tmp/$program_name.cron");
}
}
unset($crontab);
} else if (isset($quit)){
exec("crontab -l 2>/dev/null", $crontab);
$crontab = array_unique($crontab);
if (preg_grep("#${service_file}#", $crontab)){
$crontab = preg_grep("#${service_file}#", $crontab, PREG_GREP_INVERT);
debug("\nCRONTAB\n".implode("\n", $crontab)."\n");
file_put_contents("/tmp/${program_name}.cron", implode(PHP_EOL, $crontab));
shell_exec("crontab /tmp/${program_name}.cron");
unlink("/tmp/$program_name.cron");
};
unset($crontab);
}
if (is_file($lockfile)){
$lock_pid = file($lockfile, FILE_IGNORE_NEW_LINES)[0];
$pid_running=preg_replace("/\s+/", "", shell_exec("ps -p ${lock_pid}| grep ${lock_pid}"));
if (! $pid_running){
if (! isset($quit)){
file_put_contents($lockfile, getmypid());
} else {
echo "${lock_pid} is not currently running";
unlink($lockfile);
exit(0);
}
} else {
if (isset($quit)){
syslog(LOG_INFO, "killing daemon with PID [${lock_pid}]");
exec("kill $lock_pid");
unlink($lockfile);
if (function_exists('at_exit')) at_exit();
exit(0);
} else {
echo "$program_name is already running [${lock_pid}]".PHP_EOL;
exit(0);
}
}
} else {
if(isset($quit)){
echo "$program_name not currently running".PHP_EOL;
exit(0);
} else {
file_put_contents($lockfile, getmypid());
}
}
if(!isset($background)){
exec("php $service_file --background $background_args 1>/dev/null ".($DEBUG ? "":"2>&1 ")."&");
exit(0);
} else {
syslog(LOG_INFO, "process started. To terminate it, type: $program_name -q");
}
##############################
##### PROGRAM SECTION ######
##############################
$plugin = "dynamix.system.autofan";
$config_file = "/boot/config/plugins/${plugin}/fan.conf";
function scan_dir($dir, $type = ""){
$out = array();
foreach (array_slice(scandir($dir), 2) as $entry){
$sep = (preg_match("/\/$/", $dir)) ? "" : "/";
$out[] = $dir.$sep.$entry ;
}
return $out;
}
function get_highest_temp($hdds){
$highest_temp="0";
foreach ($hdds as $hdd) {
if (shell_exec("hdparm -C ${hdd} 2>/dev/null| grep -c standby") == 0){
$temp = preg_replace("/\s+/", "", shell_exec("smartctl -A ${hdd} 2>/dev/null| grep -m 1 -i Temperature_Celsius | awk '{print $10}'"));
$highest_temp = ($temp > $highest_temp) ? $temp : $highest_temp;
}
}
debug("Highest temp is ${highest_temp}ºC");
return $highest_temp;
}
function get_all_hdds(){
$hdds = array();
$flash = preg_replace("/\d$/", "", realpath("/dev/disk/by-label/UNRAID"));
foreach (scan_dir("/dev/") as $dev) {
if(preg_match("/[sh]d[a-z]+$/", $dev) && $dev != $flash) {
$hdds[] = $dev;
}
}
return $hdds;
}
$hdds = get_all_hdds();
while(TRUE){ while(TRUE){
#### DO YOUR STUFF HERE ####
# Load config file or die
if(is_file($config_file)){
$params = (is_file($config_file)) ? parse_ini_file($config_file) : array();
extract($params, EXTR_OVERWRITE);
} else {
unlink($lockfile);
exit(1);
}
# Wait probes to become ready
if (! is_file($PWM_CONTROLLER) || ! is_file($PWM_FAN)){
sleep(15);
continue;
}
# Set PWM_HIGH and PWM_OFF
$PWM_HIGH = 255;
$PWM_OFF = $PWM_LOW-5;
# Disable fan mininum RPM
$FAN_RPM_MIN = file(split("_", $PWM_FAN)[0]."_min", FILE_IGNORE_NEW_LINES)[0];
$D_FAN_RPM_MIN = ($FAN_RPM_MIN > 0) ? $FAN_RPM_MIN : FALSE;
# Enable speed change on fan
$PWM_MODE=file("${PWM_CONTROLLER}_enable", FILE_IGNORE_NEW_LINES)[0];
if($PWM_MODE != 1){
$DEFAULT_PWM_MODE = $PWM_MODE;
file_put_contents("${PWM_CONTROLLER}_enable", 1);
}
# Calculate size of increments.
$TEMP_INCREMENTS = $TEMP_HIGH-$TEMP_LOW;
$PWM_INCREMENTS = round(($PWM_HIGH-$PWM_LOW)/$TEMP_INCREMENTS);
# Get current fan rpm and pwm
$CURRENT_PWM = preg_replace("/\s*/", "", file_get_contents($PWM_CONTROLLER));
$CURRENT_RPM = preg_replace("/\s*/", "", file_get_contents($PWM_FAN));
# Get current fan PWM percentage
$CURRENT_PERCENT_PWM = round(($CURRENT_PWM*100)/$PWM_HIGH);
$CURRENT_OUTPUT = "${CURRENT_PWM} (${CURRENT_PERCENT_PWM}% @ ${CURRENT_RPM}rpm)";
# Calculate a new scenario
# Get highest drive temperature
$HIGHEST_TEMP = get_highest_temp($hdds);
if ($HIGHEST_TEMP <= $TEMP_LOW){
$NEW_PWM = $PWM_OFF;
$NEW_PERCENT_PWM = 0;
} else if ($HIGHEST_TEMP >= $TEMP_HIGH){
$NEW_PWM = $PWM_HIGH;
$NEW_PERCENT_PWM = 100;
} else {
$NEW_PWM = (($HIGHEST_TEMP-$TEMP_LOW)*$PWM_INCREMENTS)+$PWM_LOW;
$NEW_PERCENT_PWM = round(($NEW_PWM*100)/$PWM_HIGH);
}
# Change the fan speed as needed
if ($CURRENT_PWM != $NEW_PWM){
file_put_contents($PWM_CONTROLLER, $NEW_PWM);
sleep(5);
$NEW_RPM = preg_replace("/\s*/", "", file_get_contents($PWM_FAN));
$NEW_PERCENT_PWM = round(($NEW_PWM*100)/$PWM_HIGH);
$NEW_OUTPUT = "${NEW_PWM} (${NEW_PERCENT_PWM}% @ ${NEW_RPM}rpm)";
syslog(LOG_INFO, "highest disk temp is ${HIGHEST_TEMP}ºC, adjusting fan PWM from: $CURRENT_OUTPUT to: $NEW_OUTPUT");
}
# PRINT VARIABLES DEBUG
$defined_vars = get_defined_vars();
foreach (array("_GET","_POST","_COOKIE","_FILES","argv","argc","_SERVER") as $i) {unset($defined_vars[$i]);}
debug("\nDECLARED VARIABLES:\n".print_r($defined_vars, true));
unset($defined_vars);
$time1 = time();
$MD5 = shell_exec("md5sum $config_file|awk '{print $1}'");
$MD5 = md5_file($config_file);
for ($i=0; $i < $INTERVAL*6 ; $i++) {
sleep(10);
if (md5_file($config_file) != $MD5){syslog(LOG_INFO, "config file updated, reloading."); $i=10000;}
}
debug("Sleeped ".(time()-$time1)." seconds.");
###### END OF SECTION ######
};};?>

View File

@ -0,0 +1,5 @@
<?php
require_once '/usr/local/emhttp/plugins/ipmitool-plugin/include/ipmitool_helpers.php';
$cmd = "/usr/bin/ipmitool sel ".$_GET["options"].$ipmitool_options;
exec($cmd);
?>

View File

@ -1,10 +0,0 @@
<?php
$command = "/usr/bin/ipmitool ".$_POST["options"]." 2>/dev/null";
exec($command, $output);
$array = array();
for ($i = 0; $i < sizeof($output); $i++) {
$value = explode(",", $output[$i]);
$array[] = $value;
}
echo json_encode($array);
?>

View File

@ -0,0 +1,4 @@
<?php
require_once '/usr/local/emhttp/plugins/ipmitool-plugin/include/ipmitool_helpers.php';
echo json_encode(ipmi_events($ipmitool_options));
?>

View File

@ -0,0 +1,98 @@
<?php
/* ipmi tool variables*/
$plugin = 'ipmitool-plugin';
$ipmitool_cfg = parse_ini_file("/boot/config/plugins/$plugin/$plugin.cfg");
$ipmitool_service = isset($ipmitool_cfg['SERVICE']) ? $ipmitool_cfg['SERVICE'] : "disable";
$ipmitool_remote = isset($ipmitool_cfg['REMOTE']) ? $ipmitool_cfg['REMOTE'] : "disable";
$ipmitool_running = trim(shell_exec( "[ -f /proc/`cat /var/run/ipmievd.pid0 2> /dev/null`/exe ] && echo 'yes' || echo 'no' 2> /dev/null" ));
// get ip address of local ipmi
$ipmitool_lanip = trim(shell_exec("/usr/bin/ipmitool lan print | grep 'IP Address ' | sed -n -e 's/^.*: //p'"));
// use save ip address or use local ipmi address
$ipmitool_ipaddr = preg_match('/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/', $ipmitool_cfg['IPADDR']) ? $ipmitool_cfg['IPADDR'] : $ipmitool_lanip;
$ipmitool_cpu = isset($ipmitool_cfg['CPU_TEMP']) ? $ipmitool_cfg['CPU_TEMP'] : ""; // cpu temp display name
$ipmitool_mb = isset($ipmitool_cfg['MB_TEMP']) ? $ipmitool_cfg['MB_TEMP'] : ""; // mb temp display name
$ipmitool_fan = isset($ipmitool_cfg['IPMI_FAN']) ? $ipmitool_cfg['IPMI_FAN'] : ""; // fan speed display name
$ipmitool_user = isset($ipmitool_cfg['USER']) ? $ipmitool_cfg['USER'] : ""; // user for remote access
$ipmitool_password = isset($ipmitool_cfg['PASSWORD']) ? $ipmitool_cfg['PASSWORD'] : ""; // password for remote access
// options for remote access or not
$ipmitool_options = ($remote == "enable") ? " -I lanplus -H '$ipmitool_ipaddr' -U '$ipmitool_user' -P '".
base64_decode($ipmitool_password)."' " : "";
/* get an array of all sensors and their values */
function ipmi_sensors($options) {
$cmd = "/usr/bin/ipmitool -vc sdr $options 2>/dev/null";
exec($cmd, $output);
// key names for ipmitool sensor output
$sensor_keys = array('Name','Reading','Units','Status','Entity','Location','Type','Nominal',
'NormalMin','NormalMax','UpperNonRec','UpperCritical','UpperNonCritical','LowerNonRec',
'LowerCritical','LowerNonCritical','MinRange','MaxRange' );
$sensors_array = [];
foreach($output as $sensor){
// add sensor keys as keys to ipmitool output
$sensor_array = array_combine($sensor_keys, array_slice(explode(",", $sensor),0,18,true));
// add sensor to array of sensors
$sensors_array[] = $sensor_array;
}
return $sensors_array;
}
/* get array of events and their values */
function ipmi_events($options){
$cmd = "/usr/bin/ipmitool -c sel elist $options 2>/dev/null";
exec($cmd, $output);
// key names for ipmitool event output
$event_keys = array('Event','Datestamp','Timestamp','Sensor','Description','Status');
$events_array = [];
foreach($output as $event){
// add event keys as keys to ipmitool output cut to match
$event_array = array_combine($event_keys, array_slice(explode(",", $event),0,6,true));
$events_array[] = $event_array;
}
return $events_array;
}
/* get select options for a given sensor type */
function ipmi_get_options($selected, $type, $options){
$sensors_array = ipmi_sensors($options);
$options = "<option value='false'>No</option>\n";
foreach($sensors_array as $sensor){
if ($sensor["Type"] == $type && $sensor["Status"] != "ns"){
$name = $sensor["Name"];
$options .= "<option value='$name'";
// set saved option as selected
if ($selected == $name)
$options .= " selected";
$options .= ">$name</option>\n";
}
}
return $options;
}
/* get reading for a given sensor by name */
function ipmi_get_reading($sensor, $options) {
$sensors_array = ipmi_sensors($options);
foreach($sensors_array as $sensor_array){
if ($sensor_array["Name"] == $sensor) {
return $sensor_array["Reading"];
}
}
}
?>

View File

@ -0,0 +1,4 @@
<?php
require_once '/usr/local/emhttp/plugins/ipmitool-plugin/include/ipmitool_helpers.php';
echo json_encode(ipmi_sensors($ipmitool_options));
?>

View File

@ -0,0 +1,27 @@
<?
require_once '/usr/local/emhttp/plugins/ipmitool-plugin/include/ipmitool_helpers.php';
function my_temp($reading, $unit, $dot) {
return ($reading>0 ? ($unit=='F' ? round(9/5*$reading+32) : str_replace('.',$dot,$reading)) : '##')."&thinsp;$unit";
}
$sensors_array = [];
if ($ipmitool_cpu){
$ipmitool_cpu_temp = ipmi_get_reading($ipmitool_cpu, $ipmitool_options);
if ($ipmitool_cpu_temp)
$sensors_array[] = "<img src='/plugins/$plugin/icons/cpu.png' title='$ipmitool_cpu' class='icon'>".my_temp($ipmitool_cpu_temp, $_GET['unit'], $_GET['dot']);
}
if ($ipmitool_mb){
$ipmitool_mb_temp = ipmi_get_reading($ipmitool_mb, $ipmitool_options);
if ($ipmitool_mb_temp)
$sensors_array[] = "<img src='/plugins/$plugin/icons/mb.png' title='$ipmitool_mb' class='icon'>".my_temp($ipmitool_mb_temp, $_GET['unit'], $_GET['dot']);
}
if ($ipmitool_fan){
$ipmitool_fan_rpm = ipmi_get_reading($ipmitool_fan, $ipmitool_options);
if ($ipmitool_fan_rpm)
$sensors_array[] = "<img src='/plugins/$plugin/icons/fan.png' title='$ipmitool_fan' class='icon'>".$ipmitool_fan_rpm."&thinsp;rpm";
}
if ($sensors_array)
echo "<span id='temps' style='margin-right:16px'>".implode('&nbsp;', $sensors_array)."</span>";
?>

View File

@ -1,4 +1,40 @@
$(function(){
$('#tblSensor').tablesorter();
$('#tblEvent').tablesorter({
sortList: [[0,0]],
widgets: ['saveSort', 'filter', 'stickyHeaders'],
widgetOptions: {
stickyHeaders_filteredToTop: true,
filter_hideEmpty : true,
filter_liveSearch : true,
filter_saveFilters : true,
filter_reset : '.reset',
filter_functions: {
'.filter-name' : true,
'.filter-time' : {
"3 days" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 259200000); }, //3*24*60*60 3 days
"1 week" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 604800000); }, //7*24*60*60 1 week
"2 weeks" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 1209600000); }, //14*24*60*60 2 weeks
"1 month" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 2592000000); }, //30*24*60*60 1 month
"6 months" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 15724800000); }, //26*7*24*60*60 6 months
"1 year" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 31449600000); } //52*7*24*60*60 1 year
}
}
}
})
.tablesorterPager({
container: $(".pager"),
fixedHeight: false,
size: 10
});
sensorArray(false);
eventArray();
@ -27,38 +63,49 @@ function sensorRefresh() {
//load ipmi sensor table
function sensorArray(Refresh){
$.ajax({
type: "POST",
dataType: "json",
url: "/plugins/ipmitool-plugin/include/ipmitool_array.php",
data : {options: "-vc sdr" + Options + atob(Password)},
success: function(data) {
$.getJSON("/plugins/ipmitool-plugin/include/ipmitool_sensors.php",
{ }, function(data) {
$.each(data, function (i, val) {
if (data[i][3] != "ns") {
var Reading = data[i][1];
var LowerNonRec = data[i][13];
var LowerCritical = data[i][14];
var LowerNonCrit = data[i][15];
var UpperNonCrit = data[i][12];
var UpperCritical = data[i][11];
var UpperNonRec = data[i][10];
if (data[i].Status != "ns") {
var Reading = parseFloat(data[i].Reading);
//if (data[i].Name == "+5VSB")
//Reading = 6.2;
var LowerNonRec = parseFloat(data[i].LowerNonRec);
var LowerCritical = parseFloat(data[i].LowerCritical);
var LowerNonCritical = parseFloat(data[i].LowerNonCritical);
var UpperNonCritical = parseFloat(data[i].UpperNonCritical);
var UpperCritical = parseFloat(data[i].UpperCritical);
var UpperNonRec = parseFloat(data[i].UpperNonRec);
var Color = "green";
var Name = data[i][0].replace('+', 'plus_').replace('-', 'minus_').replace(' ', '_').replace('.', '_');
if (data[i][6]=="Voltage"){
if (parseFloat(Reading) < parseFloat(LowerNonRec) || parseFloat(Reading) > parseFloat(UpperNonRec))
// replace illegal characters
var Name = data[i].Name.replace('+', 'plus_').replace('-', 'minus_').replace(' ', '_').replace('.', '_');
if (data[i].Type=="Voltage"){
// if voltage is less than lower non-recoverable
// or voltage is greater than upper non-recoverable
if (Reading < LowerNonRec || Reading > UpperNonRec)
Color = "red";
if (parseFloat(Reading) > parseFloat(LowerNonRec) && parseFloat(Reading) < parseFloat(UpperNonRec))
// if voltage is between lower non recoverable and
if (Reading > LowerNonRec && Reading < UpperNonRec)
Color = "red";
if (parseFloat(Reading) > parseFloat(LowerCritical) && parseFloat(Reading) < parseFloat(UpperCritical))
if (Reading > LowerCritical && Reading < UpperCritical)
Color = "orange";
if (parseFloat(Reading) > parseFloat(LowerNonCrit) && parseFloat(Reading) < parseFloat(UpperNonCrit))
if (Reading > LowerNonCritical && Reading < UpperNonCritical)
Color = "green";
} else if (data[i][6]=="Fan"){
if (parseInt(Reading) < parseInt(LowerNonCrit))
} else if (data[i].Type=="Fan"){
// if Fan RPMs are less than lower non-critical
if (Reading < LowerNonCritical || Reading < LowerCritical || Reading < LowerNonRec)
Color = "red";
} else if (data[i][6]=="Temperature"){
if (parseInt(Reading) > parseInt(UpperNonCrit))
} else if (data[i].Type=="Temperature"){
// if Temperature is greater than upper non-critical
if (Reading > UpperNonCritical || Reading > UpperCritical || Reading > UpperNonRec)
Color = "red";
}
@ -67,53 +114,42 @@ function sensorArray(Refresh){
} else {
$("#tblSensor tbody")
.append("<tr id='"+Name+"'>"+
"<td title='"+data[i][3]+"'><img src='/plugins/ipmitool-plugin/images/green-on.png'/></td>"+ //status
"<td>"+data[i][0]+"</td>"+ //sensor name
"<td class='advanced'>"+ LowerNonRec +"</td>"+
"<td class='advanced'>"+ LowerCritical +"</td>"+
"<td class='advanced'>"+ LowerNonCrit +"</td>"+
"<td title='"+data[i].Status+"'><img src='/plugins/ipmitool-plugin/images/green-on.png'/></td>"+ //status
"<td>"+data[i].Name+"</td>"+ //sensor name
"<td class='advanced'>"+ data[i].LowerNonRec +"</td>"+
"<td class='advanced'>"+ data[i].LowerCritical +"</td>"+
"<td class='advanced'>"+ data[i].LowerNonCritical +"</td>"+
"<td class='reading "+ Color +"-text'>"+ Reading +"</td>"+ //sensor reading
"<td>"+data[i][2]+"</td>"+ //sensor units
"<td class='advanced'>"+ UpperNonCrit +"</td>"+
"<td class='advanced'>"+ UpperCritical +"</td>"+
"<td class='advanced'>"+ UpperNonRec +"</td>"+
"<td>"+data[i].Units+"</td>"+ //sensor units
"<td class='advanced'>"+ data[i].UpperNonCritical +"</td>"+
"<td class='advanced'>"+ data[i].UpperCritical +"</td>"+
"<td class='advanced'>"+ data[i].UpperNonRec +"</td>"+
"</tr>");
}
}
});
$("#tblSensor").trigger("update"); //update sensor table
$('#tblSensor').trigger('update'); //update sensor table
if ($.cookie('ipmitool_sensor_mode') == 'advanced')
$('.advanced').show();
else
$('.advanced').hide();
$('#tblSensor').tablesorter();
},
error : function() {},
cache: false
});
});
};
//load ipmi event table
function eventArray(){
$("#tblEvent tbody").empty();
$.ajax({
type: "POST",
dataType: "json",
url: "/plugins/ipmitool-plugin/include/ipmitool_array.php",
data : {options: "-c sel elist" + Options + atob(Password)},
success: function(data) {
$.getJSON("/plugins/ipmitool-plugin/include/ipmitool_events.php",{ }, function(data) {
$.each(data, function (i, val) {
var Status = (data[i][5] == 'Asserted') ? 'red' : 'green';
$("#tblEvent tbody")
.append("<tr id='"+data[i][0]+"'>"+
"<td title='"+data[i][5]+"'><img src='/plugins/ipmitool-plugin/images/" + Status + "-on.png'/></td>"+ //status
"<td>" + data[i][0] + "</td>"+ //event id
"<td>" + data[i][1] + " "+data[i][2]+"</td>"+ //time stamp
"<td>" + data[i][3] + "</td>"+ //sensor name
"<td>" + data[i][4] +"</td>"+ //subject
var Status = (data[i].Status == 'Asserted') ? 'red' : 'green';
$('#tblEvent tbody')
.append("<tr id='"+data[i].Event+"'>"+
"<td title='"+data[i].Status+"'><img src='/plugins/ipmitool-plugin/images/" + Status + "-on.png'/></td>"+ //status
"<td>" + data[i].Event + "</td>"+ //event id
"<td>" + data[i].Datestamp + " "+data[i].Timestamp+"</td>"+ //time stamp
"<td>" + data[i].Sensor + "</td>"+ //sensor name
"<td>" + data[i].Description +"</td>"+ //Description
"<td><a class='delete'><i class='fa fa-trash' title='delete'></i></a>"+ //delete icon
"</tr>");
@ -123,52 +159,14 @@ function eventArray(){
});
//var lastSearch = $("#tblEvent")[0].config.lastSearch;
$("#tblEvent").trigger("update"); //update table for tablesorter
$('#tblEvent').tablesorter({
sortList: [[0,1]],
widgets: ['saveSort', 'filter', 'stickyHeaders'],
widgetOptions: {
stickyHeaders_filteredToTop: true,
filter_hideEmpty : true,
filter_liveSearch : true,
filter_saveFilters : true,
filter_reset : 'a.reset',
filter_functions: {
'.filter-time' : {
"3 days" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 259200000); }, //3*24*60*60 3 days
"1 week" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 604800000); }, //7*24*60*60 1 week
"2 weeks" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 1209600000); }, //14*24*60*60 2 weeks
"1 month" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 2592000000); }, //30*24*60*60 1 month
"6 months" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 15724800000); }, //26*7*24*60*60 6 months
"1 year" : function(e, n, f, i, $r, c, data) {
return ($.now() - n <= 31449600000); } //52*7*24*60*60 1 year
},
'.filter-name' : true
}
}
})
.tablesorterPager({
container: $(".pager"),
fixedHeight: false,
size: 10
});
//$("#tblEvent").trigger("search", [lastSearch]);
$("#allEvents").click(function() {
Delete('all');
});
},
complete: function () {
},
error : function() {}
});
});
};
function Delete(Row) {
@ -176,17 +174,12 @@ function Delete(Row) {
if (Confirm){
var Method = (Row == "all") ? "clear " : "delete ";
var EventId = (Row == "all") ? "" : Row;
$.ajax({
type : "POST",
url : "/plugins/ipmitool-plugin/include/delete_event.php",
data : {options: Method + EventId + Options + atob(Password)},
success: function(data) {
$.getJSON("/plugins/ipmitool-plugin/include/ipmi_event_delete.php", {options: Method + EventId}, function(data) {
if (Row == "all")
$("#tblEvent tbody").empty(); // empty table
else
$('#'+Row).remove(); //remove table row
},
error : function() { }
});
}
);
}
};

View File

@ -6,8 +6,15 @@ exec /usr/bin/tail -n 0 -F /var/log/syslog | \
while read LINE;
do
# do not notify on ipmievd start
[[ "$LINE" == *"Waiting for events"* ]] && continue
# do not notify on remote communication failure
[[ "$LINE" == *"Get SEL Info command failed"* ]] && continue
# only notify when ipmievd: is in the system log
[[ "$LINE" != *$prog* ]] && continue
sleep 1 |
exec /usr/local/emhttp/webGui/scripts/notify -s "Notice [$HOSTNAME]" -d "$(echo "$LINE" | sed -e 's/.*ipmievd: //')" -i "warning" && continue 2
exec /usr/local/emhttp/webGui/scripts/notify -s "Notice [$HOSTNAME]" -d "$(echo "$LINE" | sed -e 's/.*$prog//')" -i "warning" && continue 2
done