From 4fc5400000a74382267b0955fdaf6b699ef2fc96 Mon Sep 17 00:00:00 2001 From: 01101001c <01101001c@gmail.com> Date: Mon, 18 Mar 2013 17:08:01 -0700 Subject: [PATCH] Thermal Sensors Widget (for pfSense v2.1-BETA1 and up). Original post: http://forum.pfsense.org/index.php/topic,59193.0.html --- .../www/widgets/include/thermal_sensors.inc | 27 ++ .../www/widgets/javascript/thermal_sensors.js | 312 +++++++++++++++++ .../widgets/thermal_sensors.widget.php | 316 ++++++++++++++++++ 3 files changed, 655 insertions(+) create mode 100644 usr/local/www/widgets/include/thermal_sensors.inc create mode 100644 usr/local/www/widgets/javascript/thermal_sensors.js create mode 100644 usr/local/www/widgets/widgets/thermal_sensors.widget.php diff --git a/usr/local/www/widgets/include/thermal_sensors.inc b/usr/local/www/widgets/include/thermal_sensors.inc new file mode 100644 index 0000000000..2ebc31decd --- /dev/null +++ b/usr/local/www/widgets/include/thermal_sensors.inc @@ -0,0 +1,27 @@ +> Advanced >> Miscellaneous tab >> Thermal Sensors section. +function getThermalSensorsData() { + + exec("/sbin/sysctl -a | grep temperature", $dfout); + $thermalSensorsData = join("|", $dfout); + return $thermalSensorsData; + +} +?> diff --git a/usr/local/www/widgets/javascript/thermal_sensors.js b/usr/local/www/widgets/javascript/thermal_sensors.js new file mode 100644 index 0000000000..17f07d087b --- /dev/null +++ b/usr/local/www/widgets/javascript/thermal_sensors.js @@ -0,0 +1,312 @@ +/* + $Id: thermal_sensors.js + Description: + Javascript functions to get and show thermal sensors data in thermal_sensors.widget.php. + NOTE: depends on proper cofing in System >> Advanced >> Miscellaneous tab >> Thermal Sensors section. + File location: + \usr\local\www\widgets\javascript\ + Used by: + \usr\local\www\widgets\widgets\thermal_sensors.widget.php + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + + +//should be called from "thermal_sensors.widget.php" +function showThermalSensorsData() { + + //get data from thermal_sensors.widget.php + url = "/widgets/widgets/thermal_sensors.widget.php?getThermalSensorsData=1" + //IE fix to disable cache when using http:// , just append timespan + + new Date().getTime(); + + jQuery.ajax(url, { + type: 'get', + success: function(data) { + var thermalSensorsData = data || ""; + buildThermalSensorsData(thermalSensorsData); + }, + error: function(jqXHR, status, error){ + buildThermalSensorsDataRaw( + "Error getting data from [thermal_sensors.widget.php] - |" + + "status: [" + (status || "") + "]|" + + "error: [" + (error || "") + "]"); + } + }); + + //call itself in 11 seconds + window.setTimeout(showThermalSensorsData, 11000); +} + +function buildThermalSensorsData(thermalSensorsData) { + //NOTE: variable thermal_sensors_widget_showRawOutput is declared/set in "thermal_sensors.widget.php" + if (thermal_sensors_widget_showRawOutput) { + buildThermalSensorsDataRaw(thermalSensorsData); + } + else { + buildThermalSensorsDataGraph(thermalSensorsData); + } +} + +function buildThermalSensorsDataRaw(thermalSensorsData) { + + var thermalSensorsContent = ""; + + if (thermalSensorsData && thermalSensorsData != "") { + thermalSensorsContent = thermalSensorsData.replace(/\|/g, "
"); + //rawData = thermalSensorsData.split("|").join("
"); + } + + loadThermalSensorsContainer(thermalSensorsContent); +} + +function loadThermalSensorsContainer (thermalSensorsContent) { + + if (thermalSensorsContent && thermalSensorsContent != "") { + //load generated graph (or raw data) into thermalSensorsContainer (thermalSensorsContainer DIV defined in "thermal_sensors.widget.php") + jQuery('#thermalSensorsContainer').html(thermalSensorsContent); + } else { + jQuery('#thermalSensorsContainer').html("No Thermal Sensors data available.

"); + jQuery('
').html( + "* You can configure a proper Thermal Sensor / Module under
" + + "   System > Advanced > Miscellaneous : Thermal Sensors section.
" + ).appendTo('#thermalSensorsContainer'); + } +} + +function buildThermalSensorsDataGraph(thermalSensorsData) { + + //local constants + var normalColor = "LimeGreen"; + var normalColorShadowTop = "Lime"; + var normalColorShadowBottom = "Green"; + + var warningColor = "Orange"; + var warningColorShadowBottom = "Chocolate"; + + var criticalColor = "Red"; + var criticalColorShadowBottom = "DarkRed"; + + //local variables + var barBgColor = normalColor; //green/normal as default + var barBgColorShadowTop = normalColorShadowTop; //green/normal as default + var barBgColorShadowBottom = normalColorShadowBottom; //green/normal as default + + var thermalSensorsArray = new Array(); + + if (thermalSensorsData && thermalSensorsData != ""){ + thermalSensorsArray = thermalSensorsData.split("|"); + } + + var thermalSensorsHTMLContent = ""; + var itemsToPulsate = new Array(); + + //generate graph for each temperature sensor and append to thermalSensorsHTMLContent string + for (var i = 0; i < thermalSensorsArray.length; i++) { + + var sensorDataArray = thermalSensorsArray[i].split(":"); + var sensorName = sensorDataArray[0].trim(); + var thermalSensorValue = getThermalSensorValue(sensorDataArray[1]); + + var pulsateTimes = 0; + var pulsateDuration = 0; + + var warningTempThresholdPosition = 0; + var criticalTempThresholdPosition = 0; + + //NOTE: the following variables are declared/set in "thermal_sensors.widget.php": + // thermal_sensors_widget_coreWarningTempThreshold, thermal_sensors_widget_coreCriticalTempThreshold, + // thermal_sensors_widget_zoneWarningTempThreshold, thermal_sensors_widget_zoneCriticalTempThreshold + // thermal_sensors_widget_pulsateWarning, thermal_sensors_widget_pulsateCritical + + //set graph color and pulsate parameters + if (sensorName.indexOf("cpu") > -1) { //check CPU Threshold config settings + + warningTempThresholdPosition = thermal_sensors_widget_coreWarningTempThreshold; + criticalTempThresholdPosition = thermal_sensors_widget_coreCriticalTempThreshold; + + if (thermalSensorValue < thermal_sensors_widget_coreWarningTempThreshold) { + barBgColor = normalColor; + barBgColorShadowTop = normalColorShadowTop; + barBgColorShadowBottom = normalColorShadowBottom; + pulsateTimes = 0; + pulsateDuration = 0; + } else if (thermalSensorValue >= thermal_sensors_widget_coreWarningTempThreshold && thermalSensorValue < thermal_sensors_widget_coreCriticalTempThreshold) { + barBgColor = warningColor; + barBgColorShadowTop = warningColor; + barBgColorShadowBottom = warningColorShadowBottom; + pulsateTimes = thermal_sensors_widget_pulsateWarning ? 4 : 0; + pulsateDuration = thermal_sensors_widget_pulsateWarning ? 900 : 0; + } else { // thermalSensorValue > thermal_sensors_widget_coreCriticalTempThreshold + barBgColor = criticalColor; + barBgColorShadowTop = criticalColor; + barBgColorShadowBottom = criticalColorShadowBottom; + pulsateTimes = thermal_sensors_widget_pulsateCritical ? 7 : 0; + pulsateDuration = thermal_sensors_widget_pulsateCritical ? 900 : 0; + } + } else { //assuming sensor is for a zone, check Zone Threshold config settings + + warningTempThresholdPosition = thermal_sensors_widget_zoneWarningTempThreshold; + criticalTempThresholdPosition = thermal_sensors_widget_zoneCriticalTempThreshold; + + if (thermalSensorValue < thermal_sensors_widget_zoneWarningTempThreshold) { + + barBgColor = normalColor; + barBgColorShadowTop = normalColorShadowTop; + barBgColorShadowBottom = normalColorShadowBottom; + pulsateTimes = 0; + pulsateDuration = 0; + + } else if (thermalSensorValue >= thermal_sensors_widget_zoneWarningTempThreshold + && thermalSensorValue < thermal_sensors_widget_zoneCriticalTempThreshold) { + + barBgColor = warningColor; + barBgColorShadowTop = warningColor; + barBgColorShadowBottom = warningColorShadowBottom; + pulsateTimes = thermal_sensors_widget_pulsateWarning ? 4 : 0; + pulsateDuration = thermal_sensors_widget_pulsateWarning ? 900 : 0; + + } else { // thermalSensorValue > thermal_sensors_widget_zoneCriticalTempThreshold + + barBgColor = criticalColor; + barBgColorShadowTop = criticalColor; + barBgColorShadowBottom = criticalColorShadowBottom; + pulsateTimes = thermal_sensors_widget_pulsateCritical ? 7 : 0; + pulsateDuration = thermal_sensors_widget_pulsateCritical ? 900 : 0; + } + } + + //NOTE: variable thermal_sensors_widget_showFullSensorName is declared/set in "thermal_sensors.widget.php" + if (!thermal_sensors_widget_showFullSensorName) { + sensorName = getSensorFriendlyName(sensorName); + } + + //build temperature item/row for a sensor + //NOTE: additional styles are set in 'thermal_sensors.widget.php' + var thermalSensorRow = "
" + + //sensor name and temperature value + "
" + sensorName + ":
" + thermalSensorValue + " °C
" + + //temperature bar + "
" + + "
" + + //threshold targets (warning and critical) + "
" + + "
" + + //temperature scale (max 100 C) + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
100°
" + + "
" + + "
"; + + //collect parameters for warning/critical items we need to pulsate + if (pulsateTimes > 0) { + var params = i + "|" + barBgColor + "|" + pulsateTimes + "|" + pulsateDuration; + itemsToPulsate.push(params); + } + + //append HTML item + thermalSensorsHTMLContent = thermalSensorsHTMLContent + thermalSensorRow; + } + + //load generated graph into thermalSensorsContainer (DIV defined in "thermal_sensors.widget.php") + loadThermalSensorsContainer(thermalSensorsHTMLContent); + + if (itemsToPulsate.length > 0) { + //pulsate/flash warning/critical items we collected + pulsateThermalSensorsItems(itemsToPulsate); + } +} + +function pulsateThermalSensorsItems(itemsToPulsate) { + + //pulsate/flash warning/critical items we collected + for (var i = 0; i < itemsToPulsate.length; i++) { + + var pulsateParams = itemsToPulsate[i].split("|"); + var rowNum = parseInt(pulsateParams[0]); + //var textColor = pulsateParams[1]; + var pulsateTimes = parseInt(pulsateParams[2]); + var pulsateDuration = parseInt(pulsateParams[3]); + + //pulsate temp Value + var divThermalSensorValue = jQuery("#thermalSensorValue" + rowNum); //get temp value by id + divThermalSensorValue.effect("pulsate", { + times: pulsateTimes + ,easing: 'linear' //'easeInExpo' + }, pulsateDuration); + ////set Temp Value color + //divThermalSensorValue.css( { color: textColor } ); + + //pulsate temp Bar + var divThermalSensorBar = jQuery("#thermalSensorBar" + rowNum); //get temp bar by id + divThermalSensorBar.effect("pulsate", { + times: pulsateTimes + ,easing: 'linear' //'easeInExpo' + }, pulsateDuration); + + } +} + +function getSensorFriendlyName(sensorFullName){ + + var friendlyName = ""; + + switch (sensorFullName) { + case "hw.acpi.thermal.tz0.temperature": + friendlyName = "Zone 0"; + break; + case "hw.acpi.thermal.tz1.temperature": + friendlyName = "Zone 1"; + break; + case "dev.cpu.0.temperature": + friendlyName = "Core 0"; + break; + case "dev.cpu.1.temperature": + friendlyName = "Core 1"; + break; + case "dev.cpu.2.temperature": + friendlyName = "Core 2"; + break; + case "dev.cpu.3.temperature": + friendlyName = "Core 3"; + break; + default: + friendlyName = sensorFullName; + } + + return friendlyName; +} + +function getThermalSensorValue(stringValue){ + return (+parseFloat(stringValue) || 0).toFixed(1); +} diff --git a/usr/local/www/widgets/widgets/thermal_sensors.widget.php b/usr/local/www/widgets/widgets/thermal_sensors.widget.php new file mode 100644 index 0000000000..7fa4a2b096 --- /dev/null +++ b/usr/local/www/widgets/widgets/thermal_sensors.widget.php @@ -0,0 +1,316 @@ +> Advanced >> Miscellaneous tab >> Thermal Sensors section. + + File location: + \usr\local\www\widgets\widgets\ + Depends on: + \usr\local\www\widgets\javascript\thermal_sensors.js + \usr\local\www\widgets\include\thermal_sensors.inc + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +$nocsrf = true; + +require_once("guiconfig.inc"); +require_once("/usr/local/www/widgets/include/thermal_sensors.inc"); + +//========================================================================= +//called by showThermalSensorsData() (jQuery Ajax call) in thermal_sensors.js +if (isset($_GET["getThermalSensorsData"])) { + //get Thermal Sensors data and return + echo getThermalSensorsData(); + return; +} +//========================================================================= + + +const WIDGETS_CONFIG_SECTION_KEY = "widgets"; +const THERMAL_SENSORS_WIDGET_SUBSECTION_KEY = "thermal_sensors_widget"; + +//default constants +const DEFAULT_WARNING_THRESHOLD = 60; //60 C +const DEFAULT_CRITICAL_THRESHOLD = 70; //70 C +const MIN_THRESHOLD_VALUE = 1; //deg C +const MAX_THRESHOLD_VALUE = 100; //deg C + +//NOTE: keys used in $_POST and $config should match text and checkbox inputs' IDs/names in HTML code section +//========================================================================= +//save widget config settings on POST +if ($_POST) { + saveThresholdSettings($config, $_POST, "thermal_sensors_widget_zone_warning_threshold", "thermal_sensors_widget_zone_critical_threshold"); + saveThresholdSettings($config, $_POST, "thermal_sensors_widget_core_warning_threshold", "thermal_sensors_widget_core_critical_threshold"); + + //handle checkboxes separately + saveGraphDisplaySettings($config, $_POST, "thermal_sensors_widget_show_raw_output"); + saveGraphDisplaySettings($config, $_POST, "thermal_sensors_widget_show_full_sensor_name"); + saveGraphDisplaySettings($config, $_POST, "thermal_sensors_widget_pulsate_warning"); + saveGraphDisplaySettings($config, $_POST, "thermal_sensors_widget_pulsate_critical"); + + //write settings to config file + write_config("Saved thermal_sensors_widget settings via Dashboard."); + header("Location: ../../index.php"); +} + +function saveThresholdSettings(&$configArray, &$postArray, $warningValueKey, $criticalValueKey) { + $warningValue = 0; + $criticalValue = 0; + + if (isset($postArray[$warningValueKey])) { + $warningValue = (int) $postArray[$warningValueKey]; + } + + if (isset($postArray[$criticalValueKey])) { + $criticalValue = (int) $postArray[$criticalValueKey]; + } + + if ( + ($warningValue >= MIN_THRESHOLD_VALUE && $warningValue <= MAX_THRESHOLD_VALUE) && + ($criticalValue >= MIN_THRESHOLD_VALUE && $criticalValue <= MAX_THRESHOLD_VALUE) && + ($warningValue < $criticalValue) + ) { + //all validated ok, save to config array + $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$warningValueKey] = $warningValue; + $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$criticalValueKey] = $criticalValue; + } +} + +function saveGraphDisplaySettings(&$configArray, &$postArray, $valueKey) { + $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey] = isset($postArray[$valueKey]) ? 1 : 0; +} + +//========================================================================= +//get Threshold settings from config (apply defaults if missing) +$thermal_sensors_widget_zoneWarningTempThreshold = getThresholdValueFromConfig($config, "thermal_sensors_widget_zone_warning_threshold", DEFAULT_WARNING_THRESHOLD); +$thermal_sensors_widget_zoneCriticalTempThreshold = getThresholdValueFromConfig($config, "thermal_sensors_widget_zone_critical_threshold", DEFAULT_CRITICAL_THRESHOLD); +$thermal_sensors_widget_coreWarningTempThreshold = getThresholdValueFromConfig($config, "thermal_sensors_widget_core_warning_threshold", DEFAULT_WARNING_THRESHOLD); +$thermal_sensors_widget_coreCriticalTempThreshold = getThresholdValueFromConfig($config, "thermal_sensors_widget_core_critical_threshold", DEFAULT_CRITICAL_THRESHOLD); + +//get display settings from config (apply defaults if missing) +$thermal_sensors_widget_showRawOutput = getBoolValueFromConfig($config, "thermal_sensors_widget_show_raw_output", false); +$thermal_sensors_widget_showFullSensorName = getBoolValueFromConfig($config, "thermal_sensors_widget_show_full_sensor_name", false); +$thermal_sensors_widget_pulsateWarning = getBoolValueFromConfig($config, "thermal_sensors_widget_pulsate_warning", true); +$thermal_sensors_widget_pulsateCritical = getBoolValueFromConfig($config, "thermal_sensors_widget_pulsate_critical", true); + +function getThresholdValueFromConfig(&$configArray, $valueKey, $defaultValue) { + + $thresholdValue = $defaultValue; + + if (isset($configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey])) { + $thresholdValue = (int) $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey]; + } + + if ($thresholdValue < MIN_THRESHOLD_VALUE || $thresholdValue > MAX_THRESHOLD_VALUE) { + //set to default if not in allowed range + $thresholdValue = $defaultValue; + } + return $thresholdValue; +} + +function getBoolValueFromConfig(&$configArray, $valueKey, $defaultValue) { + + $boolValue = false; + + if (isset($configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey])) { + $boolValue = (bool) $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey]; + } else { + //set to default if not in allowed range + $boolValue = $defaultValue; + } + return $boolValue; +} + +//========================================================================= +?> + + + + + + + + + +
+
+ (Updating...)

+
+
+ + +