empowering creative people

Showcase Image

Introduction

If you haven't already seen it, check out part 1 of this project. it has all the background info in it. And if you haven't got one yet, get yourself a particle photon, they are great.

This part of the project was hooking the particle photons up to a very simple web page that would let me remotely check the status of the systems and control them as I see fit. From here on it will help if you know a little of html, css and java-script! Also, I'm no expert so there may be a better way of doing things so use of the following code is at your own risk.


Project Description

Now that the devices are connected to the could and accepting commands back and forth there are a couple of options for pushing the information to and from the devices. Web hooks are one way, but I chose to try the JavaScript api built into the JavaScript of the web page. There are security issues with this, the JavaScript is executed browser side ... so a set of particle credentials are passed to the browser. I'm only doing this as an interim measure, if you do it... just make sure you put the files in a secure part of your server.

Now to the detail. First of all I built a simple web page, I got a little fancy and used my own icon fonts, (so I can change the colour of them dynamically) but basically this is a simple page and each element has an #id tag.

The colour of the 'machine icon' represents its state, in this case, connected is green, red is manually overridden, etc. The code to make this happen is quite straight forward, however one issue had me tearing my hair out for a while! JavaScript is executed asynchronously, so you must use call back functions! If you don't the functions don't wait for the returned values from the particle server and you just get 'null' results for everything. Coming from a C background this was incredibly frustrating to get my head around!

So the basic way to code it is as follows. First declare some variables;

var particle = new Particle();
var token = 'your actual access token ... remember what I said about security';
var deviceID = 'your actual device ID';
//... for all of your devices var lastUpdatedDate;
var deviceConnected;
var variableStatus;
var otherVariableStatus;

Now we create a handler so that when the page is ready it will poll the device;

$ (document).ready(
function(){
PollVariable(DeviceId, 'the variable name being polled', token, callBackFunction);
AttachButtonScript();
}
)

function PollVariable(DeviceID, VarName, token, callback) {
particle.getVariable({ deviceId: DeviceID, name: VarName, auth: token }).then(function (data) { callback(data, null); }, function (err) { console.error(VarName, ' error...:', err); callback(null, 'error'); });
}

The data passed to the callback function is actually a data object, which contains quite a bit of information. We are only really interested in a few things though, so now we use those in the callback to fill our global status variables and pass them to the function that updates the icons;

function callBackFunction(data, error){ 
	if(data.body.coreInfo.last_heard != null){
		lastUpdatedDate = dateObject = new Date(Date.parse(data.body.coreInfo.last_heard));
	}
	
	if(data.body.coreInfo.deviceID == DeviceId){
		if(data.body.coreInfo.connected == false) { 
			console.error('Device is not connected')
		} else {
			deviceConnected = true;
			if(data.body.name == 'Your variable name') {
				variableStatus = data.body.result;
				if(data.body.name == 'Your other variable name') {
					otherVariableStatus = data.body.result;
					//now check whether all of the variables have been polled successfully, if they have move on to update the icons
					if(variableStatus != null && otherVariableStatus != null){
						UpdateSwitch(variableStatus, otherVariableStatus, 'the ID tag of the html item to update');
					}
					UpdateIcon(deviceConnected, 'the ID tag of the icon to update');
				}
			}
		}
	}
}

And now we update the styling;

function UpdateSwitch(Var1, Var2, SwitchId) {
if (Var1 == true) {
document.getElementById(SwitchId).style.color = 'colour one';
} else if (Var2 == true) {
document.getElementById(SwitchId).style.color = 'colour two';
} else {
document.getElementById(SwitchId).style.color = 'colour three';
}
}

function UpdateIcon(Var1, IconID) {
if (Var1 === true) {
document.getElementById(IconID).style.color = 'colour one';
} else {
document.getElementById(IconID).style.color = 'colour two';
}
}

Now we create a handler to regularly call that routine and keep the page up to date;

setInterval(
function() {
variableStatus = null;
otherVariableStatus = null;
PollVariable(deviceID, 'variable name', token, callBackFunction);
PollVariable(deviceID, 'other variable name', token, callBackFunction);
}, (1000*60)); //1 minute interval

The next thing we need to do is attach a button script to the switch buttons. This is called from our document ready function.

function attachButtonScript() {
document.getElementById("compressorSwitch").onclick = function() {
var fnPr = particle.callFunction({ deviceId: deviceId, name: 'function name', argument: 'the argument', auth: token});
fnPr.then(function(data) { PollVariable(deviceId, 'variable that should have changed', token, callBackFunction); },
function(err) {
console.log('An error occurred:', err);
});
};

And that's basically it! I used the above code to extend the functionality further and created the detailed settings page for each device, as you can see I have a few other sensors attached to the compressor, maybe I got a little carried away :S

So what are you waiting for, get a photon and start coding.