From 86cda4fadae771251ddf6173f9af518604ee3879 Mon Sep 17 00:00:00 2001 From: Meliox Date: Thu, 20 Aug 2026 20:01:40 +0200 Subject: [PATCH] =?UTF-8?q?fix(node=5Finfo):=20normalize=20UPS=20data=20?= =?UTF-8?q?=E2=80=94=20derive=20ups.realpower=20fallback=20and=20clean=20i?= =?UTF-8?q?nvalid=20battery.mfr.date?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/node_info/files/Collector/Ups.pm | 26 +++++++++++++++++++ .../node_info/files/PveMod_pvemanagerlib.js | 10 +++---- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/modules/node_info/files/Collector/Ups.pm b/src/modules/node_info/files/Collector/Ups.pm index 487507a..2596ca1 100644 --- a/src/modules/node_info/files/Collector/Ups.pm +++ b/src/modules/node_info/files/Collector/Ups.pm @@ -112,6 +112,8 @@ sub _parse_upsc_output { } } } + + _normalize_ups_data($ups_data); }; if ($@) { debug(__LINE__, "Error parsing upsc output: $@"); @@ -122,4 +124,28 @@ sub _parse_upsc_output { return $ups_data; } +# ============================================================================ +# UPS — data normalization +# ============================================================================ + +sub _normalize_ups_data { + my ($ups_data) = @_; + + # Some devices report a placeholder (e.g. "OPEN") instead of a real date + if (defined $ups_data->{'battery.mfr.date'} && $ups_data->{'battery.mfr.date'} !~ m{^\d{4}[/-]\d{1,2}[/-]\d{1,2}$}) { + delete $ups_data->{'battery.mfr.date'}; + } + + # Derive real power draw for devices that don't report ups.realpower directly + if (!defined $ups_data->{'ups.realpower'}) { + if (defined $ups_data->{'ups.load'} && defined $ups_data->{'ups.realpower.nominal'}) { + $ups_data->{'ups.realpower'} = int((($ups_data->{'ups.load'} / 100) * $ups_data->{'ups.realpower.nominal'}) + 0.5); + } elsif (defined $ups_data->{'output.current'} && defined $ups_data->{'output.voltage'}) { + $ups_data->{'ups.realpower'} = int(($ups_data->{'output.current'} * $ups_data->{'output.voltage'}) + 0.5); + } + } + + return; +} + 1; diff --git a/src/modules/node_info/files/PveMod_pvemanagerlib.js b/src/modules/node_info/files/PveMod_pvemanagerlib.js index ea9755c..e9507ff 100644 --- a/src/modules/node_info/files/PveMod_pvemanagerlib.js +++ b/src/modules/node_info/files/PveMod_pvemanagerlib.js @@ -969,7 +969,7 @@ Ext.define('PVE.node.StatusView', { const testResult = upsData['ups.test.result']; const batteryChargeLow = upsData['battery.charge.low']; const batteryRuntimeLow = upsData['battery.runtime.low']; - const upsRealPowerNominal = upsData['ups.realpower.nominal']; + const upsRealPower = upsData['ups.realpower']; const batteryMfrDate = upsData['battery.mfr.date']; // Main status line with all metrics @@ -1046,12 +1046,8 @@ Ext.define('PVE.node.StatusView', { // Calculate actual watt usage if (statusLine) statusLine += ' | '; let actualWattage = null; - if (upsLoad && upsRealPowerNominal) { - const load = parseFloat(upsLoad); - const nominal = parseFloat(upsRealPowerNominal); - if (!isNaN(load) && !isNaN(nominal)) { - actualWattage = Math.round((load / 100) * nominal); - } + if (upsRealPower && !isNaN(parseFloat(upsRealPower))) { + actualWattage = Math.round(parseFloat(upsRealPower)); } // Real power (calculated watt usage)