This commit is contained in:
martind2000 2017-01-06 16:59:39 +00:00
parent 0d7099f22d
commit c9b90f2221
6 changed files with 530 additions and 52 deletions

384
app/css/ui.css Normal file
View File

@ -0,0 +1,384 @@
/* by ericftremblay.com */
body {
background: #d1d1d1;
height: 100%;
padding: 20px;
font: 13px/50px sans-serif;
color: #666;
-webkit-box-sizing: border-box;
}
h1 { font: 30px sans-serif; }
h3 { font: 1em sans-serif; color: #888; }
p { font: 12px/20px sans-serif; padding-bottom: 10px; }
input {
display: block;
margin: 0 0 20px 5px;
}
/* Toggle */
input[type="checkbox"] {
background-image: -webkit-linear-gradient(hsla(0,0%,0%,.1), hsla(0,0%,100%,.1)),
-webkit-linear-gradient(right, #b0c43c 50%, #999 50%);
background-size: 100% 100%, 200% 100%;
background-position: 0 0, 5px 0;
border-radius: 25px;
box-shadow: inset 0 1px 4px hsla(0,0%,0%,.5),
inset 0 0 10px hsla(0,0%,0%,.5),
0 0 0 1px hsla(0,0%,0%,.1),
0 -1px 2px 1px hsla(0,0%,0%,.25),
0 2px 2px 1px hsla(0,0%,100%,.5),
0 -2px 10px 2px hsla(0,0%,100%,.75),
0 2px 10px 2px hsla(0,0%,0%,.25);
cursor: pointer;
height: 30px;
padding-right: 10px;
position: relative;
width: 63px;
-webkit-appearance: none;
-webkit-transition: .15s;
}
input[type="checkbox"]:after {
background-color: #eee;
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,0%,.1));
box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,1),
inset 0 -1px 1px 1px hsla(0,0%,0%,.25),
0 1px 3px 1px hsla(0,0%,0%,.5),
0 0 2px hsla(0,0%,0%,.25);
content: '';
display: block;
height: 30px;
left: 0;
position: relative;
top: 0;
width: 30px;
border-radius: 100%;
}
input[type="checkbox"]:checked {
background-position: 0 0, 45px 0;
padding-left: 33px;
padding-right: 0;
}
input[type="checkbox"]:before {
color: #eee;
content: 'Off';
font: 12.5px/20px sans-serif;
height: 20px;
left: 33px;
letter-spacing: 1px;
position: absolute;
text-align: center;
top: 6px;
width: 20px;
text-shadow: 0 -1px 1px rgba(0,0,0,0.5);
}
input[type="checkbox"]:checked:before {
content: 'On';
left: 9px;
}
/* Slider */
input[type="range"] {
background-image: -webkit-linear-gradient(left, hsla(0,0%,100%,.1) 45%, transparent 45%),
-webkit-linear-gradient(hsla(0,0%,0%,.1), hsla(0,0%,100%,.1)),
-webkit-linear-gradient(left, #b0c43c, #f66);
background-size: 3px 3px, 100% 100%, 100% 100%;
border-radius: 25px;
box-shadow: inset 0 1px 4px hsla(0,0%,0%,.5),
inset 0 0 10px hsla(0,0%,0%,.5),
0 0 0 1px hsla(0,0%,0%,.1),
0 -1px 2px 1px hsla(0,0%,0%,.25),
0 2px 2px 1px hsla(0,0%,100%,.5),
0 -2px 10px 2px hsla(0,0%,100%,.75),
0 2px 10px 2px hsla(0,0%,0%,.25);
cursor: ew-resize;
height: 10px;
position: relative;
width: 250px;
-webkit-appearance: none;
-webkit-transition: .15s;
}
input[type="range"]::-webkit-slider-thumb {
background-color: #eee;
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,0%,.1));
border-radius: 25px;
box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,1),
inset 0 -1px 1px 1px hsla(0,0%,0%,.25),
0 1px 3px 1px hsla(0,0%,0%,.5),
0 0 2px hsla(0,0%,0%,.25);
content: '';
display: block;
height: 20px;
left: 0;
position: relative;
top: 0;
width: 20px;
-webkit-appearance: none;
}
/* Radio */
input[type="radio"] {
background-color: #ddd;
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,0%,.1));
border-radius: 100%;
box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,1),
inset 0 -1px 1px 1px hsla(0,0%,0%,.25),
0 1px 3px 1px hsla(0,0%,0%,.5),
0 0 2px hsla(0,0%,0%,.25);
cursor: pointer;
display: inline-block;
height: 20px;
margin-right: 15px;
position: relative;
width: 20px;
-webkit-appearance: none;
}
input[type="radio"]:after {
background-color: #666;
border-radius: 100%;
box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.4),
0 1px 1px hsla(0,0%,100%,.8);
content: '';
display: block;
height: 12px;
width: 12px;
left: 4px;
position: relative;
top: 4px;
}
input[type="radio"]:checked:after {
background-color: #b0c43c;
box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.4),
inset 0 2px 2px hsla(0,0%,100%,.4),
0 1px 1px hsla(0,0%,100%,.8),
0 0 2px 2px hsla(68,69%,76%,.4);
}
/* Input Text */
input[type="text"], input[type="password"] {
background: #eee;
background-size: 100% 100%, 200% 100%;
background-position: 0 0, 5px 0;
border-radius: 5px;
box-shadow: inset 0 1px 4px hsla(0,0%,0%,.1),
inset 0 0 10px hsla(0,0%,0%,.1),
0 0 0 1px hsla(0,0%,0%,.1),
0 -1px 2px 1px hsla(0,0%,0%,.25),
0 2px 2px 1px hsla(0,0%,100%,.5),
0 -2px 10px 2px hsla(0,0%,100%,.75),
0 2px 10px 2px hsla(0,0%,0%,.25);
cursor: pointer;
border: 0;
width: 200px;
padding: 10px 15px;
font: 13px/20px sans-serif;
color: #888;
position: relative;
-webkit-appearance: none;
-webkit-transition: .15s;
}
input[type="text"]:focus, input[type="password"]:focus {
background: #fff;
outline: 0 none;
}
/* Submit */
input[type="submit"] {
background-color: #eee;
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,0%,.1));
border-radius: 8px;
box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,1),
inset 0 -1px 1px 1px hsla(0,0%,0%,.25),
0 1px 3px 1px hsla(0,0%,0%,.25),
0 0 2px hsla(0,0%,0%,.25);
cursor: pointer;
display: inline-block;
padding: 10px 20px;
font: 15px/20px sans-serif;
color: #999;
border: 0;
position: relative;
-webkit-appearance: none;
}
input[type="submit"]:hover {
color: #666;
background-color: #fff;
}
input[type="submit"]:active {
color: #888;
background-color: #fff;
position: relative;
top: 2px;
box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,1),
inset 0 -1px 1px 1px hsla(0,0%,0%,.15),
0 1px 3px 1px hsla(0,0%,0%,.15)}
/* Scrollbar */
::-webkit-scrollbar {
-webkit-appearance: none;
width: 10px;
height: 10px;
background: #d1d1d1;
}
::-webkit-scrollbar-thumb {
background-color: #999;
border-radius: 25px;
}
/* Tabs */
.tabs {
position: relative;
margin: 40px auto;
width: 750px;
}
.tabs input[id*="tab"] {
position: absolute;
z-index: 1000;
width: 120px;
left: 0px;
top: 0px;
opacity: 0;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
cursor: pointer;
}
.tabs input[id*="tab"]#tab-2 {
left: 120px;
}
.tabs input[id*="tab"]#tab-3 {
left: 240px;
}
.tabs label {
background: -webkit-linear-gradient(bottom, #ededed 0%,#ddd 100%);
height: 40px;
width: 80px;
font: 16px/40px sans-serif;
position: relative;
padding: 0 20px;
float: left;
display: block;
margin: 0 2px 0 0;
color: #666;
text-align: center;
border-radius: 6px 6px 0 0;
box-shadow: 2px 0 1px rgba(0,0,0,0.1), -2px 0 2px rgba(0,0,0,0.1);
cursor: pointer;
}
.tabs label:after {
content: '';
background: #d1d1d1;
position: absolute;
bottom: -2px;
left: 0;
width: 100%;
height: 2px;
display: block;
}
.tabs input[id*="tab"]:hover + label {
background: #eee;
}
.tabs label:first-of-type {
z-index: 4;
box-shadow: 0 0 4px rgba(0,0,0,0.2);
}
.tab-label-2 {
z-index: 3;
}
.tab-label-3 {
z-index: 2;
}
.tabs input[id*="tab"]:checked + label {
background: -webkit-linear-gradient(top, #ededed 0%,#d1d1d1 100%);
z-index: 6;
}
.clear-shadow {
clear: both;
}
.content {
position: relative;
width: 100%;
height: 1px;
z-index: 5;
border-top: solid 1px #eee;
}
.content div {
position: absolute;
top: 0;
left: 0;
z-index: 1;
opacity: 0;
height: 350px;
width: 800px;
padding: 30px;
-webkit-transition: opacity linear 0.1s;
}
.tabs input.tab-selector-1[id*="tab"]:checked ~ .content .content-1,
.tabs input.tab-selector-2[id*="tab"]:checked ~ .content .content-2,
.tabs input.tab-selector-3[id*="tab"]:checked ~ .content .content-3{
z-index: 100;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: alpha(opacity=100);
opacity: 1;
-webkit-transition: opacity ease-out 0.2s 0.1s;
-moz-transition: opacity ease-out 0.2s 0.1s;
-o-transition: opacity ease-out 0.2s 0.1s;
-ms-transition: opacity ease-out 0.2s 0.1s;
transition: opacity ease-out 0.2s 0.1s;
}
/* Dropdown list */
select[name*="menu"] {
background: #eee;
border-radius: 5px;
cursor: pointer;
border: 0;
padding: 10px 15px;
font: 13px/20px sans-serif;
color: #888;
position: relative;
-webkit-appearance: none;
-webkit-transition: .15s;
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,0%,.1));
box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,.25),
inset 0 -1px 1px 1px hsla(0,0%,0%,.1),
0 1px 3px 1px hsla(0,0%,0%,.1),
0 0 2px hsla(0,0%,0%,.1);
}
select[name*="menu"]:focus {
background: #fff;
outline: 0 none;
}

View File

@ -10,14 +10,14 @@
*/
(function($) {
let TodayDataModel = Backbone.Model.extend({
/* let TodayDataModel = Backbone.Model.extend({
initialize: function () {
this.set('url', '/today/data');
console.log(this.get('url'));
//This.update();
}
});
});*/
const webSocketModel = new SOCKETMANAGER();

View File

@ -35,7 +35,7 @@ let Clock = Backbone.View.extend({
render: function () {
const now = this.model.get('now');
//var curTime = now.format('<span class="hour">{24hr}</span>{mm}');
const curTime = now.format('<span class="time">{24hr} {mm}</span>');
const curTime = now.format('<span class="time">{24hr}:{mm}</span>');
const curDate = now.format('{yyyy}-{MM}-{dd}');
if (this.prevTime !== curTime) {

View File

@ -5,72 +5,71 @@
* Time: 14:20
*
*/
var WeatherModel = Backbone.Model.extend({
initialize: function() {
this.set('url','https://api.darksky.net/forecast/9ad2a41d420f3cf4960571bb886f710c/' + this.get('lat').toString() + ',' + this.get('long').toString() + '?units=uk2&exclude=minutely,hourly,daily,alerts,flags');
let WeatherModel = Backbone.Model.extend({
initialize: function () {
this.set('url', 'https://api.darksky.net/forecast/9ad2a41d420f3cf4960571bb886f710c/' + this.get('lat').toString() + ',' + this.get('long').toString() + '?units=uk2&exclude=minutely,hourly,daily,alerts,flags');
console.log(this.get('url'));
// this.update();
// this.update();
},
update: function() {
update: function () {
this.getWeather();
var now = new Date;
var mod = 1800000 - (now.getTime() % 1800000);
var weatherTrigger = function() {
const now = new Date;
let mod = 1800000 - (now.getTime() % 1800000);
let weatherTrigger = function () {
this.update();
};
},
getWeather: function() {
var self = this;
getWeather: function () {
const self = this;
$.ajax({
type: 'GET',
url: self.get('url'),
data: '',
dataType: 'json',
timeout: 10000,
context: $('body'),
contentType: ('application/json'),
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
},
success: function(data) {
var stored = {
temperature: data.currently.temperature,
icon: data.currently.icon,
summary: data.currently.summary
};
self.set(stored);
},
error: function(xhr, type) {
console.error('ajax error');
console.error(xhr);
console.error(type);
}
});
type: 'GET',
url: self.get('url'),
data: '',
dataType: 'json',
timeout: 10000,
context: $('body'),
contentType: ('application/json'),
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
},
success: function (data) {
const stored = {
temperature: data.currently.temperature,
icon: data.currently.icon,
summary: data.currently.summary
};
self.set(stored);
},
error: function (xhr, type) {
console.error('ajax error');
console.error(xhr);
console.error(type);
}
});
}
});
var Weather = Backbone.View.extend({
let Weather = Backbone.View.extend({
tagName: 'div',
initialize: function() {
initialize: function () {
_.bindAll(this, 'render');
this.model.bind('change', this.render);
this.$weatherText = $('#weatherDescription');
this.$weatherTemp = $('#temp');
this.$weatherIcon = $('#weatherIcon');
},
render: function() {
render: function () {
console.log('Weather:Render');
var ws = '<i class="wi wi-forecast-io-' + this.model.get('icon') + '"></i>';
const ws = '<i class="wi wi-forecast-io-' + this.model.get('icon') + '"></i>';
this.$weatherTemp.empty().html(parseInt(this.model.get('temperature')) + '&deg;c&nbsp;');
this.$weatherText.empty().html(this.model.get('summary'));
this.$weatherTemp.empty().html(parseInt(this.model.get('temperature')) + '&deg;c&nbsp;');
this.$weatherText.empty().html(this.model.get('summary'));
this.$weatherIcon.empty().html(ws);
this.$weatherIcon.empty().html(ws);
}
});

61
app/ui.html Normal file
View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Clean Webkit CSS3 UI</h1>
<section class="tabs">
<input id="tab-1" type="radio" name="radio-set" class="tab-selector-1" checked="checked" />
<label for="tab-1" class="tab-label-1">Elements</label>
<input id="tab-2" type="radio" name="radio-set" class="tab-selector-2" />
<label for="tab-2" class="tab-label-2">Text Fields</label>
<input id="tab-3" type="radio" name="radio-set" class="tab-selector-3" />
<label for="tab-3" class="tab-label-3">Details</label>
<div class="clear-shadow"></div>
<div class="content">
<div class="content-1">
Slider (Range)
<input type="range">
Toggles (Checkboxes)
<input type="checkbox" unchecked>
<input type="checkbox" checked>
Radio buttons<br />
<input type="radio" name="choix">
<input type="radio" name="choix" checked>
</div>
<div class="content-2">
Text Fields
<input type="text" placeholder="Username" name="input_text">
Password Fields
<input type="password" placeholder="Password" name="password">
<input type="submit" value="Submit »">
</div>
<div class="content-3">
<p><b>The Clean Webkit CSS3 UI inclued:</b></p>
<p>Form Inputs
<br/>- Range
<br/>- Checkboxes
<br/>- Radio buttons
<br/>- Submit button
<br/>- Text and password fields</p>
<p>CSS3 Tabs with radio buttons
<br/>Custom scrollbar</p>
<br />
<p>ericftremblay.com</p>
<p>github.com/ericft</p>
</div>
</div>
</section>
</body>
</html>

View File

@ -25,8 +25,13 @@ const mqttClient = function (events) {
this.livingRoom = {
temp: 0,
last: 0
last: 0,
data: []
};
this.first = false;
this.maxLength = 99;
let mode = 'FanOff';
const d = new Date();
@ -50,13 +55,39 @@ const mqttClient = function (events) {
}
});
this.storeData = function (data, alt) {
if (!this.first) {
this.first = true;
return [];
}
let target = alt || this.livingRoom.data;
if (target.length === this.maxLength) {
target = target.slice(1);
}
target.push(data);
if (alt) {
return target;
}
this.livingRoom.data = target;
};
this.logTemp = function () {
const now = new Date;
const mod = 60000 - (now.getTime() % 60000);
this.storeData(this.livingRoom.temp);
const data = {id: 'graph', data: this.livingRoom.data};
events.emit('sendSocket', data);
setTimeout(this.logTemp.bind(this), mod + 10);
};
this.fanTimer = function () {
let n;
const now = new Date;
const mod = 900000 - (now.getTime() % 900000);
const day = now.getDay();
const daytimeLimits = {low:27900000,high:63000000};
const daytimeLimits = {low: 27900000, high: 63000000};
const nowMS = (now.getHours() * 3600000) + (now.getMinutes() * 60000);
if (globalMode === 'FanOff') {
@ -67,7 +98,7 @@ const mqttClient = function (events) {
mode = (parseFloat(this.livingRoom.temp) <= 22.5) ? 'FanOn' : 'FanOff';
}
if ((globalMode !== 'FanOff' || mode !== 'FanOff') && ((day >=1 && day <=5) && (nowMS >= daytimeLimits.low && nowMS <= daytimeLimits.high))) {
if ((globalMode !== 'FanOff' || mode !== 'FanOff') && ((day >= 1 && day <= 5) && (nowMS >= daytimeLimits.low && nowMS <= daytimeLimits.high))) {
logger.info('Week day');
mode = 'FanOff'
}
@ -79,14 +110,16 @@ const mqttClient = function (events) {
logger.error('No message received for over 10 minutes');
mode = 'FanOff';
logger.warn('Setting quit for 15 seconds.');
setTimeout(()=>{throw new error('Ejecting for restart');}, 15000);
setTimeout(() => {
throw new error('Ejecting for restart');
}, 15000);
}
logger.info('LR temp:', this.livingRoom.temp);
const data = {id: 'temperature', data: {mode: globalMode, temp: this.livingRoom.temp}};
events.emit('sendIFTTT', mode);
const data = {id: 'temperature', data: {mode: globalMode, temp: this.livingRoom.temp}};
events.emit('sendSocket', data);
setTimeout(this.fanTimer.bind(this), mod + 10);
@ -110,6 +143,7 @@ const mqttClient = function (events) {
this.connected = true;
logger.info('Connected to Silvr Broker');
this.fanTimer();
this.logTemp();
}.bind(this));
this.client.subscribe('livingroomTemp');