This commit is contained in:
Martin Donnelly 2016-08-08 11:46:31 +01:00
commit c8ceeb9900
457 changed files with 89670 additions and 0 deletions

32
.editorconfig Normal file
View File

@ -0,0 +1,32 @@
; http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
[*.txt]
insert_final_newline = false
trim_trailing_whitespace = false
[*.py]
indent_size = 4
[*.m]
indent_size = 4
[Makefile]
indent_style = tab
indent_size = 8
[*.{js,json}]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false

180
.gitignore vendored Normal file
View File

@ -0,0 +1,180 @@
# Created by .ignore support plugin (hsz.mobi)
### Archives template
# It's better to unpack these files and commit the raw source because
# git has its own built in compression methods.
*.7z
*.jar
*.rar
*.zip
*.gz
*.bzip
*.bz2
*.xz
*.lzma
*.cab
#packing-only formats
*.iso
*.tar
#package management formats
*.dmg
*.xpi
*.gem
*.egg
*.deb
*.rpm
*.msi
*.msm
*.msp
### Windows template
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### OSX template
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Node template
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules
bower_components
### VisualStudioCode template
.settings
### Xcode template
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate
dist

46
.jscsrc Normal file
View File

@ -0,0 +1,46 @@
{
"disallowKeywords": ["with"],
"disallowKeywordsOnNewLine": ["else"],
"disallowMixedSpacesAndTabs": true,
"disallowMultipleVarDecl": "exceptUndefined",
"disallowNewlineBeforeBlockStatements": true,
"disallowQuotedKeysInObjects": true,
"disallowSpaceAfterObjectKeys": true,
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowSpacesInFunction": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInsideParentheses": true,
"disallowTrailingWhitespace": true,
"maximumLineLength": 160,
"requireCamelCaseOrUpperCaseIdentifiers": false,
"requireCapitalizedComments": true,
"requireCapitalizedConstructors": true,
"requireCurlyBraces": true,
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"case",
"return",
"try",
"catch",
"typeof"
],
"requireSpaceAfterLineComment": true,
"requireSpaceAfterBinaryOperators": true,
"requireSpaceBeforeBinaryOperators": true,
"requireSpaceBeforeBlockStatements": true,
"requireSpaceBeforeObjectValues": true,
"requireSpacesInFunction": {
"beforeOpeningCurlyBrace": true
},
"requireTrailingComma": false,
"requireEarlyReturn": false,
"validateIndentation": 2,
"validateLineBreaks": "LF",
"validateQuoteMarks": "'"
}

37
.jshintrc Normal file
View File

@ -0,0 +1,37 @@
{
"predef": [
"Promise",
"$"
],
"globals": {
"$": false,
"MicroEvent": false
},
"node":true,
"browser": true,
"boss": true,
"curly": true,
"debug": false,
"devel": true,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": false,
"nomen": false,
"onevar": false,
"plusplus": false,
"regexp": false,
"undef": true,
"sub": true,
"strict": false,
"white": false,
"eqnull": true,
"esnext": true,
"unused": true,
"supernew":true
}

90
app.js Normal file
View File

@ -0,0 +1,90 @@
/**
* Created by Martin on 08/02/2016.
*/
'use strict';
var express = require('express');
var path = require('path');
var http = require('http');
var ejs = require('ejs');
var morgan = require('morgan');
var cookieparser = require('cookie-parser');
var session = require('express-session');
var methodoverride = require('method-override');
var bodyparser = require('body-parser');
var errorhandler = require('errorhandler');
var log4js = require('log4js');
var logger = log4js.getLogger();
var WebSocketServer = require('websocket').server;
var EventEmitter = require('events');
var busEmitter = new EventEmitter();
var apn = require('apn');
require('sugar-date');
var isProduction = false;
var mdotApi = require('./lib/mdot/api.js');
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
if (process.env.NODE_ENV === 'production') {
isProduction = true;
}
logger.warn('isProduction:', isProduction);
var app = express();
app.set('port', process.env.PORT || 4545);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(morgan('combined'));
app.use(cookieparser('your secret here'));
app.use(session({
secret: '1234567890QWERTY', resave: false, saveUninitialized: false
}));
/* 'default', 'short', 'tiny', 'dev' */
app.use(methodoverride());
app.use(bodyparser.urlencoded({extended: false}));
// Parse application/json
app.use(bodyparser.json());
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'X-Requested-With');
next();
});
// Run npm start --production to use dist
var staticDir = isProduction ? 'dist' : 'app';
app.use(express.static(path.join(__dirname, staticDir)));
app.use(errorhandler({dumpExceptions: true, showStack: true}));
// Events and sockets
function originIsAllowed(origin) {
// Put logic here to detect whether the specified origin is allowed.
return true;
}
// glue routes
mdotApi(app);
//app.get('/api/mdot/:id', mDot.getData);
app.listen(3010, function() {
logger.info('Express listening on 3010');
});

276
app/css/app.css Normal file
View File

@ -0,0 +1,276 @@
body {
font-family: Ubuntu, "Helvetica Neue", Helvetica, arial, sans-serif;
background-color: #004c6d;
}
html, body {
height: 100%;
overflow: hidden;
}
#weatherIcon {
margin-left:25%;
margin-right:25%;
height:70px;
width:70px;
}
#lightR, #projR { color: red !important; }
#lightG, #projG { color: green !important; }
#lightB, #projB { color: blue !important; }
#lightW, #projW { background-color: #aabbcc; }
.lightBG, .heatingBG, .projectorBG {
float: right;
}
/*.lightBG {
background-color: rgba(255, 255, 0, 0.3);
}
.heatingBG {
background-color: rgba(255, 0, 255, 0.3);
}
.projectorBG {
background-color: rgba(0, 255, 255, 0.3);
}*/
.mui-panel {
background-color: #015579;
}
.h105 {
height: 100px;
}
.mdHeading {
overflow: hidden;
}
.mui--text-title {
color: #ffffff;
}
.item_content {
height: 100px;
/* border: 1px solid grey;*/
min-height: 100px;
overflow: hidden;
}
.item_content a.title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #ffffff;
}
.item_content div.body, .item_content div.site, .item_content div.tags {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #313131;
}
.time, .date, .temp {
font-family: 'Ubuntu Condensed', sans-serif;
font-size: 80px;
color: #bad649;
}
.time span.hour:after {
content: ":";
}
.date {
font-size: 35px;
line-height: 1;
}
.temp::after {
content: "°c";
}
.item_content div.tags {
color: blue;
}
.noConnection {
color: rgb(244, 150, 26);
}
#caltext {
color: #fff;
}
/* Smartphones (portrait and landscape) ----------- */
@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
/* Styles */
.time, .date, .temp {
font-family: 'Ubuntu Condensed', sans-serif;
font-size: 33px;
/*color: #ff0000;*/
}
.time {
font-size: 50px;
line-height: 1;
}
.time span.hour:after {
content: "\a";
white-space: pre;
}
.temp {
font-size: 70px;
}
.temp::after {
content: "°";
}
.wd-we {
font-size: 75%;
}
.mo {
font-size: 85%;
}
.mo.mo-1, .mo.mo-10 {
font-size: 70%;
}
.mo.mo-2 {
font-size: 65%;
}
.mo.mo-8 {
font-size: 80%;
}
.mo.mo-9 {
font-size: 55%;
}
.mo.mo-11, .mo.mo-12 {
font-size: 60%;
}
}
/* Smartphones (landscape) ----------- */
@media only screen and (min-width: 321px) {
/* Styles */
}
/* Smartphones (portrait) ----------- */
@media only screen and (max-width: 320px) {
/* Styles */
}
.spinner {
margin: 25px auto 0;
width: 70px;
text-align: center;
}
.spinner > div {
width: 18px;
height: 18px;
background-color: rgb(244, 150, 26);
border-radius: 100%;
display: inline-block;
-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
animation: sk-bouncedelay 1.4s infinite ease-in-out both;
}
.spinner .bounce1 {
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s;
}
.spinner .bounce2 {
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s;
}
@-webkit-keyframes sk-bouncedelay {
0%, 80%, 100% { -webkit-transform: scale(0) }
40% { -webkit-transform: scale(1.0) }
}
@keyframes sk-bouncedelay {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0);
}
40% {
-webkit-transform: scale(1.0);
transform: scale(1.0);
}
}
.material-icons {
color: #e5f7fd;
}
.material-icons.md-18 { font-size: 18px; }
.material-icons.md-24 { font-size: 24px; }
.material-icons.md-36 { font-size: 36px; }
.material-icons.md-48 { font-size: 48px; }
.material-icons.md-100 { font-size: 100px; }
/* Rules for using icons as black on a light background. */
.material-icons.md-dark { color: rgba(0, 0, 0, 0.54); }
.material-icons.md-dark.md-inactive { color: rgba(0, 0, 0, 0.26); }
/* Rules for using icons as white on a dark background. */
.material-icons.md-light { color: rgba(255, 255, 255, 1); }
.material-icons.md-light.md-inactive { color: rgba(255, 255, 255, 0.3); }
.material-icons.md-bulb {
content: ""
}
/*
fan : toys
<i class="material-icons">&#xE332;</i>
bulb : lightbulb_outline
<i class="material-icons">&#xE90F;</i>
calendar: event_note
<i class="material-icons">&#xE616;</i>
projector: cast
<i class="material-icons">&#xE307;</i>
*/
.md-display {
opacity: 1;
transition: opacity 0.3s, visibility 0.3s;
}
.lostConnection {
opacity: 0.5;
transition: opacity 0.3s, visibility 0.3s;
}

View File

@ -0,0 +1,15 @@
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}

1912
app/css/mui.css Normal file

File diff suppressed because it is too large Load Diff

1912
app/css/mui.custom.css Normal file

File diff suppressed because it is too large Load Diff

1
app/css/mui.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

12
app/fav/browserconfig.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square70x70logo src="/fav/mstile-70x70.png"/>
<square150x150logo src="/fav/mstile-150x150.png"/>
<square310x310logo src="/fav/mstile-310x310.png"/>
<wide310x150logo src="/fav/mstile-310x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
app/fav/favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

BIN
app/fav/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

BIN
app/fav/favicon-96x96.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
app/fav/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

43
app/fav/manifest.json Normal file
View File

@ -0,0 +1,43 @@
{
"name": "Censis Smart Office ",
"icons": [
{
"src": "\/fav\/android-chrome-36x36.png",
"sizes": "36x36",
"type": "image\/png",
"density": 0.75
},
{
"src": "\/fav\/android-chrome-48x48.png",
"sizes": "48x48",
"type": "image\/png",
"density": 1
},
{
"src": "\/fav\/android-chrome-72x72.png",
"sizes": "72x72",
"type": "image\/png",
"density": 1.5
},
{
"src": "\/fav\/android-chrome-96x96.png",
"sizes": "96x96",
"type": "image\/png",
"density": 2
},
{
"src": "\/fav\/android-chrome-144x144.png",
"sizes": "144x144",
"type": "image\/png",
"density": 3
},
{
"src": "\/fav\/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image\/png",
"density": 4
}
],
"display": "standalone",
"orientation": "portrait"
}

BIN
app/fav/mstile-144x144.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
app/fav/mstile-150x150.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
app/fav/mstile-310x150.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
app/fav/mstile-310x310.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
app/fav/mstile-70x70.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,46 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="991.000000pt" height="991.000000pt" viewBox="0 0 991.000000 991.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,991.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M7465 9503 c-480 -60 -867 -422 -967 -903 -28 -132 -21 -345 16 -517
40 -184 56 -315 56 -460 0 -146 -15 -244 -54 -347 -36 -96 -38 -98 -89 -80
-71 25 -267 73 -372 90 -219 35 -551 33 -774 -5 -973 -169 -1752 -917 -1945
-1871 -14 -67 -27 -124 -30 -127 -9 -9 -162 19 -235 43 -168 56 -304 137 -577
345 -209 157 -328 222 -489 266 -93 25 -114 27 -290 27 -207 0 -253 -8 -420
-73 -270 -104 -514 -347 -624 -623 -113 -281 -105 -620 20 -887 113 -241 291
-426 524 -541 311 -154 673 -157 985 -9 107 51 172 95 328 226 311 258 558
392 752 405 l44 3 17 -70 c115 -492 361 -914 725 -1247 354 -324 795 -530
1294 -604 80 -12 177 -17 320 -17 222 0 346 14 545 58 254 57 407 0 493 -183
25 -52 27 -68 27 -177 -1 -119 -1 -121 -49 -245 -66 -173 -86 -263 -93 -410
-21 -494 279 -940 743 -1106 352 -126 754 -67 1054 156 84 62 205 187 259 269
62 91 126 231 157 341 38 140 45 372 14 520 -96 469 -473 820 -950 886 -179
25 -223 35 -297 69 -85 39 -159 105 -199 177 -27 49 -29 61 -29 158 0 95 3
110 27 156 15 28 70 102 123 165 239 281 410 611 500 963 57 223 70 332 70
596 0 264 -13 373 -70 595 -115 448 -379 885 -712 1179 -57 50 -103 95 -103
100 0 19 92 136 150 189 119 110 264 194 490 282 80 31 176 69 215 86 333 142
568 418 656 770 29 120 36 325 15 448 -84 482 -453 849 -931 926 -82 14 -245
18 -320 8z m-879 -2369 c179 -72 362 -175 526 -296 l67 -49 -23 -52 c-78 -176
-73 -421 13 -642 17 -45 63 -137 103 -205 210 -367 298 -727 268 -1103 -53
-664 -433 -1233 -1019 -1527 -295 -148 -564 -207 -891 -197 -233 7 -398 39
-600 114 -449 168 -823 510 -1029 943 -42 89 -123 311 -116 318 2 2 44 -11 95
-28 199 -66 403 -188 797 -477 211 -155 338 -226 497 -278 766 -251 1582 242
1721 1041 20 113 19 336 0 450 -95 545 -532 983 -1079 1081 -125 22 -354 22
-470 -1 -279 -54 -482 -162 -716 -377 -330 -304 -539 -447 -753 -514 -117 -37
-118 -37 -101 33 82 320 239 603 467 839 161 167 310 274 522 379 232 113 430
166 690 184 357 24 460 45 614 125 111 57 194 125 255 209 26 36 54 66 60 66
7 0 52 -16 102 -36z m-701 -1448 c90 -24 232 -98 307 -160 122 -101 217 -251
259 -411 28 -105 30 -279 4 -380 -91 -359 -405 -608 -770 -608 -123 0 -231 25
-350 83 -165 80 -284 199 -364 363 -54 109 -72 180 -78 308 -11 224 60 417
215 581 109 116 254 198 407 232 87 19 283 15 370 -8z m-2044 -463 c-10 -56
-15 -144 -14 -313 0 -211 3 -246 25 -348 l24 -114 -30 6 c-106 20 -209 26
-353 20 l-162 -6 -6 24 c-31 139 -44 479 -25 664 6 65 13 120 13 120 1 1 114
5 252 9 137 3 252 8 254 11 2 2 12 4 21 4 15 0 15 -6 1 -77z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
app/gfx/100.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
app/gfx/105.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
app/gfx/128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
app/gfx/icons/Clock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
app/gfx/icons/Cloud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
app/gfx/icons/Downpour.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

BIN
app/gfx/icons/Fog Day.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
app/gfx/icons/Fog Night.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
app/gfx/icons/Full Moon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
app/gfx/icons/Hail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/gfx/icons/Icy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
app/gfx/icons/Idea.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
app/gfx/icons/Light Off.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/gfx/icons/No Rain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
app/gfx/icons/Rain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
app/gfx/icons/Sleet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
app/gfx/icons/Snow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
app/gfx/icons/Storm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
app/gfx/icons/Sun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
app/gfx/icons/TV On.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
app/gfx/icons/Wet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/gfx/icons/Winter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
app/gfx/icons/calendar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

BIN
app/gfx/icons/fan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<path d="M256,32c77.313,0,140,62.688,140,140c0,76.125-45.875,85-54.5,168c0,7.75-6.25,14-14,14h-143c-7.75,0-14-6.25-14-14h-0.031
C161.875,257,116,248.125,116,172C116,94.688,178.688,32,256,32 M326,368c7.75,0,14,6.25,14,14s-6.25,14-14,14H186
c-7.75,0-14-6.25-14-14s6.25-14,14-14H326 M326,410c7.75,0,14,6.25,14,14s-6.25,14-14,14H186c-7.75,0-14-6.25-14-14s6.25-14,14-14
H326 M312,452c0,15.469-12.531,28-28,28h-56c-15.469,0-28-12.531-28-28H312 M256,0C161.156,0,84,77.156,84,172
c0,47.625,15.563,74.969,29.25,99.125c11.625,20.438,21.688,38.156,25.281,71.094c0.344,7.313,2.438,14.188,5.844,20.219
C141.563,368.375,140,375,140,382c0,7.563,1.813,14.688,5.063,21c-3.25,6.313-5.063,13.438-5.063,21
c0,19.719,12.469,36.563,29.938,43.094C176.625,492.906,200.125,512,228,512h56c27.875,0,51.375-19.094,58.063-44.906
C359.531,460.563,372,443.719,372,424c0-7.563-1.844-14.688-5.094-21c3.25-6.313,5.094-13.438,5.094-21
c0-7-1.563-13.625-4.375-19.531c3.406-6.063,5.469-12.969,5.813-20.281c3.625-32.906,13.656-50.594,25.281-71.063
C412.438,247,428,219.625,428,172C428,77.156,350.844,0,256,0L256,0z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
app/gfx/projector.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
app/gfx/projector.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

318
app/index.html Normal file
View File

@ -0,0 +1,318 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Console</title>
<!-- build:fonts -->
<link rel="stylesheet"
href="http://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700"
type="text/css">
<link href='https://fonts.googleapis.com/css?family=Ubuntu+Condensed'
rel='stylesheet' type='text/css'>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<!-- endbuild -->
<!-- build:css -->
<link href="css/mui.css" rel="stylesheet" type="text/css"/>
<link href="css/app.css" rel="stylesheet" type="text/css"/>
<!-- endbuild -->
<link rel="apple-touch-icon" sizes="57x57"
href="/fav/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60"
href="/fav/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72"
href="/fav/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76"
href="/fav/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114"
href="/fav/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120"
href="/fav/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144"
href="/fav/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152"
href="/fav/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180"
href="/fav/apple-touch-icon-180x180.png">
<link rel="icon" type="image/png" href="/fav/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/fav/android-chrome-192x192.png"
sizes="192x192">
<link rel="icon" type="image/png" href="/fav/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/fav/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="/fav/manifest.json">
<link rel="mask-icon" href="/fav/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="/fav/favicon.ico">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-TileImage" content="/fav/mstile-144x144.png">
<meta name="msapplication-config" content="/fav/browserconfig.xml">
<meta name="theme-color" content="#00aeef">
</head>
<body class="mui--no-user-select">
<div id="iosTaskbar" style="height:25px;display:none;"></div>
<div class="mui-container">
<div class="mui-panel" style="display: ;">
<div class="mui-row mui--text-center">
<img src="gfx/censis_logo_white.png">
</div>
</div>
<div class="mui-panel" id="noSocket" style="display: none;">
<div class="mui-row">
<div
class="mui--text-body2 mui--text-center noConnection">Lost connection to server. Waiting for connection
</div>
<div id='longWait' class="spinner" style="display: none;">
<div class="bounce1"></div>
<div class="bounce2"></div>
<div class="bounce3"></div>
</div>
</div>
</div>
<div class="mui-panel" id="noDevice" style="display: none;">
<div class="mui-row">
<div
class="mui--text-body2 mui--text-center noConnection">We are having problems connecting to one or more of the devices. Please restart them and wait for them to reconnect.
</div>
</div>
</div>
<div class="mui-panel" id="clock">
<div class="mui-row">
<div class="mui-col-xs-4 ">
<div id="time" class="mui--text-center time">12:34</div>
</div>
<div class="mui-col-xs-4 item_content">
<div id="date" class="mui--text-center date">14 April<br>2016</div>
</div>
<div class="mui-col-xs-4 item_content">
<div id="weather" class="mui--text-center date">
<div id="weatherIcon">
<canvas id="icon1" width="210" height="210"
style="max-width: 70px; max-height:70px"></canvas>
</div>
<div class="mui--text-center" id="weatherText"></div>
</div>
</div>
</div>
</div>
<div class="mui-panel" id="extender" style="display: none;">
<div class="mui-row">
<div class="mui-col-xs-12 mui--text-center">
<div class="mui--text-title ">
Extend meeting
</div>
</div>
</div>
<div class="mui-row">
<div class="mui-col-xs-12 mui--text-center">
<button id="extend05" class="mui-btn mui-btn--fab">5</button>
<button id="extend10" class="mui-btn mui-btn--fab">10</button>
<button id="extend15" class="mui-btn mui-btn--fab">15</button>
<button id="extend30" class="mui-btn mui-btn--fab">30</button>
</div>
</div>
</div>
<div class="mui-panel" id="calendar" style="display: none;">
<div class="mui-row">
<div class="mui-col-xs-4 mui--text-center"><span
class="material-icons md-100">&#xE616;</span></div>
<div class="mui-col-xs-8 item_content">
<div class="mui-row ">
<div class="mui--text-title "><a class='title'
href="#">Meeting room</a>
</div>
</div>
<div class="mui-row">
<div id="caltext"></div>
<div id="extendInfo" class="mui--text-subhead mui--text-accent"></div>
</div>
</div>
</div>
</div>
<div id="front-light" class="md-display">
<div class="mui-panel">
<div class="mui-row">
<div class="mui-col-xs-4 mui--text-center"><span
class="material-icons md-100">&#xE90F;</span></div>
<div class="mui-col-xs-4 item_content">
<div class="mui-row mui--text-center">
<div class="mui--text-title mui--text-center"><a class='title'
href="#">Front light</a>
</div>
</div>
<div class="mui-row mui--text-center">
<button id="frontLightOn" class="mui-btn mui-btn--primary lightOn">On
</button>
<button id="frontLightOff" class="mui-btn mui-btn--danger lightOff"
style="display: none;">Off
</button>
</div>
</div>
<div class="mui-col-xs-4 mui--text-center" id="auxFront"
style="display:none;">
<div>
<button class="mui-btn mui-btn--small mui-btn--accent lightUp"
id="frontUp">BRIGHTER
</button>
</div>
<div>
<button class="mui-btn mui-btn--small mui-btn--accent lightDown"
id="frontDown">DARKER
</button>
</div>
</div>
</div>
</div>
</div>
<!--<div class="mui-panel" id="middle-light">
<div class="mui-row">
<div class="mui-col-xs-4 mui&#45;&#45;text-center"><i class="material-icons md-100">&#xE90F;</i></div>
<div class="mui-col-xs-4 item_content">
<div class="mui-row">
<div class="mui&#45;&#45;text-title mui&#45;&#45;text-center"><a class='title'
href="#">Middle light</a>
</div>
</div>
<div class="mui-row mui&#45;&#45;text-center">
<button id="middleLightOn"
class="mui-btn mui-btn&#45;&#45;primary">On
</button>
<button id="middleLightOff" class="mui-btn mui-btn&#45;&#45;danger"
style="display: none;">Off
</button>
</div>
</div>
</div>
</div>-->
<div class="mui-panel" id="back-light">
<div class="mui-row">
<div class="mui-col-xs-4 mui--text-center"><i
class="material-icons md-100">&#xE90F;</i></div>
<div class="mui-col-xs-4 item_content">
<div class="mui-row">
<div class="mui--text-title mui--text-center"><a class='title'
href="#">Back light</a>
</div>
</div>
<div class="mui-row mui--text-center">
<button id="backLightOn" class="mui-btn mui-btn--primary lightOn">On
</button>
<button id="backLightOff" class="mui-btn mui-btn--danger lightOff"
style="display: none;">Off
</button>
</div>
</div>
<div class="mui-col-xs-4 mui--text-center" id="auxBack"
style="display: none;">
<div>
<button class="mui-btn mui-btn--small mui-btn--accent lightUp"
id="backUp">BRIGHTER
</button>
</div>
<div>
<button class="mui-btn mui-btn--small mui-btn--accent lightDown"
id="backDown">DARKER
</button>
</div>
</div>
</div>
</div>
<div class="mui-panel" id="heating-panel" style="display: none ;">
<div class="mui-row">
<div class="mui-col-xs-4 mui--text-center"><i
class="material-icons md-100">&#xE332;</i>
</div>
<div class="mui-col-xs-4 item_content">
<div class="mui-row">
<div class="mui--text-title mui--text-center"><a class='title'
href="#">Fan</a>
</div>
</div>
<div class="mui-row mui--text-center">
<button id="heatingOn" class="mui-btn mui-btn--primary">On
</button>
<button id="heatingOff" class="mui-btn mui-btn--danger"
style="display: none;">Off
</button>
</div>
</div>
<div class="mui-col-xs-4 mui--text-center">
<div id="curTemp" class="temp"></div>
</div>
</div>
</div>
<div class="mui-panel" id="projector-panel" style="display:;">
<div class="mui-row">
<div class="mui-col-xs-4 mui--text-center"><i
class="material-icons md-100">&#xE307;</i></div>
<div class="mui-col-xs-4 item_content">
<div class="mui-row">
<div class="mui--text-title mui--text-center"><a class='title'
href="#">Projector</a>
</div>
</div>
<div class="mui-row mui--text-center">
<button id="projectorOn" class="mui-btn mui-btn--primary">On
</button>
<button id="projectorOff" class="mui-btn mui-btn--danger"
style="display: none;">Off
</button>
</div>
</div>
<div class="mui-col-xs-4 mui--text-center" id="auxProjector"
style="display:none;">
<div>
<button class="mui-btn mui-btn--small mui-btn--accent"
id="projectorHDMI">HDMI
</button>
</div>
<div>
<button class="mui-btn mui-btn--small mui-btn--accent"
id="projectorVGA">VGA
</button>
</div>
</div>
</div>
</div>
<!--<div class="mui-panel">
<div class="mui-row">
<div class="mui-col-md-3"><span id="lightR">-&#45;&#45;</span></div>
<div class="mui-col-md-3"><span id="lightG">-&#45;&#45;</span></div>
<div class="mui-col-md-3"><span id="lightB">-&#45;&#45;</span></div>
<div class="mui-col-md-3"><span id="lightW">-&#45;&#45;</span></div>
</div>
<div class="mui-row">
<div class="mui-col-md-3"><span id="projR">-&#45;&#45;</span></div>
<div class="mui-col-md-3"><span id="projG">-&#45;&#45;</span></div>
<div class="mui-col-md-3"><span id="projB">-&#45;&#45;</span></div>
<div class="mui-col-md-3"><span id="projW">-&#45;&#45;</span></div>
</div>
</div>-->
</div>
<script src="cordova.js"></script>
<!-- build:vendor -->
<script src="lib/mui.js"></script>
<script src="lib/jquery.js"
integrity="sha256-laXWtGydpwqJ8JA+X9x2miwmaiKhn8tVmOVEigRNtP4="
crossorigin="anonymous"></script>
<script src="lib/chroma.js"></script>
<script src="lib/underscore.js"></script>
<script src="lib/backbone.js"></script>
<!--<script src="lib/sugar-date.js"></script>-->
<script src="lib/sugar-full.min.js"></script>
<script src="lib/skycons.js"></script>
<script src="lib/microevent.js"></script>
<!-- endbuild -->
<!-- build:js -->
<script src="js/sowebsocket.js"></script>
<script src="js/colours.js"></script>
<script src="js/parts/clock.js"></script>
<script src="js/parts/meetings.js"></script>
<script src="js/parts/lights.js"></script>
<script src="js/parts/projector.js"></script>
<script src="js/appv3.js"></script>
</body>
<!-- endbuild -->
</html>

403
app/js/mdot.js Normal file
View File

@ -0,0 +1,403 @@
'use strict';
/* global Backbone, _, $ */
/* global mainview */
/* jshint browser: true , devel: true*/
(function($) {
var mqttConfig = {
orgId: 'qz0da4',
userName: 'a-qz0da4-dfwwdkmkzr',
appKey: '9txJEf3Cjy7hkSOvkv',
prefix: 'iot-2/type/mDot/id/'
};
var sendAuthentication = function(xhr) {
var user = 'a-qz0da4-dfwwdkmkzr'; // Your actual username
var pass = '9txJEf3Cjy7hkSOvkv'; // Your actual password
var token = user.concat(':', pass);
xhr.setRequestHeader('Authorization', ('Basic '.concat(btoa(token))));
console.log('Auth:', ('Basic '.concat(btoa(token))));
};
var EventsModel = Backbone.Model.extend({
initialize: function() {
_.bindAll(this, 'processAdded');
this.on('all',function(d) {
console.log('model:all',d);
this.temporal = {low: 0,high: 0};
});
this.on('add',function() {
this.processAdded();
});
},
processAdded: function() {
console.log('Model:ProcessAdded');
var tempCollection = new Backbone.Collection();
_.invoke(DeviceCollection.toArray(), 'destroy');
this.temporal = {low: 0,high: 0};
_(this.get('events')).each(function(i) {
i.evt.decoded = this.decoder(i.evt.data);
i.evt.dateTime = this.dateTime(i.timestamp.$date);
if (this.temporal.low === 0 || this.temporal.low > i.timestamp.$date) {
this.temporal.low = i.timestamp.$date;
}
if (this.temporal.high === 0 || this.temporal.high < i.timestamp.$date) {
this.temporal.high = i.timestamp.$date;
}
tempCollection.add({dt: i.evt.dateTime.dateTime,lux: i.evt.decoded.light, temp: i.evt.decoded.temp, co2: i.evt.decoded.co2, humid: i.evt.decoded.humid, noise: i.evt.decoded.noise});
}, this);
DeviceCollection.temporal = this.temporal;
DeviceCollection.models = tempCollection.models;
DeviceCollection.trigger('update');
console.log('temporal:', this.temporal);
},
decoder: function(data) {
var _obj = {};
var _data = window.atob(data).split('');
var bytes = _data.map(i => i.charCodeAt());
_obj.light = parseInt('0x' + ('0' + bytes[0]).substr(-2) + ('0' + bytes[1]).substr(-2));
_obj.co2 = parseInt(_data[2] + _data[3] + _data[4] + _data[5] + _data[6], 10);
_obj.temp = (parseInt(_data[7] + _data[8] + _data[9] + _data[10] + _data[11], 10) - 1000) / 10;
_obj.humid = (parseInt(_data[12] + _data[13] + _data[14] + _data[15] + _data[16], 10) / 10);
_obj.noise = parseInt('0x' + ('0' + bytes[17]).substr(-2) + ('0' + bytes[18]).substr(-2));
_obj.binData = bytes;
return _obj;
},
dateTime: function($date) {
var dateTime = new Date.create($date);
var date = dateTime.format('{yyyy}-{MM}-{dd}');
var time = dateTime.format('{HH}:{mm}:{ss}');
return {dateTime: dateTime.format('{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}'), date: date, time: time};
}
});
var mDotCollection = Backbone.Collection.extend({
model: EventsModel,
url: 'https://qz0da4.internetofthings.ibmcloud.com/api/v0002/historian/types/mDot/devices/',
initialize: function() {
this.on('all',function(d) {
console.log('Collection:all',d);
});
this.on('update', function() {
// Console.log('Collection:update',this);
});
}
});
var ItemView = Backbone.View.extend({
tagName: 'div', className: 'item mui-container', initialize: function() {
this.template = _.template($('#item-template').html());
console.log('ItemView:Init');
// This.render();
}, render: function() {
console.log('ItemView:Render');
_(this.model.events).each(function(i) {
this.$el.append(this.template({item: i}));
}, this);
return this;
}
});
var MDOT = Backbone.View.extend({
model: EventsModel, el: $('#output'),
events: {
'click button#refresh': 'refresh'
}, initialize: function() {
_.bindAll(this, 'render', 'refresh', 'update');
this.collection.bind('change reset add remove', this.render, this);
this.template = _.template($('#list-template').html());
this.render();
}, refresh: function() {
}, update: function() {
console.log('MDOT:update');
this.collection.each(function(model) {
// Var events = model.get('events');
// var e = new ItemView({model: model.toJSON()});
});
}, render: function() {
console.log('MDOT:render');
var that = this;
this.$el.empty();
this.collection.each(function(model) {
var events = model.get('events');
var e = new ItemView({model: model.toJSON()}).render().el;
console.log('render:done:');
that.$el.append(e);
});
console.log('bah');
return this;
}
});
var MainModel = Backbone.Model.extend({});
var MainView = Backbone.View.extend({
el: $('#main'),
template: _.template($('#main-template').html()),
events: {
'change select#device': 'changeDevice',
'click button#refresh': 'updateDevice',
'change input#from': 'changeDate',
'change input#to': 'changeDate',
submit: function(event) {}
},
initialize: function() {
_.bindAll(this, 'render','changeDevice', 'updateDevice');
this.model.on('change',this.updateDevice);
console.log('MainView:', this);
this.render();
},
render: function() {
$(this.el).html(this.template());
return this;
},changeDate: function(elm) {
console.log('ChangeDate', elm);
if (Number.isNaN(elm.currentTarget.valueAsNumber)) {
this.model.unset(elm.currentTarget.id);
} else {
this.model.set(elm.currentTarget.id, elm.currentTarget.valueAsNumber);
}
},
changeDevice: function() {
var newDevice;
console.log('MainView:ChangeDevice');
newDevice = this.$el.find('#device')[0].value;
this.model.set('device', newDevice);
},
updateDevice: function() {
var fetchObj = {beforeSend: sendAuthentication};
var rangeObj = {start: null, end: null};
console.log('MainView:Updatedevice');
console.log(this.model);
if (this.model.has('from') && this.model.has('to')) {
rangeObj.start = this.model.get('from');
rangeObj.end = this.model.get('to');
fetchObj.data = $.param(rangeObj);
console.log(fetchObj.data);
}
if (this.model.has('device')) {
// FetchObj.data = $.param({key:'"'+ this.model.get('device') + '"'});
// this.collection.url = 'https://qz0da4.internetofthings.ibmcloud.com/api/v0002/historian/types/mDot/devices/' + this.model.get('device');
this.collection.url = '/api/mdot/' + this.model.get('device');
// this.collection.url = 'http://127.0.0.1:5984/mdot/_design/getDevice/_view/getDevice';
this.collection.fetch(fetchObj);
} else {
console.error('Nothing to get!');
}
}
});
var GraphView = Backbone.View.extend({
el: $('#graph'),
template: _.template($('#graph-template').html()),
initialize: function() {
this.modes = ['','lux','temp','co2','humid','noise'];
this.mode = 0;
this.xmlns = 'http://www.w3.org/2000/svg';
console.log('GraphView!');
_.bindAll(this, 'render', 'changeMode', 'updateGraph');
this.collection.on('update',function(d) {
if (this.mode > 0) {
this.updateGraph();
}
}, this);
this.render();
},
events: {
'change select#displaymode': 'changeMode'
},
render: function() {
$(this.el).html(this.template());
this.$line = $(this.el).find('#line');
this.$maxY = $(this.el).find('#maxY');
this.$datapoints = $(this.el).find('#datapoints');
this.$baseline = $(this.el).find('#baseline');
return this;
},
changeMode: function() {
this.mode = this.$el.find('#displaymode')[0].value;
this.updateGraph();
console.log('new mode:', this.mode);
},
updateGraph: function() {
var calcArray;
var startX;
var xstep;
var scale;
let ceiling, ceilingLimit;
let points = [];
let data = [];
let circle, title;
let getMode = this.modes[this.mode];
var occupied;
_(this.collection.models).each(function(i) {
// Console.log(i);
points.push(i.get(getMode));
data.push(i.get('dt') + ' / ' + i.get(getMode));
}, this);
ceiling = points.reduce(function(p, v) {
return (Math.abs(p) > Math.abs(v) ? Math.abs(p) : Math.abs(v));
});
ceilingLimit = (Math.ceil((Math.round(ceiling) + 1) / 10) * 10);
if (ceilingLimit > 1000) {
ceilingLimit = (Math.ceil((Math.round(ceiling) + 1) / 50) * 50);
}
this.$datapoints.empty();
this.$baseline.empty();
scale = 124 / ceilingLimit;
// Var xstep = (280 - 46) / 100;
xstep = 2.34;
startX = 46 + (100 - points.length) * xstep;
calcArray = [];
for (var x = 0;x < points.length;x++) {
calcArray.push((startX + (x * xstep)).toFixed(2) + ',' + (136 - ((points[x]) * scale)).toFixed(2));
circle = document.createElementNS(this.xmlns,'circle');
title = document.createElementNS(this.xmlns,'title');
if (parseInt(this.mode) === 5) {
occupied = (points[x] > 920) ? 'purple' : 'red';
} else if (parseInt(this.mode) === 3) {
occupied = (points[x] > 579) ? 'purple' : 'red';
} else {
occupied = 'red';
}
circle.setAttributeNS(null,'fill',occupied);
circle.setAttributeNS(null,'cx',(startX + (x * xstep)).toFixed(2).toString());
circle.setAttributeNS(null,'cy',(136 - ((points[x]) * scale)).toFixed(2).toString());
circle.setAttributeNS(null,'r','2');
circle.setAttributeNS(null,'stroke-width','1');
title.textContent = data[x];
circle.appendChild(title);
this.$datapoints[0].appendChild(circle);
}
console.log('This.mode = ', this.mode);
if (parseInt(this.mode) === 3 || parseInt(this.mode) === 5) {
var avgLine = (parseInt(this.mode) === 3) ? 526 : 852;
var bline = document.createElementNS(this.xmlns,'line');
bline.setAttributeNS(null,'x1',46);
bline.setAttributeNS(null,'y1',(136 - (avgLine * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'x2',280);
bline.setAttributeNS(null,'y2',(136 - (avgLine * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'stroke','#00ff00');
bline.setAttributeNS(null,'stroke-width','1');
this.$baseline[0].appendChild(bline);
bline = document.createElementNS(this.xmlns,'line');
bline.setAttributeNS(null,'x1',46);
bline.setAttributeNS(null,'y1',(136 - (4884 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'x2',280);
bline.setAttributeNS(null,'y2',(136 - (4884 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'stroke','#00ff55');
bline.setAttributeNS(null,'stroke-width','1');
this.$baseline[0].appendChild(bline);
}
if (parseInt(this.mode) === 3) {
var bline = document.createElementNS(this.xmlns,'line');
bline.setAttributeNS(null,'x1',46);
bline.setAttributeNS(null,'y1',(136 - (632 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'x2',280);
bline.setAttributeNS(null,'y2',(136 - (632 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'stroke','yellow');
bline.setAttributeNS(null,'stroke-width','1');
this.$baseline[0].appendChild(bline);
var bline = document.createElementNS(this.xmlns,'line');
bline.setAttributeNS(null,'x1',46);
bline.setAttributeNS(null,'y1',(136 - (1045 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'x2',280);
bline.setAttributeNS(null,'y2',(136 - (1045 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'stroke','red');
bline.setAttributeNS(null,'stroke-width','1');
this.$baseline[0].appendChild(bline);
}
this.$line[0].setAttribute('points',calcArray.join(' '));
this.$maxY[0].textContent = ceilingLimit;
}
});
var DeviceCollection = new Backbone.Collection;
var mdotCollection = new mDotCollection();
var mainSettings = new MainModel();
var mainview = new MainView({collection: mdotCollection, model: mainSettings});
var mdot = new MDOT({collection: mdotCollection});
var grapher = new GraphView({collection: DeviceCollection});
})(jQuery);

1920
app/lib/backbone.js Normal file

File diff suppressed because it is too large Load Diff

61
app/lib/base64.js Normal file
View File

@ -0,0 +1,61 @@
;(function () {
var object = typeof exports != 'undefined' ? exports : self; // #8: web workers
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function InvalidCharacterError(message) {
this.message = message;
}
InvalidCharacterError.prototype = new Error;
InvalidCharacterError.prototype.name = 'InvalidCharacterError';
// encoder
// [https://gist.github.com/999166] by [https://github.com/nignag]
object.btoa || (
object.btoa = function (input) {
var str = String(input);
for (
// initialize result and counter
var block, charCode, idx = 0, map = chars, output = '';
// if the next str index does not exist:
// change the mapping table to "="
// check if d has no fractional digits
str.charAt(idx | 0) || (map = '=', idx % 1);
// "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
output += map.charAt(63 & block >> 8 - idx % 1 * 8)
) {
charCode = str.charCodeAt(idx += 3/4);
if (charCode > 0xFF) {
throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
}
block = block << 8 | charCode;
}
return output;
});
// decoder
// [https://gist.github.com/1020396] by [https://github.com/atk]
object.atob || (
object.atob = function (input) {
var str = String(input).replace(/=+$/, '');
if (str.length % 4 == 1) {
throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded.");
}
for (
// initialize result and counters
var bc = 0, bs, buffer, idx = 0, output = '';
// get next character
buffer = str.charAt(idx++);
// character found in table? initialize bit storage and add its ascii value;
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
// and if not first of each 4 characters,
// convert the first 8 bits to one ascii character
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
// try to find character in table (0-63, not found => -1)
buffer = chars.indexOf(buffer);
}
return output;
});
}());

Some files were not shown because too many files have changed in this diff Show More