From 2f481e4cb83f0c72a9f3aad11431e4abcf5d632c Mon Sep 17 00:00:00 2001 From: AppaRao Puli Date: Tue, 29 Jan 2019 17:42:23 +0530 Subject: WebUI: Sensors page modifications Modified sensors page to use Redfish as backend. Also added threshold sensor values in page view. Tested By: Loaded webui page and tested all operations. - Sensors page load and layout. - Search Filter and Severity filters. - Export functionality. Change-Id: Ic799453ffcd17e9a69e073a12173b4e97a928458 Signed-off-by: AppaRao Puli --- app/common/services/api-utils.js | 181 +++++---------------- .../controllers/sensors-overview-controller.html | 94 +++++++---- .../controllers/sensors-overview-controller.js | 116 +++++++++---- app/server-health/styles/sensors.scss | 108 +++++------- 4 files changed, 232 insertions(+), 267 deletions(-) diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js index 211f6d7..7643a4e 100644 --- a/app/common/services/api-utils.js +++ b/app/common/services/api-utils.js @@ -931,158 +931,55 @@ window.angular && (function(angular) { return deferred.promise; }, - getAllSensorStatus: function(callback) { + getSensorsInfo: function(url) { + return $http({ + method: 'GET', + url: DataService.getHost() + url, + withCredentials: true + }) + .then( + function(response) { + return response.data; + }, + function(error) { + console.log(JSON.stringify(error)); + }); + }, + getAllChassisCollection: function() { + var deferred = $q.defer(); + var promises = []; $http({ method: 'GET', - url: DataService.getHost() + - '/xyz/openbmc_project/sensors/enumerate', + url: DataService.getHost() + '/redfish/v1/Chassis', withCredentials: true }) .then( function(response) { - var json = JSON.stringify(response.data); - var content = JSON.parse(json); - var dataClone = JSON.parse(JSON.stringify(content.data)); - var sensorData = []; - var severity = {}; - var title = ''; - var tempKeyParts = []; - var order = 0; - var customOrder = 0; - - function getSensorStatus(reading) { - var severityFlags = { - critical: false, - warning: false, - normal: false - }, - severityText = '', order = 0; - - if (reading.hasOwnProperty('CriticalLow') && - reading.Value < reading.CriticalLow) { - severityFlags.critical = true; - severityText = 'critical'; - order = 2; - } else if ( - reading.hasOwnProperty('CriticalHigh') && - reading.Value > reading.CriticalHigh) { - severityFlags.critical = true; - severityText = 'critical'; - order = 2; - } else if ( - reading.hasOwnProperty('CriticalLow') && - reading.hasOwnProperty('WarningLow') && - reading.Value >= reading.CriticalLow && - reading.Value <= reading.WarningLow) { - severityFlags.warning = true; - severityText = 'warning'; - order = 1; - } else if ( - reading.hasOwnProperty('WarningHigh') && - reading.hasOwnProperty('CriticalHigh') && - reading.Value >= reading.WarningHigh && - reading.Value <= reading.CriticalHigh) { - severityFlags.warning = true; - severityText = 'warning'; - order = 1; - } else { - severityFlags.normal = true; - severityText = 'normal'; - } - return { - flags: severityFlags, - severityText: severityText, - order: order - }; - } - - for (var key in content.data) { - if (content.data.hasOwnProperty(key) && - content.data[key].hasOwnProperty('Unit')) { - severity = getSensorStatus(content.data[key]); - - if (!content.data[key].hasOwnProperty('CriticalLow')) { - content.data[key].CriticalLow = '--'; - content.data[key].CriticalHigh = '--'; - } - - if (!content.data[key].hasOwnProperty('WarningLow')) { - content.data[key].WarningLow = '--'; - content.data[key].WarningHigh = '--'; - } - - tempKeyParts = key.split('/'); - title = tempKeyParts.pop(); - title = tempKeyParts.pop() + '_' + title; - title = title.split('_') - .map(function(item) { - return item.toLowerCase() - .charAt(0) - .toUpperCase() + - item.slice(1); - }) - .reduce(function(prev, el) { - return prev + ' ' + el; - }); - - content.data[key].Value = getScaledValue( - content.data[key].Value, content.data[key].Scale); - content.data[key].CriticalLow = getScaledValue( - content.data[key].CriticalLow, - content.data[key].Scale); - content.data[key].CriticalHigh = getScaledValue( - content.data[key].CriticalHigh, - content.data[key].Scale); - content.data[key].WarningLow = getScaledValue( - content.data[key].WarningLow, - content.data[key].Scale); - content.data[key].WarningHigh = getScaledValue( - content.data[key].WarningHigh, - content.data[key].Scale); - if (Constants.SENSOR_SORT_ORDER.indexOf( - content.data[key].Unit) > -1) { - customOrder = Constants.SENSOR_SORT_ORDER.indexOf( - content.data[key].Unit); - } else { - customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT; - } - - sensorData.push(Object.assign( - { - path: key, - selected: false, - confirm: false, - copied: false, - title: title, - unit: - Constants - .SENSOR_UNIT_MAP[content.data[key].Unit], - severity_flags: severity.flags, - status: severity.severityText, - order: severity.order, - custom_order: customOrder, - search_text: - (title + ' ' + content.data[key].Value + ' ' + - Constants.SENSOR_UNIT_MAP[content.data[key] - .Unit] + - ' ' + severity.severityText + ' ' + - content.data[key].CriticalLow + ' ' + - content.data[key].CriticalHigh + ' ' + - content.data[key].WarningLow + ' ' + - content.data[key].WarningHigh + ' ') - .toLowerCase(), - original_data: - {key: key, value: content.data[key]} + var members = response.data['Members']; + angular.forEach( + members, + function(member) { + promises.push($http({ + method: 'GET', + url: DataService.getHost() + + member['@odata.id'], + withCredentials: true + }).then(function(res) { + return res.data; + })); + }), + $q.all(promises).then( + function(results) { + deferred.resolve(results); }, - content.data[key])); - } - } - - callback(sensorData, dataClone); + function(errors) { + deferred.reject(errors); + }); }, function(error) { - console.log(error); + console.log(JSON.stringify(error)); }); + return deferred.promise; }, getActivation: function(imageId) { return $http({ diff --git a/app/server-health/controllers/sensors-overview-controller.html b/app/server-health/controllers/sensors-overview-controller.html index 5a6f95a..3ad4aa6 100644 --- a/app/server-health/controllers/sensors-overview-controller.html +++ b/app/server-health/controllers/sensors-overview-controller.html @@ -5,12 +5,11 @@
- - +
@@ -32,41 +31,74 @@ -
- +
+ + +
-
- +
{{messages.NO_SENSOR_DATA}} {{messages.CRITICAL_NO_SENSOR_DATA}} {{messages.WARNING_NO_SENSOR_DATA}} - {{messages.NORMAL_NO_SENSOR_DATA}} - + {{messages.NORMAL_NO_SENSOR_DATA}}
- -
-
-
-

Sensors ({{filteredSensorData.length}})

-

Low critical

-

Low warning

-

Current

-

High warning

-

High critical

+
+
+
+
+
Name
+
Status
+
LC
+
LW
+
Reading
+
HW
+
HC
+
+
+
+
+
{{sensor.Name}}
+
{{sensor.Status.Health}}
+
{{sensor.LowerThresholdCritical | number:2}} Volts
+
{{sensor.LowerThresholdNonCritical | number:2}} Volts
+
{{sensor.ReadingVolts | number:2}} Volts
+
{{sensor.UpperThresholdNonCritical | number:2}} Volts
+
{{sensor.UpperThresholdCritical | number:2}} Volts
+
+
+
{{sensor.Name}}
+
{{sensor.Status.Health}}
+
{{sensor.LowerThresholdCritical | number:2}} °C
+
{{sensor.LowerThresholdNonCritical | number:2}} °C
+
{{sensor.ReadingCelsius | number:2}} °C
+
{{sensor.UpperThresholdNonCritical | number:2}} °C
+
{{sensor.UpperThresholdCritical | number:2}} °C
+
+
+
{{sensor.Name}}
+
{{sensor.Status.Health}}
+
{{sensor.LowerThresholdCritical | number:2}} {{sensor.ReadingUnits}}
+
{{sensor.LowerThresholdNonCritical | number:2}} {{sensor.ReadingUnits}}
+
{{sensor.Reading | number:2}} {{sensor.ReadingUnits}}
+
NA
+
NA
+
+
-
- -
-

{{sensor.title}}

-

Low critical{{sensor.CriticalLow}}

-

Low warning{{sensor.WarningLow}}

-

Current{{sensor.Value}}

-

High warning{{sensor.WarningHigh}}

-

High critical{{sensor.CriticalHigh}}

-
diff --git a/app/server-health/controllers/sensors-overview-controller.js b/app/server-health/controllers/sensors-overview-controller.js index 40e0b58..96349d2 100644 --- a/app/server-health/controllers/sensors-overview-controller.js +++ b/app/server-health/controllers/sensors-overview-controller.js @@ -9,27 +9,27 @@ window.angular && (function(angular) { 'use strict'; angular.module('app.overview').controller('sensorsOverviewController', [ - '$scope', '$log', '$window', 'APIUtils', 'dataService', 'Constants', - function($scope, $log, $window, APIUtils, dataService, Constants) { + '$scope', '$q', '$window', 'APIUtils', 'dataService', 'Constants', + function($scope, $q, $window, APIUtils, dataService, Constants) { $scope.dataService = dataService; - $scope.dropdown_selected = false; - - $scope.$log = $log; + $scope.loading = false; + $scope.componentList = []; + $scope.sensorsInfo = {}; + $scope.fullSensorsInfo = []; + $scope.selectedComponent = {}; + $scope.showThresholds = true; // TODO: add button to toggle this.. + $scope.showCompDropdown = false; $scope.customSearch = ''; $scope.searchTerms = []; $scope.messages = Constants.MESSAGES.SENSOR; + $scope.filteredVoltSensors = []; + $scope.filteredTempSensors = []; + $scope.filteredFanSensors = []; + $scope.selectedSeverity = - {all: true, normal: false, warning: false, critical: false}; + {all: true, ok: false, warning: false, critical: false}; $scope.export_name = 'sensors.json'; - $scope.loading = false; - $scope.jsonData = function(data) { - var dt = {}; - data.data.forEach(function(item) { - dt[item.original_data.key] = item.original_data.value; - }); - return JSON.stringify(dt); - }; $scope.clear = function() { $scope.customSearch = ''; @@ -64,7 +64,7 @@ window.angular && (function(angular) { $scope.selectedSeverity.all = !$scope.selectedSeverity.all; if ($scope.selectedSeverity.all) { - $scope.selectedSeverity.normal = false; + $scope.selectedSeverity.ok = false; $scope.selectedSeverity.warning = false; $scope.selectedSeverity.critical = false; } @@ -73,9 +73,9 @@ window.angular && (function(angular) { $scope.toggleSeverity = function(severity) { $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity]; - if (['normal', 'warning', 'critical'].indexOf(severity) > -1) { + if (['ok', 'warning', 'critical'].indexOf(severity) > -1) { if ($scope.selectedSeverity[severity] == false && - (!$scope.selectedSeverity.normal && + (!$scope.selectedSeverity.ok && !$scope.selectedSeverity.warning && !$scope.selectedSeverity.critical)) { $scope.selectedSeverity.all = true; @@ -83,10 +83,10 @@ window.angular && (function(angular) { } } - if ($scope.selectedSeverity.normal && $scope.selectedSeverity.warning && + if ($scope.selectedSeverity.ok && $scope.selectedSeverity.warning && $scope.selectedSeverity.critical) { $scope.selectedSeverity.all = true; - $scope.selectedSeverity.normal = false; + $scope.selectedSeverity.ok = false; $scope.selectedSeverity.warning = false; $scope.selectedSeverity.critical = false; } else { @@ -98,31 +98,87 @@ window.angular && (function(angular) { if ($scope.selectedSeverity.all) return true; return ( - (sensor.severity_flags.normal && $scope.selectedSeverity.normal) || - (sensor.severity_flags.warning && + ((sensor.Status.Health == 'OK') && $scope.selectedSeverity.ok) || + ((sensor.Status.Health == 'Warning') && $scope.selectedSeverity.warning) || - (sensor.severity_flags.critical && + ((sensor.Status.Health == 'Critical') && $scope.selectedSeverity.critical)); }; $scope.filterBySearchTerms = function(sensor) { if (!$scope.searchTerms.length) return true; for (var i = 0, length = $scope.searchTerms.length; i < length; i++) { - if (sensor.search_text.indexOf($scope.searchTerms[i].toLowerCase()) == - -1) + // TODO: Form it while getting data + var search_text = sensor.Name.toLowerCase(); + if (search_text.indexOf($scope.searchTerms[i].toLowerCase()) == -1) return false; } return true; }; + $scope.selectComponent = function(index) { + $scope.loading = true; + $scope.showCompDropdown = false; + if (index == -1) { + // Flattened sensor data to display all sensors. + $scope.selectedComponent = {'Name': 'All'}; + $scope.sensorsInfo = {'Temperatures': [], 'Fans': [], 'Voltages': []}; + // Looping through all chassis collections to flattened sensors data + angular.forEach($scope.fullSensorsInfo, function(record) { + $scope.sensorsInfo.Temperatures = [].concat( + $scope.sensorsInfo.Temperatures, record.sensors.Temperatures); + $scope.sensorsInfo.Fans = + [].concat($scope.sensorsInfo.Fans, record.sensors.Fans); + $scope.sensorsInfo.Voltages = + [].concat($scope.sensorsInfo.Voltages, record.sensors.Voltages); + }); + } else { + $scope.selectedComponent = $scope.fullSensorsInfo[index]; + $scope.sensorsInfo = $scope.selectedComponent['sensors']; + } + $scope.loading = false; + }; + + function getComponentSensors(component) { + var data = component; + data['sensors'] = {'Temperatures': [], 'Fans': [], 'Voltages': []}; + APIUtils.getSensorsInfo(component.Thermal['@odata.id']) + .then(function(res) { + if (res.hasOwnProperty('Temperatures')) { + data.sensors['Temperatures'] = res.Temperatures; + } + if (res.hasOwnProperty('Fans')) { + data.sensors['Fans'] = res.Fans; + } + return; + }); + APIUtils.getSensorsInfo(component.Power['@odata.id']) + .then(function(res) { + if (res.hasOwnProperty('Voltages')) { + data.sensors['Voltages'] = res.Voltages; + } + return; + }); + return data; + }; + $scope.loadSensorData = function() { $scope.loading = true; - APIUtils.getAllSensorStatus(function(data, originalData) { - $scope.data = data; - $scope.originalData = originalData; - $scope.export_data = JSON.stringify(originalData); - $scope.loading = false; - }); + APIUtils.getAllChassisCollection() + .then( + function(chassisList) { + angular.forEach(chassisList, function(chassis) { + var resData = getComponentSensors(chassis); + $scope.fullSensorsInfo.push(resData); + }); + }, + function(error) { + console.log(JSON.stringify(error)); + }) + .finally(function() { + $scope.selectComponent(0); + $scope.loading = false; + }); }; $scope.loadSensorData(); diff --git a/app/server-health/styles/sensors.scss b/app/server-health/styles/sensors.scss index 041a1e5..074d27b 100644 --- a/app/server-health/styles/sensors.scss +++ b/app/server-health/styles/sensors.scss @@ -37,35 +37,15 @@ $title-minWidth: 210px; } } -.sensor__title { - min-width: 28%; - margin-bottom: 0; -} - -.sensor__reading { - width: 100%; - text-align: right; - margin-bottom: 0; - display: none; - @include mediaQuery(medium) { - display: inline-block; - width: auto; - min-width: calc(70% * (1 / 5) - 18px); - } -} - -.sensor__readings-row { - width: 100%; - position: relative; - display: block; +.sensor__table { + width: auto; + min-width: 60%; margin: 0; background: $white; text-decoration: none; border: 1px solid $medgrey; background: lighten($lightgrey,1%); - margin-top: 1em; @include mediaQuery(medium) { - padding: .3em 1em .3em 1.5em; margin-top: 0; border-top: 0; background: transparent; @@ -73,75 +53,54 @@ $title-minWidth: 210px; .sensor__title { font-weight: 700; background: darken($lightgrey, 5%); - min-width: 100%; - padding: .8em; + min-width: 25%; + overflow: visible; @include mediaQuery(medium) { - min-width: 30%; + min-width: 25%; background: transparent; - padding: .5em .5em .5em 0; - } - .icon__normal { - width: 0; } } - .content-label { - font-size: 1em; - margin-left: .8em; - color: $darkgrey; - } - .sensor__reading { - @include fontCourierBold; + .sensor__reading, + .sensor__status { display: block; - padding: .3em .8em; + min-width: 15%; + overflow: visible; @include mediaQuery(medium) { display: inline-block; - padding: 0; } } - .sensor__current { - background: darken($thresh-normal, 3%); - margin: 0; + .sensor__threshold { + display: block; + overflow: visible; @include mediaQuery(medium) { - background: $thresh-normal; - padding: .7em .3em; - margin-left: 10px; - min-width: 109px; - } - @include mediaQuery(large) { - background: $thresh-normal; - padding: .7em; - margin-left: .3em; - margin-right: .3em; - min-width: 150px; - } - .sensor__label { - font-weight: 700; - @include mediaQuery(medium) { - font-weight:300; - } + display: inline-block; } } - .sensor__critical { + .sensor__Critical { background: $thresh-critical; color: $white; .content-label { color: $white; } } - .sensor__warn { + .sensor__Warning { background: $thresh-warning; color: $black; .content-label { color: $black; } } - + .sensor__OK { + background: $thresh-normal; + color: $black; + .content-label { + color: $black; + } + } } // Sensors - #sensors, #sensors-overview { - .toggle-filter { margin-bottom: 20px; } @@ -149,6 +108,27 @@ $title-minWidth: 210px; padding-left: 0px; padding-right: 0px; } + .dropdown__button { + margin-bottom: 1.2em; + } + .dropdown__list { + margin-top: -17px; + } + .dropdown__button { + width: 25em; + margin-top: 0; + text-align: left; + border: 0.1em solid; + } + .dropdown__wrapper { + width: 25em; + margin-top: 0.4em; + text-align: left; + } + .select__filter { + margin-bottom: 20px; + margin-left: 15px; + } } //end sensor details -- cgit v1.2.1