Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
desertwitch authored Jul 26, 2023
2 parents 6c4d6da + 0d1c4bf commit 72f7545
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 30 deletions.
6 changes: 5 additions & 1 deletion source/nut/usr/local/emhttp/plugins/nut/NUTsettings.page
Original file line number Diff line number Diff line change
Expand Up @@ -377,11 +377,15 @@ require_once '/usr/local/emhttp/plugins/nut/include/nut_config.php'; ?>
<dd>
<select class="" name="FOOTER_STYLE" size="1">
<?=mk_option($nut_footer_style, '0', 'Default');?>
<?=mk_option($nut_footer_style, '1', 'Small');?>
<?=mk_option($nut_footer_style, '1', 'Minimal');?>
</select>
</dd>
</dl>

<blockquote class="inline_help">
<p>Tooltip disabled on Minimal style.</p>
</blockquote>

<dl>
<dt>Display Page Refresh:</dt>
<dd>
Expand Down
24 changes: 24 additions & 0 deletions source/nut/usr/local/emhttp/plugins/nut/include/nut_config.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,28 @@
$nut_interval = isset($nut_cfg['INTERVAL']) ? intval($nut_cfg['INTERVAL']) : 15 ;
$nut_runtime = isset($nut_cfg['RUNTIME']) ? htmlspecialchars($nut_cfg ['RUNTIME']) : 'battery.runtime';
$nut_running = (intval(trim(shell_exec( "[ -f /proc/`cat /var/run/nut/upsmon.pid 2> /dev/null`/exe ] && echo 1 || echo 0 2> /dev/null" ))) === 1 );

# debug constant to overwrite ups.status
// define('NUT_STATUS_DEBUG', 'OB DISCHRG BYPASS CAL');
$nut_states = [
'OL' => ['severity' => 0, 'msg' => 'On line'],
'OB' => ['severity' => 0, 'msg' => 'On battery'],
'LB' => ['severity' => 1, 'msg' => 'Low battery'],
'HB' => ['severity' => 0, 'msg' => 'High battery'],
'RB' => ['severity' => 2, 'msg' => 'The battery needs to be replaced'],
'CHRG' => ['severity' => 0, 'msg' => 'The battery is charging'],
'DISCHRG' => ['severity' => 1, 'msg' => 'The battery is discharging'],
'BYPASS' => ['severity' => 1, 'msg' => 'UPS bypass circuit is active (no battery protection is available)'],
'CAL' => ['severity' => 0, 'msg' => 'UPS is currently performing runtime calibration (on battery)'],
'OFF' => ['severity' => 1, 'msg' => 'UPS is offline and is not supplying power to the load'],
'OVER' => ['severity' => 2, 'msg' => 'UPS is overloaded'],
'TRIM' => ['severity' => 1, 'msg' => 'UPS is trimming incoming voltage (called "buck" in some hardware)'],
'BOOST' => ['severity' => 1, 'msg' => 'UPS is boosting incoming voltage'],
'FSD' => ['severity' => 1, 'msg' => 'Forced Shutdown'],
];
$nut_msgSeverity = [
0 => ['label' => 'info', 'css_class' => 'green-text'],
1 => ['label' => 'warning', 'css_class' => 'orange-text'],
2 => ['label' => 'error', 'css_class' => 'red-text'],
];
?>
65 changes: 51 additions & 14 deletions source/nut/usr/local/emhttp/plugins/nut/include/nut_footer.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function format_time($seconds) {
$status = [];
$ups_status = get_ups($nut_name, $nut_ip);
if (count($ups_status)) {
$online = ( array_key_exists("ups.status", $ups_status) && stripos($ups_status["ups.status"],'OL')!==false );
$online = ( array_key_exists("ups.status", $ups_status) ? nut_ups_status([$ups_status["ups.status"]], true) : false );
$battery = (array_key_exists("battery.charge",$ups_status)) ? intval(strtok($ups_status['battery.charge'],' ')) : false;
$load = (array_key_exists("ups.load", $ups_status)) ? intval(strtok($ups_status['ups.load'],' ')) : 0;
$realPower = (array_key_exists("ups.realpower", $ups_status)) ? intval(strtok($ups_status['ups.realpower'],' ')) : NULL;
Expand All @@ -77,18 +77,41 @@ function format_time($seconds) {
$status[3] = "<span id='nut_alarm' class='tooltip-nut $orange' data=\"$alarms\"><i class='fa fa-bell faa-ring animated'></i></span>";
}

if ($battery !== false) {
$battery_runtime = array_key_exists($nut_runtime, $ups_status) ? format_time($ups_status[$nut_runtime]) : "n/a";
if ($online && $battery < 100) $icon = "<span id='".($config['FOOTER_STYLE'] == 1 ? "copyright" : "nut_battery")."' class='tooltip-nut ".($config['FOOTER_STYLE'] == 1 ? "$black" : "$green")."' data='[{$nut_name}] Online - Battery is charging'><i class='fa fa-battery-charging'></i>&thinsp;{$battery}&thinsp;%</span>";
else if ($online && $battery == 100) $icon = "<span id='".($config['FOOTER_STYLE'] == 1 ? "copyright" : "nut_battery")."' class='tooltip-nut ".($config['FOOTER_STYLE'] == 1 ? "$black" : "$green")."' data='[{$nut_name}] Online - Battery is full'><i class='fa fa-battery-full'></i>&thinsp;{$battery}&thinsp;%</span>";
else if (!$online) $icon = "<span id='".($config['FOOTER_STYLE'] == 1 ? "copyright" : "nut_battery")."' class='tooltip-nut $red' data='[{$nut_name}] Offline - Battery is discharging - Est. $battery_runtime left'><i class='fa fa-battery-discharging'></i>&thinsp;{$battery}&thinsp;%</span>";
else $icon = "<span id='".($config['FOOTER_STYLE'] == 1 ? "copyright" : "nut_battery")."' class='tooltip-nut ".($config['FOOTER_STYLE'] == 1 ? "$black" : "$green")."' data='[{$nut_name}] Battery status unknown'><i class='fa fa-battery-discharging'></i>n/a</span>";

$status[0] = $icon;
$battery_runtime = array_key_exists($nut_runtime, $ups_status) ? format_time($ups_status[$nut_runtime]) : "n/a";
$css_class = $online['severity'] > 0 ? $nut_msgSeverity[$online['severity']]['css_class'] : ($config['FOOTER_STYLE'] == 1 ? $black : $green);
$fa_icon = '';
$statusTooltipData = '';
$batteryText = $battery . "&thinsp;%";
# if no battery info
if ($battery === false) {
$batteryText = " n/a";
$fa_icon = "fa-battery-empty";
$online['fulltext'][] = 'Battery info not available';
# if ups.status contain CHRG
} else if (is_array($online) && in_array('CHRG', $online['value'])) {
$fa_icon = "fa-battery-charging";
# if ups.status contain DISCHRG
} else if (is_array($online) && in_array('DISCHRG', $online['value'])) {
$fa_icon = "fa-battery-discharging";
$online['fulltext'][] = "Est. " . $battery_runtime . " left";
# other ups.status messages
} else if (is_array($online) && $online['value']) {
$fa_icon = "fa-battery-full";
# blink battery icon if ups.status contain RB (Replace Battery)
if (in_array('RB', $online['value']))
$fa_icon .= ' fa-blink';
# unknown status
} else {
$status[0] = "<span id='nut_battery'class='tooltip-nut' style='margin:0 6px 0 12px' data='[$nut_name] Battery info not available'><i class='fa fa-battery-empty'></i>&thinsp;n/a</span>";
$fa_icon = "fa-battery-empty";
$online['fulltext'][] = 'Battery status unknown';
}

# enable tooltip on Default footer style
if ($config['FOOTER_STYLE'] == 0)
$statusTooltipData = ' data="[' . $nut_name . '] ' . implode(' - ', $online['fulltext']) . '"';

$status[0] = "<span id='" . ($config['FOOTER_STYLE'] == 0 ? "nut_battery" : "") . "' class='tooltip-nut " . $css_class . "'" . $statusTooltipData . "><i class='fa " . $fa_icon . "' style='vertical-align: baseline;'></i>&thinsp;" . $batteryText . "</span>";

# ups.power.nominal (in VA) or compute from load and ups.power.nominal
$apparentPower = $powerNominal > 0 && $load ? round($powerNominal * $load * 0.01) : -1;

Expand All @@ -98,14 +121,28 @@ function format_time($seconds) {
if ($realPower < 0)
$realPower = $realPowerNominal && $load ? round($realPowerNominal * $load * 0.01) : -1;

$powerText = '';
$powerTooltipData = '';
# display load, real and apparent power
if ($realPower >= 0 && $apparentPower >= 0) {
$status[1] = "<span id='".($config['FOOTER_STYLE'] == 1 ? "copyright" : "nut_power")."' class='tooltip-nut " . ($load >= 90 ? "$red" : ($config['FOOTER_STYLE'] == 1 ? "$black" : "$green")) . "' data='[{$nut_name}] Load: $load&thinsp;% - Real power: $realPower&thinsp;W - Apparent power: $apparentPower&thinsp;VA'><i class='fa fa-plug'></i>&thinsp;{$realPower}&thinsp;W ({$apparentPower}&thinsp;VA)</span>";
$powerText = "{$realPower}&thinsp;W ({$apparentPower}&thinsp;VA)";
$powerTooltipData = "Load: $load&thinsp;% - Real power: $realPower&thinsp;W - Apparent power: $apparentPower&thinsp;VA";
# display load and real power
} else if ($realPower >= 0 && $load) {
$status[1] = "<span id='".($config['FOOTER_STYLE'] == 1 ? "copyright" : "nut_power")."' class='tooltip-nut " . ($load >= 90 ? "$red" : ($config['FOOTER_STYLE'] == 1 ? "$black" : "$green")) . "' data='[{$nut_name}] Load: $load&thinsp;% - Real power: $realPower&thinsp;W'><i class='fa fa-plug'></i>&thinsp;{$realPower}&thinsp;W</span>";
} else if ($apparentPower >= 0){
$status[1] = "<span id='".($config['FOOTER_STYLE'] == 1 ? "copyright" : "nut_power")."' class='tooltip-nut " . ($load >= 90 ? "$red" : ($config['FOOTER_STYLE'] == 1 ? "$black" : "$green"))."' data='[{$nut_name}] Load: $load&thinsp;% - Apparent power: $apparentPower&thinsp;VA'><i class='fa fa-plug'></i>&thinsp;{$apparentPower}&thinsp;VA</span>";
$powerText = "{$realPower}&thinsp;W";
$powerTooltipData = "Load: $load&thinsp;% - Real power: $realPower&thinsp;W";
# display load and apparent power
} else if ($apparentPower >= 0) {
$powerText = "{$apparentPower}&thinsp;VA";
$powerTooltipData = "Load: $load&thinsp;% - Apparent power: $apparentPower&thinsp;VA";
}

# enable tooltip on Default footer style
if ($config['FOOTER_STYLE'] == 0)
$powerTooltipData = " data='[{$nut_name}] " . $powerTooltipData . "'";

$status[1] = "<span id='".($config['FOOTER_STYLE'] == 0 ? "nut_power" : "")."' class='tooltip-nut " . ($load >= 90 ? $red : ($config['FOOTER_STYLE'] == 1 ? $black : $green)) . "'" . $powerTooltipData . "><i class='fa fa-plug'></i>&thinsp;" . $powerText . "</span>";

echo "<span style='margin:0 6px 0 12px'>".implode('</span><span style="margin:0 6px 0 6px">', $status)."</span>";
} else {
echo "<span style='margin:0 6px 0 12px' id='nut_power' class='tooltip-nut' data='$nut_name: UPS info not availabe, check your settings'><i class='fa fa-battery-empty'></i>&nbsp;n/a</span>";
Expand Down
42 changes: 41 additions & 1 deletion source/nut/usr/local/emhttp/plugins/nut/include/nut_helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ function write_php_ini($array, $file)
}

function safefilerewrite($fileName, $dataToSave)
{ if ($fp = fopen($fileName, 'w'))
{
if ($fp = fopen($fileName, 'w'))
{
$startTime = microtime();
do
Expand All @@ -63,4 +64,43 @@ function safefilerewrite($fileName, $dataToSave)
}
}

function nut_ups_status($rows, $valueOnly = false)
{
global $nut_states;

$severity = 0;
$status_values = [];
$status_fulltext = [];
array_walk($rows, function($row) use (&$severity, &$status_fulltext, &$status_values, $nut_states, $valueOnly) {
# if only ups.status value as param
if ($valueOnly)
$status_values = explode(' ', $row);
# if status array as param, find ups.status
else if (preg_match('/^ups.status:\s*([^$]+)/i', $row, $matches))
$status_values = explode(' ', $matches[1]);
# skip everything else
else
return;

# if debug constant defined, overwrite ups.status values
if (defined('NUT_STATUS_DEBUG'))
$status_values = explode(' ', NUT_STATUS_DEBUG);

# replace ups.status flags with full text message.
$status_fulltext = array_map(function($var) use (&$severity, $nut_states) {
if (isset($nut_states[$var]) && $nut_states[$var]) {
# keep the highest severity message level
$severity = max($severity, $nut_states[$var]['severity']);
return $nut_states[$var]['msg'];
# if unknown status flag, return it
} else {
return $var;
}
}, $status_values);
});

# return highest severity message level, array of status flags and array of full text status message
return ['severity' => $severity, 'value' => $status_values, 'fulltext' => $status_fulltext];
}

?>
21 changes: 10 additions & 11 deletions source/nut/usr/local/emhttp/plugins/nut/include/nut_status.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@
*/
require_once '/usr/local/emhttp/plugins/nut/include/nut_config.php';

$state = [
'OL' => 'Online',
'OB' => 'On battery',
'OL LB' => 'Online low battery',
'OB LB' => 'Low battery'
];

$red = "class='red-text'";
$green = "class='green-text'";
$orange = "class='orange-text'";
Expand All @@ -28,8 +21,9 @@
$result = [];

if (file_exists('/var/run/nut/upsmon.pid')) {

exec("/usr/bin/upsc ".escapeshellarg($nut_name)."@$nut_ip 2>/dev/null", $rows);

if ($_GET['diagsave'] == "true") {

$diagarray = $rows;
Expand All @@ -48,14 +42,19 @@
die($diagstring);

}

$upsStatus = nut_ups_status($rows);

for ($i=0; $i<count($rows); $i++) {
$row = array_map('trim', explode(':', $rows[$i], 2));
$key = $row[0];
$val = strtr($row[1], $state);
$val = $row[1];
switch ($key) {
case 'ups.status':
$status[0] = $val ? (stripos($val,'online')===false ? "<td $red>$val</td>" : "<td $green>$val</td>") : "<td $orange>Refreshing...</td>";
if ($upsStatus['fulltext'])
$status[0] = '<td' . (isset($nut_msgSeverity[$upsStatus['severity']]) ? ' class="' . $nut_msgSeverity[$upsStatus['severity']]['css_class'] . '"' : '') . '>' . implode(' - ', $upsStatus['fulltext']) . '</td>';
else
$status[0] = '<td class="' . $nut_msgSeverity[1]['css_class'] . '">Refreshing...</td>';
break;
case 'battery.charge':
$status[1] = strtok($val,' ')<=10 ? "<td $red>".intval($val). "&thinsp;%</td>" : "<td $green>".intval($val). "&thinsp;%</td>";
Expand Down Expand Up @@ -85,7 +84,7 @@
}
}

# if manual, override values
# if manual, overwrite values
if ($nut_power == 'manual') {
$powerNominal = intval($nut_powerva);
$realPowerNominal = intval($nut_powerw);
Expand Down
25 changes: 22 additions & 3 deletions source/nut/usr/local/emhttp/plugins/nut/nutFooter.page
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ EOT;
?>

<?require_once '/usr/local/emhttp/plugins/nut/include/nut_config.php';?>
<?$config = parse_ini_file('/boot/config/plugins/nut/nut.cfg');?>
<?if ($nut_footer == "enable" && $nut_running):?>
<?$update= $nut_refresh == "enable" ? true : false;?>
<style type="text/css">
Expand All @@ -65,6 +66,13 @@ EOT;
content: "\f240";
animation: 2s battery-discharging infinite;
}
@keyframes fa-blink {
0% { opacity: 1; }
50% { opacity: 0; }
}
.fa-blink {
animation: fa-blink .6s linear infinite;
}
@keyframes ring{
0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}
2%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}
Expand Down Expand Up @@ -93,6 +101,15 @@ EOT;
-webkit-animation:ring 3s ease infinite;
animation:ring 3s ease infinite
}
#nut_footer {
float: right;
margin-right: 6px;
}
#nut_footer.minimal {
font-family: bitstream;
font-size: 1.1rem;
padding-right: 10px;
}
</style>
<script type="text/javascript">
function getNUTfooter() {
Expand All @@ -119,7 +136,10 @@ EOT;

$(function()
{
footer = $("<span id='nut_footer'></span>").insertAfter("div#footer > span#copyright").css("float","right").css("margin-right", "6px");
var footer = $("<span id='nut_footer'></span>").insertAfter("div#footer > span#copyright");
<?if ($config['FOOTER_STYLE'] == 1): ?>
footer.addClass('minimal');
<?endif;?>
getNUTfooter();
$('body').on('mouseenter', '.tooltip-nut', function()
{
Expand All @@ -138,7 +158,6 @@ EOT;
instance.content($(helper.origin).attr("data"));
}
}).tooltipster('open');

}
});
}
Expand All @@ -154,7 +173,7 @@ EOT;
$('#tblUPSNUTDash').find('tr.updated').remove();

$('#tblUPSNUTDash').append('<tr class="updated"><td>'+
"<tr class='updated'><td><span class='w36 ups'>UPS status:</span><span class='nut_status'>"+data[0]+"</span></td></tr>" +
"<tr class='updated'><td style='display: flex;'><span class='w36 ups'>UPS status:</span><span class='nut_status' style='flex: 1; white-space: normal;'>"+data[0]+"</span></td></tr>" +
"<tr class='updated'><td><span class='w36 ups'>Battery charge:</span><span class='nut_bcharge'>"+data[1]+"</span></td></tr>" +
"<tr class='updated'><td><span class='w36 ups'>Runtime left:</span><span class='nut_timeleft'>"+data[2]+"</span></td></tr>" +
"<tr class='updated'><td><span class='w36 ups'>Nominal power:</span>"+data[3]+"</td></tr>");
Expand Down

0 comments on commit 72f7545

Please sign in to comment.