Let there be a light - Angular, nodeRED and Websockets
NodeRED has conquered a place in my permanent toolbox. I run an instance in Bluemix, on my local machine and on a Raspberry PI. I build a little demo where a light connected to a Particle lights up based on an event reaching a NodeRED instance. However I don't carry my IoT gear every time (got lots of funny looks at airport security for it), but I still want to demo the app. The NodeRED side is easy. I just added a websocket output node and the server side is ready to roll.
On the browser side I decided to use angular.js and one of its web socket libraries ng-websocket. The application code is just about 50 lines, so here it goes:
The HTML is simple. I split it into the main file and 3 status files. One could easily put the statuses into a script template section or inside the app This would reduce the number of http requests. For the bulb I used font-awesome, so no image has been harmed in creating this demo.
As usual: YMMV
On the browser side I decided to use angular.js and one of its web socket libraries ng-websocket. The application code is just about 50 lines, so here it goes:
'use strict';
var websocketEndpoint = 'wss://'+window.location.hostname+'/ws/bulb';
console.log('Application loading ...');
// Declare app level module which depends on views, and components
var myApp = angular.module('myApp', ['ngWebsocket','ngRoute']);
myApp.config(['$routeProvider', function($routeProvider) {
console.log('Routes loading... ');
$routeProvider.when('/bulbon', {
templateUrl: 'bulbs/bulb-on.html'
}).when('/bulboff', {
templateUrl: 'bulbs/bulb-off.html'
}).when('/bulbunknown', {
templateUrl: 'bulbs/bulb-unknown.html'
}).otherwise({redirectTo: '/bulbunknown'});
}]);
myApp.run(function ($websocket, $location) {
console.log('run');
var ws = $websocket.$new({
url: websocketEndpoint,
reconnect: true
}); // instance of ngWebsocket, handled by $websocket service
ws.$on('$open', function () {
console.log('Websocket connection open');
});
ws.$on('$message', function (data) {
console.log('data arrived');
console.log(data);
var newlocation = '#/bulbunknown';
if (data.bulb === 1) {
newlocation = '#/bulbon';
} else if (data.bulb === 0) {
newlocation = '#/bulboff';
}
window.location = newlocation;
});
ws.$on('$close', function () {
console.log('Websocket connection closed');
});
});
console.log('Done');
##
The HTML is simple. I split it into the main file and 3 status files. One could easily put the statuses into a script template section or inside the app This would reduce the number of http requests. For the bulb I used font-awesome, so no image has been harmed in creating this demo.
The bower.json
{
"name": "iotlightbulb",
"description": "A simple lightbulb show from a websocket",
"version": "0.1.0",
"license": "APACHE2.0",
"private": true,
"dependencies": {
"angular": "~1.4.0",
"angular-route": "~1.4.0",
"html5-boilerplate": "~5.2.0",
"ng-websocket": "~0.2.1",
"components-font-awesome": "components/font-awesome#~4.3.0"
}
}
index.html
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>The Socket bulb</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bower_components/html5-boilerplate/dist/css/normalize.css">
<link rel="stylesheet" href="bower_components/html5-boilerplate/dist/css/main.css">
<link rel="stylesheet" href="bower_components/components-font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="app.css">
<script src="bower_components/html5-boilerplate/dist/js/vendor/modernizr-2.8.3.min.js"></script>
</head>
<body ng-app="myApp">
<div class="container">
<!--[if lt IE 9]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<h1>Angular Lightbulb App</h1>
<div ng-view>Let there be light</div>
<ul class="menu">
<li><a href="#/bulbunknown">unknown</a></li>
<li><a href="#/bulbon">ON</a></li>
<li><a href="#/bulboff">OFF</a></li>
</ul>
</div>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/ng-websocket/ng-websocket.js"></script>
<script src="app.js"></script>
</body>
</html>
bulb-unknown.html
<p>The light <br/>
<span class="fa-stack fa-5x">
<i class="fa fa-lightbulb-o fa-stack-2x" style="color : #000044"></i>
<i class="fa fa-question-circle fa-stack-1x" style="color : red"></i>
</span>
</p>
bulb-on.html
<p>The light <br/>
<span class="fa-stack fa-5x">
<i class="fa fa-cog fa-stack-2x" style="color : yellow"></i>
<i class="fa fa-lightbulb-o fa-stack-2x" style="color : #FFAB00"></i>
</span>
</p>
bulb-off.html
<p>The light <br/>
<span class="fa-stack fa-5x">
<i class="fa fa-ban fa-stack-2x" style="color: red;"></i>
<i class="fa fa-lightbulb-o fa-stack-2x"> </i>
</span>
</p>
The CSS
/*app css stylesheet*/
.container {
margin : 25%;
width : 50%;
text-align: center;
}
.menu {
list-style: none;
border-top: 0.1em solid black;
margin-top: 2em;
padding: 0 0 0.5em;
}
.menu:before {
content: "[";
}
.menu:after {
content: "]";
}
.menu > li {
display: inline;
}
.menu > li:before {
content: "|";
padding-right: 0.3em;
}
.menu > li:nth-child(1):before {
content: "";
padding: 0;
}
As usual: YMMV
Posted by Stephan H Wissel on 24 August 2015 | Comments (0) | categories: Bluemix JavaScript NodeRED WebDevelopment