Last active
December 21, 2015 06:09
-
-
Save bacall213/6262094 to your computer and use it in GitHub Desktop.
Ninja Temperature/Humidity BETA Dashboard Widget [2W x 1H] [Author: Brian Call] [License: MIT]
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": "Temperature/Humidity", | |
"deviceMap": [ | |
{ "deviceId": 31, "vendor": 0, "minimum": 1, "maximum": 1 }, | |
{ "deviceId": 30, "vendor": 0, "minimum": 1, "maximum": 1 } | |
], | |
"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 column styling */ | |
.column { | |
width: 50%; | |
height: 100%; | |
top: 0%; | |
position: relative; | |
float: left; | |
background: white; | |
} | |
/* Left-side label styling (e.g. "Temperature") */ | |
.labelleft { | |
position: absolute; | |
top: 80px; | |
width: 100%; | |
text-align: center; | |
color: rgba(0,0,0,0.3); | |
} | |
/* Left-side value styling */ | |
.valueleft { | |
position: absolute; | |
top: 45px; | |
width: 100%; | |
text-align: center; | |
font-size: 45px; | |
font-weight: bold; | |
left: 28px; | |
.unitsleft { | |
font-size: 14px; | |
font-weight: normal; | |
vertical-align: super; | |
position: relative; | |
top: -10px; | |
} | |
.hivaltextleft { | |
position: relative; | |
display: inline-block; | |
color: hsl(20,75%,65%); | |
font-weight: bold; | |
font-size: 10px; | |
width: 50px; | |
top: -15px; | |
left: -28px; | |
text-align: left; | |
} | |
.lovaltextleft { | |
position: relative; | |
display: inline-block; | |
color: hsl(203,60%,56%); | |
font-weight: bold; | |
font-size: 10px; | |
width: 50px; | |
top: -33px; | |
left: 49px; | |
text-align: left; | |
} | |
} | |
/* Right-side label styling (e.g. "Humidity") */ | |
.labelright { | |
position: absolute; | |
top: 80px; | |
width: 100%; | |
text-align: center; | |
color: rgba(0,0,0,0.3); | |
} | |
/* Right-side value styling */ | |
.valueright { | |
position: absolute; | |
top: 45px; | |
width: 100%; | |
text-align: center; | |
font-size: 45px; | |
font-weight: bold; | |
left: 58px; | |
.unitsright { | |
font-size: 14px; | |
font-weight: normal; | |
vertical-align: super; | |
position: relative; | |
top: -10px; | |
} | |
.hivaltextright { | |
position: relative; | |
display: inline-block; | |
color: hsl(20,75%,65%); | |
font-weight: bold; | |
font-size: 10px; | |
width: 50px; | |
top: -15px; | |
left: -26px; | |
text-align: left; | |
} | |
.lovaltextright { | |
position: relative; | |
display: inline-block; | |
color: hsl(203,60%,56%); | |
font-weight: bold; | |
font-size: 10px; | |
width: 50px; | |
top: -4px; | |
left: -89px; | |
text-align: left; | |
} | |
} | |
/* Sparkline styling */ | |
.sparkline { | |
position: relative; | |
top: 105px; | |
width: 90%; | |
height: 85px; | |
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: 30px; | |
} | |
} | |
/* Left-side text color */ | |
.sensorleft { | |
color: hsl(45,100%,45%); | |
} | |
/* Right-side text color */ | |
.sensorright { | |
color: hsl(203,60%,56%); | |
} |
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="sensorleft column"> | |
<div class="labelleft">Temperature</div> | |
<div class="valueleft"> | |
<span class="text"></span> | |
<sup class="unitsleft">°F</sup> | |
<span class="hivaltextleft"></span> | |
<span class="lovaltextleft"></span> | |
</div> | |
<div class="sparkline"></div> | |
</div> | |
<div class="sensorright column"> | |
<div class="labelright">Humidity</div> | |
<div class="valueright"> | |
<span class="text"></span> | |
<sup class="unitsright">%</sup> | |
<span class="hivaltextright"></span> | |
<span class="lovaltextright"></span> | |
</div> | |
<div class="sparkline"></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
/* Define the sparkline sensor graphs */ | |
var sparkSensorRight = element.find(".sensorright .sparkline"); | |
var sparkSensorLeft = element.find(".sensorleft .sparkline"); | |
/* Values from the sensors will be stored in these arrays */ | |
var dataSensorRight = []; | |
var dataSensorRightTimestamps = []; | |
var dataSensorLeft = []; | |
var dataSensorLeftTimestamps = []; | |
/* | |
Set celsius/fahrenheit - | |
F = Fahrenheit | |
C = Celsius | |
*/ | |
var temperatureType = "F"; | |
/* | |
Sparkline (graph) styling options - | |
chartRangeMinX: Defines the min number of points on the X-axis. This helps set the scale. | |
chartRanageMaxX: Defines the max number of points on the X-axis | |
e.g. 1440 updates = 24 hr/day * 60 min/hr | |
This assumes a data refresh of 1 minute | |
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. | |
*/ | |
var sparklineOptionsSensorLeft = { | |
width: '100%', | |
height: '85px', | |
chartRangeMinX: 0, | |
chartRangeMaxX: 100, | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Temperature: ', | |
tooltipSuffix: '°F', | |
fillColor: null, | |
lineColor: 'hsl(45,100%,45%)', | |
//tooltipFormat: '<span style="color: {{color}}">●</span> {{prefix}}{{y}}{{suffix}}' | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataSensorLeftTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
var sparklineOptionsSensorRight = { | |
width: '100%', | |
height: '85px', | |
chartRangeMinX: 0, | |
chartRangeMaxX: 100, | |
chartRangeMin: 0, // Minimum Y-axis value, 0 < humidity < 100 | |
chartRangeMax: 100, // Maximum Y-axis value, 0 < humidity < 100 | |
drawNormalOnTop: false, | |
tooltipPrefix: ' Humidity: ', | |
tooltipSuffix: '%', | |
fillColor: null, | |
lineColor: 'hsl(203,60%,56%)', | |
//tooltipFormat: '<span style="color: {{color}}">●</span> {{prefix}}{{y}}{{suffix}}' | |
tooltipFormatter: function(sparkline, options, fields) { | |
return '<div class="jsqfield"><span style="color: ' + fields.color + '">●</span>' + options.get('tooltipPrefix') + fields.y + options.get('tooltipSuffix') + ' @ ' + dataSensorRightTimestamps[fields.x] + '</div>'; | |
} | |
}; | |
// 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; | |
}; | |
// 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; | |
}; | |
/* Push values to the right-side sensor display */ | |
function SetSensorRight(value, timestamp) { | |
/* Update value */ | |
element.find(".sensorright .valueright .text").html(value); | |
/* Update graph */ | |
dataSensorRight.push(value); | |
dataSensorRightTimestamps.push(sensor_timestamp(timestamp)); | |
sparkSensorRight.sparkline(dataSensorRight, sparklineOptionsSensorRight); | |
/* Update high/low values */ | |
element.find(".sensorright .valueright .hivaltextright").html("HI: " + Math.max.apply(null, dataSensorRight)); | |
element.find(".sensorright .valueright .lovaltextright").html("LO: " + Math.min.apply(null, dataSensorRight)); | |
}; | |
/* Push values to the left-side sensor display */ | |
function SetSensorLeft(value, timestamp) { | |
/* Update value */ | |
element.find(".sensorleft .valueleft .text").html(value); | |
/* Update data array for graph */ | |
dataSensorLeft.push(value); | |
dataSensorLeftTimestamps.push(sensor_timestamp(timestamp)); | |
/* Update graph */ | |
sparkSensorLeft.sparkline(dataSensorLeft, sparklineOptionsSensorLeft); | |
/* Update high/low values */ | |
element.find(".sensorleft .valueleft .hivaltextleft").html("HI: " + Math.max.apply(null, dataSensorLeft)); | |
element.find(".sensorleft .valueleft .lovaltextleft").html("LO: " + Math.min.apply(null, dataSensorLeft)); | |
}; | |
/* 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) { | |
SetSensorRight(data.DA, data.timestamp); | |
}; | |
/* Device ID 31 = 433 MHz temperature sensor */ | |
if (data.D === 31) { | |
if (temperatureType === "F") { | |
/* Convert to fahrenheit */ | |
F = (data.DA * 9 / 5 + 32).toFixed(2); | |
SetSensorLeft(F, data.timestamp); | |
} | |
else if (temperatureType === "C") { | |
/* Celsius */ | |
SetSensorLeft(data.DA, data.timestamp) | |
} | |
else { | |
/* Assume fahrenheit - but this should never be reached */ | |
/* Convert to fahrenheit */ | |
F = (data.DA * 9 / 5 + 32).toFixed(2); | |
SetSensorLeft(F, data.timestamp); | |
}; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment