Last active
December 24, 2015 07:39
-
-
Save bacall213/6765303 to your computer and use it in GitHub Desktop.
[STABLE] Ninjablock Universal Widget - Reconfigurable for upload/download/temperature/humidity just by changing a couple variables. Value display spacing and sparkline options are adjusted per the data type being displayed. [NOTE: This widget does not support two of the same device types at the same time (e.g. two temperature displays, two downl…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
return { | |
"name": "Universal Widget (1x1)", | |
"deviceMap": [ | |
{ "deviceId": 31, "vendor": 0, "minimum": 1, "maximum": 1 }, //Temperature | |
{ "deviceId": 30, "vendor": 0, "minimum": 1, "maximum": 1 }, //Humidity | |
{ "deviceId": [530,531,532,533], "minimum": 1, "maximum": 1}, //Network In | |
{ "deviceId": [540,541,542,543], "minimum": 1, "maximum": 1}, //Network Out | |
{ "deviceId": 2000, "minimum": 1, "maximum": 2} //Sandbox | |
], | |
"forceDeviceMapGroup": true | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* General styling */ | |
background: white; | |
/* Left column styling */ | |
.leftColumn { | |
width: 50%; | |
height: 100%; | |
top: 0%; | |
position: relative; | |
float: left; | |
background: white; | |
} | |
/* Right column styling */ | |
.rightColumn { | |
width: 50%; | |
height: 100%; | |
top: 0%; | |
position: relative; | |
float: left; | |
background: white; | |
} | |
/* Left-side label styling (e.g. "Temperature") */ | |
.leftLabel { | |
position: absolute; | |
top: 95px; | |
width: 100%; | |
text-align: center; | |
color: rgba(0,0,0,0.3); | |
font-size: 1.1em; | |
font-variant:small-caps; | |
font-weight: bold; | |
} | |
/* Left-side value styling */ | |
.leftValue { | |
position: absolute; | |
top: 40px; | |
width: 100%; | |
text-align: left; | |
font-size: 35px; | |
font-weight: bold; | |
left: 18px; | |
color: hsl(45,100%,45%); | |
.leftUnits { | |
font-size: 14px; | |
font-weight: normal; | |
vertical-align: super; | |
position: relative; | |
top: -5px; | |
left: -8px; | |
} | |
.leftHiValText { | |
position: relative; | |
display: block; | |
color: hsl(20,75%,65%); | |
font-weight: bold; | |
font-size: 10px; | |
width: 50px; | |
top: 4px; | |
line-height: 15px; | |
text-align: left; | |
} | |
.leftLoValText { | |
position: relative; | |
display: block; | |
color: hsl(203,60%,56%); | |
font-weight: bold; | |
font-size: 10px; | |
width: 50px; | |
top: 0px; | |
line-height: 15px; | |
text-align: left; | |
} | |
} | |
/* Right-side label styling (e.g. "Humidity") */ | |
.rightLabel { | |
position: absolute; | |
top: 95px; | |
width: 100%; | |
text-align: center; | |
color: rgba(0,0,0,0.3); | |
font-size: 1.1em; | |
font-variant:small-caps; | |
font-weight: bold; | |
} | |
/* Right-side value styling */ | |
.rightValue { | |
position: absolute; | |
top: 40px; | |
width: 100%; | |
text-align: left; | |
font-size: 35px; | |
font-weight: bold; | |
left: 45px; | |
color: hsl(203,60%,56%); | |
.rightUnits { | |
font-size: 14px; | |
font-weight: normal; | |
vertical-align: super; | |
position: relative; | |
top: -5px; | |
left: -8px; | |
} | |
.rightHiValText { | |
position: relative; | |
display: block; | |
color: hsl(20,75%,65%); | |
font-weight: bold; | |
font-size: 10px; | |
width: 50px; | |
top: 4px; | |
line-height: 15px; | |
text-align: left; | |
} | |
.rightLoValText { | |
position: relative; | |
display: block; | |
color: hsl(203,60%,56%); | |
font-weight: bold; | |
font-size: 10px; | |
width: 50px; | |
top: 0px; | |
line-height: 15px; | |
text-align: left; | |
} | |
} | |
/* Left-side sparkline styling */ | |
.leftSparkline { | |
position: relative; | |
top: 120px; | |
width: 90%; | |
height: 80px; | |
margin-left: auto; | |
margin-right: auto; | |
line-height: 30px; | |
border: 1px solid hsl(0,0%,90%); | |
background: hsl(0,0%,95%); | |
canvas { | |
width: 100%; | |
height: 80px; | |
} | |
} | |
/* Right-side sparkline styling */ | |
.rightSparkline { | |
position: relative; | |
top: 120px; | |
width: 90%; | |
height: 80px; | |
margin-left: auto; | |
margin-right: auto; | |
line-height: 30px; | |
border: 1px solid hsl(0,0%,90%); | |
background: hsl(0,0%,95%); | |
canvas { | |
width: 100%; | |
height: 80px; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="leftColumn"> | |
<div class="leftLabel"></div> | |
<div class="leftValue"> | |
<span class="text"></span> | |
<sup class="leftUnits"></sup> | |
<span class="leftHiValText"></span> | |
<span class="leftLoValText"></span> | |
</div> | |
<div class="leftSparkline"></div> | |
</div> | |
<div class="rightColumn"> | |
<div class="rightLabel"></div> | |
<div class="rightValue"> | |
<span class="text"></span> | |
<sup class="rightUnits"></sup> | |
<span class="rightHiValText"></span> | |
<span class="rightLoValText"></span> | |
</div> | |
<div class="rightSparkline"></div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* UNIVERSAL WIDGET */ | |
/* Define the sparkline sensor graphs */ | |
var sparkRightSensor = element.find(".rightSparkline"); | |
var sparkLeftSensor = element.find(".leftSparkline"); | |
/* Identify key elements for various uses */ | |
var rightSensorHiText = element.find(".rightColumn .rightValue .rightHiValText"); | |
var rightSensorLoText = element.find(".rightColumn .rightValue .rightLoValText"); | |
var leftSensorHiText = element.find(".leftColumn .leftValue .leftHiValText"); | |
var leftSensorLoText = element.find(".leftColumn .leftValue .leftLoValText"); | |
/** | |
* Opentip: Options | |
*/ | |
Opentip.styles.normalToolTip = { | |
"extends": "standard", | |
stem: true, | |
tipJoint: "bottom", | |
showOn: "mouseover", | |
borderRadius: 0, | |
borderWidth: 1, | |
borderColor: "#FFFFFF", | |
showEffect: "appear", | |
hideEffect: "appear", | |
showEffectDuration: 0.0, | |
hideEffectDuration: 0.0, | |
stemBase: 10, | |
stemLength: 5, | |
background: "rgba(0,0,0,0.6)", | |
removeElementsOnHide: true, | |
offset: [0, 15], | |
escapeContent: false | |
}; | |
/** | |
* Opentip: Creation | |
*/ | |
//var ELEMENT_NAME = element.find("#ELEMENT_NAME"); | |
//var TIP_NAME = new Opentip(TARGET_ELEMENT_NAME, { style: "TIP_STYLE" }); | |
var opentipRightSensorHiText = new Opentip(rightSensorHiText, { style: "normalToolTip" }); | |
var opentipRightSensorLoText = new Opentip(rightSensorLoText, { style: "normalToolTip" }); | |
var opentipLeftSensorHiText = new Opentip(leftSensorHiText, { style: "normalToolTip" }); | |
var opentipLeftSensorLoText = new Opentip(leftSensorLoText, { style: "normalToolTip" }); | |
/* Values from the sensors will be stored in these arrays */ | |
var dataRightSensor = []; | |
var dataRightSensorTimestamps = []; | |
var dataRightSensorUnits = ""; | |
var dataRightSensorHiLo = ({ | |
"high": -1, | |
"highTime": "", | |
"low": 999, | |
"lowTime": "" | |
}); | |
var dataLeftSensor = []; | |
var dataLeftSensorTimestamps = []; | |
var dataLeftSensorUnits = ""; | |
var dataLeftSensorHiLo = ({ | |
"high": -1, | |
"highTime": "", | |
"low": 999, | |
"lowTime": "" | |
}); | |
/* Limit the array lengths to keep the graphs looking neat */ | |
var maxArrayLen = 200; | |
/* Graph and sensor value colors */ | |
var colorLeftSensor = "hsl(45,100%,45%)"; | |
var colorRightSensor = "hsl(203,60%,56%)"; | |
/* Settings for the widget title */ | |
var customWidgetTitle = "false"; // Set this to anything but "false" to use your own title | |
var widgetTitleLeft = ""; // This variable will house the automatically generated title for the left widget | |
var widgetTitleRight = ""; // This variable will house the automatically generated title for the right widget | |
/* | |
* Set celsius/fahrenheit - | |
* F = Fahrenheit | |
* C = Celsius | |
* | |
* NOTE: Used only when a sensor type is set to "Temp" | |
*/ | |
var temperatureType = "F"; | |
/* | |
* Define your sensor types - | |
* Allows logic in onData() to do some of the work for you | |
* | |
* Allowable sensor types: | |
* 1) "Temp" = Temperature | |
* NOTE: Set "temperatureType" to "F" or "C" to your preference | |
* 2) "Humidity" = Humidity | |
* 3) "NetworkIn" = Network In (Download) | |
* 4) "NetworkOut" = Network Out (Upload) | |
* 5) "SENSOR_TYPE" = SENSOR_DESCRIPTION | |
*/ | |
var sensorTypeLeft = "NetworkIn"; | |
var sensorTypeRight = "NetworkOut"; | |
// Convert timestamp provided by driver | |
function sensor_timestamp(timestamp) { | |
var localTime = new Date(timestamp); | |
var month = localTime.getMonth() + 1; // Month is 0-11, add 1 to make it 1-12 | |
var day = localTime.getDate(); | |
var year = localTime.getFullYear(); | |
var hours = localTime.getHours(); | |
var minutes = localTime.getMinutes(); | |
var seconds = localTime.getSeconds(); | |
// Months are 1-12, so add "0" in front of 1-9 to conform with ISO 8601 | |
if (month < 10) { | |
month = "0" + month; | |
}; | |
// Days are 1-31, so add "0" in front of 1-9 to conform with ISO 8601 | |
if (day < 10) { | |
day = "0" + day; | |
}; | |
// Seconds are returned 0-59, so add a "0" at the front if 0-9 | |
if (seconds < 10) { | |
seconds = "0" + seconds; | |
}; | |
// Minutes are returns 0-59, so add a "0" at the front if 0-9 | |
if (minutes < 10) { | |
minutes = "0" + minutes; | |
}; | |
// Hours are returned 0-23, so add a "0" at the front if 0-9 | |
if (hours < 10) { | |
hours = "0" + hours; | |
}; | |
// Put it together - type 1 = YYYY-MM-DD hh:mm:ss | |
var timestamp_type1 = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; | |
// Put it together - type 2 = hh:mm:ss (YYY-MM-DD) | |
var timestamp_type2 = hours + ":" + minutes + ":" + seconds + " (" + year + "-" + month + "-" + day + ")"; | |
// Put it together - type 3 = hh:mm:ss YYY-MM-DD | |
var timestamp_type3 = hours + ":" + minutes + ":" + seconds + " " + year + "-" + month + "-" + day; | |
// Return timestamp for whatever purpose it's needed for | |
return timestamp_type2; | |
}; | |
/* | |
Sparkline (graph) styling options - | |
chartRangeMin: Defines the min value for the Y-axis. Undefined on purpose. | |
chartRangeMax: Defines the max on the Y-axis. Undefined on purpose. | |
Humidity should be <= 100% | |
Fahrenheit: 0 - 150 | |
Celsius: -17 ~ 65 | |
Defining a min/max would require tweaking the range for celsius/fahrenheit. | |
Let's just not set min/max Y-axis values. | |
width: Width of the graph data within the "canvas" - | |
This should be 100% unless you're going with a different style. | |
height: Height of the graph data within the "canvas" - | |
This should match the .sparkline "height" variable in the widget CSS. | |
*/ | |
/* | |
* Left sensor definitions (sensorTypeLeft) - | |
* Sparkline styling | |
* Set units | |
* Set labels | |
*/ | |
switch (sensorTypeLeft) { | |
case "Temp": | |
var sparklineOptionsLeftSensor = { | |
width: '100%', | |
height: '80px', | |
chartRangeMinX: 0, //X-axis min value = 0 | |
chartRangeMaxX: 100, //X-axis max value = 100 | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Temperature: ', | |
tooltipSuffix: '°F', | |
fillColor: null, | |
lineColor: colorLeftSensor, | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataLeftSensorTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
/* Adjust side-specific spacing */ | |
element.find(".leftValue").css({"left":"18px"}); | |
/* Set label for left sensor */ | |
element.find(".leftColumn .leftLabel").html("Temperature"); | |
if (temperatureType == "F") { | |
/* Set units for left sensor */ | |
dataLeftSensorUnits = "°F"; | |
element.find(".leftColumn .leftUnits").html(dataLeftSensorUnits); | |
/* Set Sparkline tooltip suffix */ | |
sparklineOptionsLeftSensor.tooltipSuffix = dataLeftSensorUnits; | |
} else if (temperatureType == "C") { | |
/* Set units for left sensor */ | |
dataLeftSensorUnits = "°C"; | |
element.find(".leftColumn .leftUnits").html(dataLeftSensorUnits); | |
/* Set Sparkline tooltip suffix */ | |
sparklineOptionsLeftSensor.tooltipSuffix = dataLeftSensorUnits; | |
}; | |
/* Set part of the widget title */ | |
widgetTitleLeft = "Temperature"; | |
/* END: Left sensor, case "Temp" */ | |
break; | |
case "Humidity": | |
var sparklineOptionsLeftSensor = { | |
width: '100%', | |
height: '80px', | |
chartRangeMinX: 0, //X-axis min value = 0 | |
chartRangeMaxX: 100, //X-axis max value = 100 | |
chartRangeMin: 0, //Y-axis min value = 0 | |
chartRangeMax: 100, //Y-axis max value = 100 (useful for humidity) | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Humidity: ', | |
tooltipSuffix: '%', | |
fillColor: null, | |
lineColor: colorLeftSensor, | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataLeftSensorTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
/* Adjust side-specific spacing */ | |
element.find(".leftValue").css({"left":"42px"}); | |
/* Set label for left sensor */ | |
element.find(".leftColumn .leftLabel").html("Humidity"); | |
/* Set units for left sensor */ | |
dataLeftSensorUnits = "%"; | |
element.find(".leftColumn .leftUnits").html("%"); | |
/* Set part of the widget title */ | |
widgetTitleLeft = "Humidity"; | |
/* END: Left sensor, case "Humidity" */ | |
break; | |
case "NetworkIn": | |
var sparklineOptionsLeftSensor = { | |
width: '100%', | |
height: '80px', | |
chartRangeMinX: 0, //X-axis min value = 0 | |
chartRangeMaxX: 100, //X-axis max value = 100 | |
chartRangeMin: 0, //Y-axis min value = 0 | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Download: ', | |
tooltipSuffix: ' Kbps', | |
fillColor: null, | |
lineColor: colorLeftSensor, | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataLeftSensorTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
/* Adjust side-specific spacing */ | |
element.find(".leftValue").css({"left":"40px"}); | |
/* Set label for left sensor */ | |
element.find(".leftColumn .leftLabel").html("Download"); | |
/* Set units for left sensor */ | |
dataLeftSensorUnits = " Kbps"; | |
element.find(".leftColumn .leftUnits").html(dataLeftSensorUnits); | |
/* Determine the NIC in use from one of the ninja-netmon drivers - | |
* 1) Grab the short name for the first device | |
* Example: "Net@ninjablock (wlan0|Tx)" | |
* 2) Break the short name up based on a space | |
* Example: "Net@ninjablock (wlan0|Tx)" => "Net@ninjablock" & "(wlan|Tx)" | |
* 3) Now remove the extra parenthesis | |
* Example: "(wlan0|Tx)" => "wlan0|Tx)" | |
* 4) Grab just the NIC in use | |
* Example: "wlan0|Tx)" => "wlan0" | |
* 5) Set the title to the interface value parsed from the title | |
* Example: scope.Widget.settings.name = "<insert title here>" | |
*/ | |
var widgetShortName = _.find(scope.Widget.devices, function(device) { return true; }).shortName; | |
var widgetNIC = widgetShortName.split(' '); | |
var widgetNIC = widgetNIC[1].split('('); | |
var widgetNIC = widgetNIC[1].split('|'); | |
var widgetNIC = widgetNIC[0]; | |
/* If the other sensor is also network, use a custom title to prevent a title like "Net (wlan0) & Net (wlan0)" */ | |
if (sensorTypeRight == "NetworkOut") { | |
customWidgetTitle = "Network (" + widgetNIC + ")"; | |
} else { | |
widgetTitleLeft = "Net (" + widgetNIC + ")"; | |
}; | |
/* END: Left sensor, case "NetworkIn" */ | |
break; | |
case "NetworkOut": | |
var sparklineOptionsLeftSensor = { | |
width: '100%', | |
height: '80px', | |
chartRangeMinX: 0, //X-axis min value = 0 | |
chartRangeMaxX: 100, //X-axis max value = 100 | |
chartRangeMin: 0, //Y-axis min value = 0 | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Upload: ', | |
tooltipSuffix: ' Kbps', | |
fillColor: null, | |
lineColor: colorLeftSensor, | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataLeftSensorTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
/* Adjust side-specific spacing */ | |
element.find(".leftValue").css({"left":"40px"}); | |
/* Set label for left sensor */ | |
element.find(".leftColumn .leftLabel").html("Upload"); | |
/* Set units for left sensor */ | |
dataLeftSensorUnits = " Kbps"; | |
element.find(".leftColumn .leftUnits").html(dataLeftSensorUnits); | |
/* Determine the NIC in use from one of the ninja-netmon drivers - | |
* 1) Grab the short name for the first device | |
* Example: "Net@ninjablock (wlan0|Tx)" | |
* 2) Break the short name up based on a space | |
* Example: "Net@ninjablock (wlan0|Tx)" => "Net@ninjablock" & "(wlan|Tx)" | |
* 3) Now remove the extra parenthesis | |
* Example: "(wlan0|Tx)" => "wlan0|Tx)" | |
* 4) Grab just the NIC in use | |
* Example: "wlan0|Tx)" => "wlan0" | |
* 5) Set the title to the interface value parsed from the title | |
* Example: scope.Widget.settings.name = "<insert title here>" | |
*/ | |
var widgetShortName = _.find(scope.Widget.devices, function(device) { return true; }).shortName; | |
var widgetNIC = widgetShortName.split(' '); | |
var widgetNIC = widgetNIC[1].split('('); | |
var widgetNIC = widgetNIC[1].split('|'); | |
var widgetNIC = widgetNIC[0]; | |
/* If the other sensor is also network, use a custom title to prevent a title like "Net (wlan0) & Net (wlan0)" */ | |
if (sensorTypeRight == "NetworkIn") { | |
customWidgetTitle = "Network (" + widgetNIC + ")"; | |
} else { | |
widgetTitleLeft = "Net (" + widgetNIC + ")"; | |
}; | |
/* END: Left sensor, case "NetworkOut" */ | |
break; | |
}; | |
/* | |
* Right sensor definitions (sensorTypeRight) - | |
* Sparkline styling | |
* Set units | |
* Set labels | |
*/ | |
switch (sensorTypeRight) { | |
case "Temp": | |
var sparklineOptionsRightSensor = { | |
width: '100%', | |
height: '80px', | |
chartRangeMinX: 0, //X-axis min value = 0 | |
chartRangeMaxX: 100, //X-axis max value = 100 | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Temperature: ', | |
tooltipSuffix: '°F', | |
fillColor: null, | |
lineColor: colorRightSensor, | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataRightSensorTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
/* Adjust side-specific spacing */ | |
element.find(".rightValue").css({"left":"16px"}); | |
/* Set label for left sensor */ | |
element.find(".rightColumn .rightLabel").html("Temperature"); | |
if (temperatureType == "F") { | |
/* Set units for left sensor */ | |
dataRightSensorUnits = "°F"; | |
element.find(".rightColumn .rightUnits").html(dataRightSensorUnits); | |
/* Set Sparkline tooltip suffix */ | |
sparklineOptionsRightSensor.tooltipSuffix = dataRightSensorUnits; | |
} else if (temperatureType == "C") { | |
/* Set units for left sensor */ | |
dataRightSensorUnits = "°C"; | |
element.find(".rightColumn .rightUnits").html(dataRightSensorUnits); | |
/* Set Sparkline tooltip suffix */ | |
sparklineOptionsRightSensor.tooltipSuffix = dataRightSensorUnits; | |
}; | |
/* Set part of the widget title */ | |
widgetTitleRight = "Temperature"; | |
/* END: Right sensor, case "Temp" */ | |
break; | |
case "Humidity": | |
var sparklineOptionsRightSensor = { | |
width: '100%', | |
height: '80px', | |
chartRangeMinX: 0, //X-axis min value = 0 | |
chartRangeMaxX: 100, //X-axis max value = 100 | |
chartRangeMin: 0, //Y-axis min value = 0 | |
chartRangeMax: 100, //Y-axis max value = 100 (useful for humidity) | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Humidity: ', | |
tooltipSuffix: '%', | |
fillColor: null, | |
lineColor: colorRightSensor, | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataRightSensorTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
/* Adjust side-specific spacing */ | |
element.find(".rightValue").css({"left":"45px"}); | |
/* Set label for right sensor */ | |
element.find(".rightColumn .rightLabel").html("Humidity"); | |
/* Set units for right sensor */ | |
dataRightSensorUnits = "%"; | |
element.find(".rightColumn .rightUnits").html(dataRightSensorUnits); | |
/* Set part of the widget title */ | |
widgetTitleRight = "Humidity"; | |
/* END: Right sensor, case "Humidity" */ | |
break; | |
case "NetworkIn": | |
var sparklineOptionsRightSensor = { | |
width: '100%', | |
height: '80px', | |
chartRangeMinX: 0, //X-axis min value = 0 | |
chartRangeMaxX: 100, //X-axis max value = 100 | |
chartRangeMin: 0, //Y-axis min value = 0 | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Download: ', | |
tooltipSuffix: ' Kbps', | |
fillColor: null, | |
lineColor: colorRightSensor, | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataRightSensorTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
/* Adjust side-specific spacing */ | |
element.find(".rightValue").css({"left":"40px"}); | |
/* Set label for right sensor */ | |
element.find(".rightColumn .rightLabel").html("Download"); | |
/* Set units for right sensor */ | |
dataRightSensorUnits = " Kbps"; | |
element.find(".rightColumn .rightUnits").html(dataRightSensorUnits); | |
/* Determine the NIC in use from one of the ninja-netmon drivers - | |
* 1) Grab the short name for the first device | |
* Example: "Net@ninjablock (wlan0|Tx)" | |
* 2) Break the short name up based on a space | |
* Example: "Net@ninjablock (wlan0|Tx)" => "Net@ninjablock" & "(wlan|Tx)" | |
* 3) Now remove the extra parenthesis | |
* Example: "(wlan0|Tx)" => "wlan0|Tx)" | |
* 4) Grab just the NIC in use | |
* Example: "wlan0|Tx)" => "wlan0" | |
* 5) Set the title to the interface value parsed from the title | |
* Example: scope.Widget.settings.name = "<insert title here>" | |
*/ | |
var widgetShortName = _.find(scope.Widget.devices, function(device) { return true; }).shortName; | |
var widgetNIC = widgetShortName.split(' '); | |
var widgetNIC = widgetNIC[1].split('('); | |
var widgetNIC = widgetNIC[1].split('|'); | |
var widgetNIC = widgetNIC[0]; | |
/* If the other sensor is also network, use a custom title to prevent a title like "Net (wlan0) & Net (wlan0)" */ | |
if (sensorTypeLeft == "NetworkOut") { | |
customWidgetTitle = "Network (" + widgetNIC + ")"; | |
} else { | |
widgetTitleRight = "Net (" + widgetNIC + ")"; | |
}; | |
/* END: Right sensor, case "NetworkIn" */ | |
break; | |
case "NetworkOut": | |
var sparklineOptionsRightSensor = { | |
width: '100%', | |
height: '80px', | |
chartRangeMinX: 0, //X-axis min value = 0 | |
chartRangeMaxX: 100, //X-axis max value = 100 | |
chartRangeMin: 0, //Y-axis min value = 0 | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Upload: ', | |
tooltipSuffix: ' Kbps', | |
fillColor: null, | |
lineColor: colorRightSensor, | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataRightSensorTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
/* Adjust side-specific spacing */ | |
element.find(".rightValue").css({"left":"39px"}); | |
/* Set label for right sensor */ | |
element.find(".rightColumn .rightLabel").html("Upload"); | |
/* Set units for right sensor */ | |
dataRightSensorUnits = " Kbps"; | |
element.find(".rightColumn .rightUnits").html(dataRightSensorUnits); | |
/* Determine the NIC in use from one of the ninja-netmon drivers - | |
* 1) Grab the short name for the first device | |
* Example: "Net@ninjablock (wlan0|Tx)" | |
* 2) Break the short name up based on a space | |
* Example: "Net@ninjablock (wlan0|Tx)" => "Net@ninjablock" & "(wlan|Tx)" | |
* 3) Now remove the extra parenthesis | |
* Example: "(wlan0|Tx)" => "wlan0|Tx)" | |
* 4) Grab just the NIC in use | |
* Example: "wlan0|Tx)" => "wlan0" | |
* 5) Set the title to the interface value parsed from the title | |
* Example: scope.Widget.settings.name = "<insert title here>" | |
*/ | |
var widgetShortName = _.find(scope.Widget.devices, function(device) { return true; }).shortName; | |
var widgetNIC = widgetShortName.split(' '); | |
var widgetNIC = widgetNIC[1].split('('); | |
var widgetNIC = widgetNIC[1].split('|'); | |
var widgetNIC = widgetNIC[0]; | |
/* If the other sensor is also network, use a custom title to prevent a title like "Net (wlan0) & Net (wlan0)" */ | |
if (sensorTypeLeft == "NetworkIn") { | |
customWidgetTitle = "Network (" + widgetNIC + ")"; | |
} else { | |
widgetTitleRight = "Net (" + widgetNIC + ")"; | |
}; | |
/* END: Right sensor, case "NetworkOut" */ | |
break; | |
}; | |
/* Push values to the right-side sensor display */ | |
function SetRightSensor(value, timestamp) { | |
/* Update value */ | |
element.find(".rightColumn .rightValue .text").html(value); | |
/* Update data array for graph */ | |
dataRightSensor.push(value); | |
/* Update timestamp array */ | |
dataRightSensorTimestamps.push(sensor_timestamp(timestamp)); | |
// Check for new high value | |
if ( Math.max.apply(null, dataRightSensor) > dataRightSensorHiLo.high ) { | |
dataRightSensorHiLo.high = Math.max.apply(null, dataRightSensor); | |
dataRightSensorHiLo.highTime = timestamp; | |
}; | |
// Check for new low value | |
if ( Math.min.apply(null, dataRightSensor) < dataRightSensorHiLo.low ) { | |
dataRightSensorHiLo.low = Math.min.apply(null, dataRightSensor); | |
dataRightSensorHiLo.lowTime = timestamp; | |
}; | |
/* Update high/low values */ | |
rightSensorHiText.html("HI: " + dataRightSensorHiLo.high); | |
rightSensorLoText.html("LO: " + dataRightSensorHiLo.low); | |
/* Clean up the arrays */ | |
if (dataRightSensor.length > maxArrayLen || dataRightSensorTimestamps.length > maxArrayLen) { | |
dataRightSensor = dataRightSensor.slice(dataRightSensor.length - maxArrayLen,dataRightSensor.length); | |
dataRightSensorTimestamps = dataRightSensorTimestamps.slice(dataRightSensorTimestamps.length - maxArrayLen,dataRightSensorTimestamps.length); | |
}; | |
}; | |
/* Push values to the left-side sensor display */ | |
function SetLeftSensor(value, timestamp) { | |
/* Update value */ | |
element.find(".leftColumn .leftValue .text").html(value); | |
/* Update data array for graph */ | |
dataLeftSensor.push(value); | |
/* Update timestamp array */ | |
dataLeftSensorTimestamps.push(sensor_timestamp(timestamp)); | |
// Check for new high value | |
if ( Math.max.apply(null, dataLeftSensor) > dataLeftSensorHiLo.high ) { | |
dataLeftSensorHiLo.high = Math.max.apply(null, dataLeftSensor); | |
dataLeftSensorHiLo.highTime = timestamp; | |
}; | |
// Check for new low value | |
if ( Math.min.apply(null, dataLeftSensor) < dataLeftSensorHiLo.low ) { | |
dataLeftSensorHiLo.low = Math.min.apply(null, dataLeftSensor); | |
dataLeftSensorHiLo.lowTime = timestamp; | |
}; | |
/* Update high/low values */ | |
leftSensorHiText.html("HI: " + dataLeftSensorHiLo.high); | |
leftSensorLoText.html("LO: " + dataLeftSensorHiLo.low); | |
/* Clean up the arrays */ | |
if (dataLeftSensor.length > maxArrayLen || dataLeftSensorTimestamps.length > maxArrayLen) { | |
dataLeftSensor = dataLeftSensor.slice(dataLeftSensor.length - maxArrayLen,dataLeftSensor.length); | |
dataLeftSensorTimestamps = dataLeftSensorTimestamps.slice(dataLeftSensorTimestamps.length - maxArrayLen,dataLeftSensorTimestamps.length); | |
}; | |
}; | |
/* Activate our update functions only when new data is received */ | |
scope.onData = function(data) { | |
/* Device ID 30 = 433 MHz humidity sensor */ | |
if (data.D === 30) { | |
if (sensorTypeLeft == "Humidity") { | |
SetLeftSensor(data.DA, data.timestamp); | |
} else if (sensorTypeRight == "Humidity") { | |
SetRightSensor(data.DA, data.timestamp); | |
}; | |
}; | |
/* Device ID 31 = 433 MHz temperature sensor */ | |
if (data.D === 31) { | |
if (sensorTypeLeft == "Temp") { | |
if (temperatureType === "F") { | |
/* Convert to fahrenheit */ | |
F = (data.DA * 9 / 5 + 32).toFixed(2); | |
SetLeftSensor(F, data.timestamp); | |
} else if (temperatureType === "C") { | |
/* Celsius */ | |
SetLeftSensor(data.DA, data.timestamp) | |
}; | |
} else if (sensorTypeRight == "Temp") { | |
if (temperatureType === "F") { | |
/* Convert to fahrenheit */ | |
F = (data.DA * 9 / 5 + 32).toFixed(2); | |
SetRightSensor(F, data.timestamp); | |
} else if (temperatureType === "C") { | |
/* Celsius */ | |
SetRightSensor(data.DA, data.timestamp) | |
}; | |
}; | |
}; | |
/* Device ID 530-533 = Network In (Download) */ | |
if ((data.D >=530 && data.D <= 533) || (data.G == 3 && data.D == 2000)) { | |
/* Group ID 3 = Download, as defined in the ninja-netmon driver */ | |
if (sensorTypeLeft == "NetworkIn") { | |
SetLeftSensor(data.DA, data.timestamp); | |
} else if (sensorTypeRight == "NetworkIn") { | |
SetRightSensor(data.DA, data.timestamp); | |
}; | |
}; | |
/* Device ID 540-543 = Network Out (Upload) */ | |
if ((data.D >=540 && data.D <= 543) || (data.G == 4 && data.D == 2000)) { | |
/* Group ID 4 = Upload, as defined in the ninja-netmon driver */ | |
if (sensorTypeLeft == "NetworkOut") { | |
SetLeftSensor(data.DA, data.timestamp); | |
} else if (sensorTypeRight == "NetworkOut") { | |
SetRightSensor(data.DA, data.timestamp); | |
}; | |
}; | |
/* Draw both sparklines each time there's data */ | |
sparkLeftSensor.sparkline(dataLeftSensor, sparklineOptionsLeftSensor); | |
sparkRightSensor.sparkline(dataRightSensor, sparklineOptionsRightSensor); | |
}; | |
/** | |
* TOOLTIP CONTENT MOUSEOVER HANDLER: LEFT SENSOR - HIGH VALUE | |
*/ | |
leftSensorHiText.on("mouseover", function() { | |
// Set the cursor to an arrow ("default") | |
$(this).css("cursor", "default"); | |
/** | |
* Opentip: Define contents | |
*/ | |
opentipLeftSensorHiText.setContent('<span style="color: rgb(255,255,255); font-family: arial,sans-serif; font-size: 10px">' + | |
'HI: ' + | |
dataLeftSensorHiLo.high + | |
dataLeftSensorUnits + | |
' @ ' + | |
sensor_timestamp(dataLeftSensorHiLo.highTime) + | |
'</span>'); | |
}); | |
/** | |
* TOOLTIP CONTENT MOUSEOVER HANDLER: LEFT SENSOR - LOW VALUE | |
*/ | |
leftSensorLoText.on("mouseover", function() { | |
// Set the cursor to an arrow ("default") | |
$(this).css("cursor", "default"); | |
/** | |
* Opentip: Define contents | |
*/ | |
opentipLeftSensorLoText.setContent('<span style="color: rgb(255,255,255); font-family: arial,sans-serif; font-size: 10px">' + | |
'LO: ' + | |
dataLeftSensorHiLo.low + | |
dataLeftSensorUnits + | |
' @ ' + | |
sensor_timestamp(dataLeftSensorHiLo.lowTime) + | |
'</span>'); | |
}); | |
/** | |
* TOOLTIP CONTENT MOUSEOVER HANDLER: RIGHT SENSOR - HIGH VALUE | |
*/ | |
rightSensorHiText.on("mouseover", function() { | |
// Set the cursor to an arrow ("default") | |
$(this).css("cursor", "default"); | |
/** | |
* Opentip: Define contents | |
*/ | |
opentipRightSensorHiText.setContent('<span style="color: rgb(255,255,255); font-family: arial,sans-serif; font-size: 10px">' + | |
'HI: ' + | |
dataRightSensorHiLo.high + | |
dataRightSensorUnits + | |
' @ ' + | |
sensor_timestamp(dataRightSensorHiLo.highTime) + | |
'</span>'); | |
}); | |
/** | |
* TOOLTIP CONTENT MOUSEOVER HANDLER: RIGHT SENSOR - LOW VALUE | |
*/ | |
rightSensorLoText.on("mouseover", function() { | |
// Set the cursor to an arrow ("default") | |
$(this).css("cursor", "default"); | |
/** | |
* Opentip: Define contents | |
*/ | |
opentipRightSensorLoText.setContent('<span style="color: rgb(255,255,255); font-family: arial,sans-serif; font-size: 10px">' + | |
'LO: ' + | |
dataRightSensorHiLo.low + | |
dataRightSensorUnits + | |
' @ ' + | |
sensor_timestamp(dataRightSensorHiLo.lowTime) + | |
'</span>'); | |
}); | |
/* Set Widget title */ | |
if (customWidgetTitle == "false") { | |
scope.Widget.settings.name = widgetTitleLeft + " & " + widgetTitleRight; | |
} else { | |
scope.Widget.settings.name = customWidgetTitle; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment