naomi – layer zero labs https://l0l.org.uk.archived.website make it, break it, fix it, hack it, own it Sun, 24 May 2015 10:29:59 +0000 en-GB hourly 1 https://wordpress.org/?v=4.5.14 Idle Timeout in Express https://l0l.org.uk.archived.website/2015/02/idle-timeout-express/ https://l0l.org.uk.archived.website/2015/02/idle-timeout-express/#respond Tue, 03 Feb 2015 18:04:17 +0000 https://l0l.org.uk.archived.website/?p=696 Idle Timeout was not possible in express sessions until recently. You could set maxAge on the session’s cookie, but that would make the cookie expire after the given time regardless of activity. But it is more usual to want to expire the session after a certain amount of time with no activity. That is now possible […]

The post Idle Timeout in Express appeared first on layer zero labs.

]]>
Idle Timeout was not possible in express sessions until recently. You could set maxAge on the session’s cookie, but that would make the cookie expire after the given time regardless of activity. But it is more usual to want to expire the session after a certain amount of time with no activity. That is now possible with the rolling option.

Suppose you want to log users out automatically if they haven’t used your app for half an hour. You can do this with the following settings:

var idleTimeoutSeconds = 1800;

app.use(session({
resave: true,
cookie: {
maxAge: idleTimeoutSeconds * 1000,
},
rolling: true,

// … the rest of your options

}));

The rolling option is documented here but there’s a gotcha which is not mentioned: you have to set resave to true. It’s not obvious why this would be the case, since even without resave the session data is saved on change, and the rolling option appears to produce a change in the session upon every request. But without resave: true, I found that the session was expiring after the given time regardless of activity.

The post Idle Timeout in Express appeared first on layer zero labs.

]]>
https://l0l.org.uk.archived.website/2015/02/idle-timeout-express/feed/ 0
Squatconf Presentation https://l0l.org.uk.archived.website/2014/11/squatconf-presentation/ https://l0l.org.uk.archived.website/2014/11/squatconf-presentation/#respond Sat, 15 Nov 2014 16:16:02 +0000 https://l0l.org.uk.archived.website/?p=601 We’re at SquatConf. It’s amazing! All conferences should be in squats. (Ones that serve good quality beer on draft, in particular. And where you can have  a cigarette while you’re presenting). Here are the slides for the presentation we just gave. And here’s our alternative translation of the heart sutra (now on Github!) Avalokitesvara the Origin Mistress […]

The post Squatconf Presentation appeared first on layer zero labs.

]]>
We’re at SquatConf. It’s amazing! All conferences should be in squats. (Ones that serve good quality beer on draft, in particular. And where you can have  a cigarette while you’re presenting).

Here are the slides for the presentation we just gave. And here’s our alternative translation of the heart sutra (now on Github!)

Avalokitesvara the Origin Mistress
when debugging deeply the Undefined Paramita
perceives that all of the log files are empty
and is saved from all suffering and distress.

Oh Javascript Programmer,
objects do not differ from null,
null is merely a kind of object.
Undefined is a function,
and all functions are undefined.
The same is true of strings,
integers, arrays, truth or falsehood.

Programmer,
the features of Javascript are also its bugs;
never released and never abandoned,
neither supported or unsupported,
neither maintained nor deprecated.
Therefore, in Javascript no bugs, features,
commits, reverts, authors.

No types, no classes, no entities, no attributes,
no private, no public, no package, no friends,
no runtime context;
no state or scope
and so forth until no realm of computation.

No errors and also no catching of errors,
and so forth until no breaking or crashing
and no end of crashing and breaking.

Nothing synchronous, nor asyncronous,
no pushing no popping, no heap no stack
also no returning with nothing to return.

The Origin Mistress accepts the Undefined Paramita
and logic is no hindrance.
without any logic no programs exist.
Realising this, good code is created.
(So good, it even runs in Internet Explorer.)

In the three browsers
all Programs depend on Undefined Parameters,
on Max that is less than Min, and the Number that Not a Number.

Therefore know that the Undefined Parameter
is the great transcendent mantra,
is the great bright mantra,
is the utmost mantra,
is the supreme mantra
which is able to relieve all suffering
and is truthy, insofar as it is not falsey.

So proclaim the Undefined Paramita mantra,
proclaim the mantra which says:
Object does not support this property or method.

 

The post Squatconf Presentation appeared first on layer zero labs.

]]>
https://l0l.org.uk.archived.website/2014/11/squatconf-presentation/feed/ 0
Reading multiple sensors – rfm12b_linux and node-red https://l0l.org.uk.archived.website/2014/03/reading-multiple-sensors-rfm12b_linux-and-node-red/ https://l0l.org.uk.archived.website/2014/03/reading-multiple-sensors-rfm12b_linux-and-node-red/#comments Sat, 29 Mar 2014 16:15:21 +0000 https://l0l.org.uk.archived.website/?p=382 RFM12b module vs. Jeelink This post follows on from this one where Gareth explains how to use an RFM12b module with an RPi. To recap, the RFM12b module is a radio transciever like the Jeelink, but it is much cheaper. It is, however, slightly harder to use. The Jeelink connects via USB and is immediately exposed as […]

The post Reading multiple sensors – rfm12b_linux and node-red appeared first on layer zero labs.

]]>
RFM12b module vs. Jeelink

This post follows on from this one where Gareth explains how to use an RFM12b module with an RPi. To recap, the RFM12b module is a radio transciever like the Jeelink, but it is much cheaper. It is, however, slightly harder to use. The Jeelink connects via USB and is immediately exposed as a serial port. But this RFM12b module is soldered directly onto the (in this case) Raspberry Pi. It requires installing the rfm12b_linux kernel module, which creates a /dev/ entry. This is explained in the previous post.

rfm12b_linux and node-red

This section deals with using rfm12b_linux and node-red in particular. The rest of the post applies just as much to the Jeelink. Assuming you have a stream of data being received by the RFM12b module, the next question is how to make use of that data in node-red. (This example assumes node-red is running on the RPi itself). Given that the RFM12b module is exposed as a device, our first thought was to simply tail it like a file. But this did not seem to work, as was borne out by the nonsensical output of  as using cat on the command line. But luckily, when you get the kernel module from github, it comes with some example code. One of the examples, rfm12b_read, is extremely useful. It interprets the data and relays it to standard out in the form of nice human readable strings.

Using the exec node, you can simply run the rfm12b_read script directly in node-red. You just need to tell the node the location of the script, and set it to spawn() rather than exec(). This latter step tells it to give you the data in chunks as it comes it, rather than all at once in a big pile!

Add an injector to the left of the exec node, set to start automatically, and that is all there is to reading the data into node-red.

rfm12b_linux and node-red

Sorting and parsing data from multiple sensors

In the RFM12b protocol (used by Jeenode and Jeelink as well as the RFM12b module), you specify a group id and a node id for each device. In this case we have a number of different sensors all broadcasting data and a central base station (the RPi) that needs to listen to them all. In the sensor-side code (which I won’t go into here), we set the group id to the same for all the sensors, but gave each one a different node ID. That way the RPi can listen to all the sensors in the group, and also be able to tell them apart.

In this example the RPi is receiving data from a RoomNode and also from this pH sensor, fresh from the Layer Zero Labs inventory

ph_boxph_inside

(I’m sure Gareth will be along with a post soon to describe the hardware.)

Back to node-red … basically it is just a case of using a switch node to decide which sensor the data is coming from, and then ordinary function nodes to extract meaningful values from it. However there are a few gotchas at this stage. Also the way we have done it is probably not the best, so go carefully!

The rfm12b_read script appends the date and some other information to the beginning of each set of data. It produces something like this:

Sat Mar 29 15:52:48 2014 6 bytes read 3 4 0 88 234 0

In this case 3 is the node id (meaning that it is the roomnode), 4 means that there are four bytes to follow, and the rest is the actual raw sensor data.

However this is not a string as such but a buffer object, which node-red signifies by appending “(Buffer)” so that the actual payload is:

(Buffer) Sat Mar 29 15:52:48 2014 6 bytes read 3 4 0 88 234 0

I confess to not having researched what a buffer object is, but it is stringy enough to pass it through a switch node like this:

switchnodeThe switch node looks for the string “33 2”. i.e. node id 33 and 2 bytes to follow, or conversely “3 4”, node id 3 and 4 bytes to follow. This sorts out the data streams from different sensors, while doing a very cursory check that it is not malformed.

The first gotcha is that I tried to check for it containing “6 bytes read 3” or the like, so as to be more sure that it was not malformed, but this did not work, which is probably something to do with the buffer not being exactly a string.

Once the data is sorted into the correct streams, the next thing to do is to parse it. I chose to split the payload into an array, using space as the delimiter, and then use pop() to read each byte in turn. Here’s the second gotcha: the buffer object needs a toString() before it can be split(). The third gotcha is that it also has a newline on the end, so throw away the result of the first pop().

Also be aware that the data is in bytes, and of the byte order.

// function: Parse pH

var dataArray = msg.payload.toString().split(‘ ‘);

dataArray.pop(); // last element is newline

var pHMSB = dataArray.pop();
var pHLSB = dataArray.pop();
var pH = 256* parseFloat(pHMSB)+ parseFloat(pHLSB);

var pHMsg = {payload: pH};

return [pHMsg];

The pH is a single sensor, but the roomnode includes data from various sensors, in our case temperature and humidity, so the code is a little more complex and the function has two outputs, one for each sensor:

// function: Parse Roomnode

var dataArray = msg.payload.toString().split(‘ ‘);

dataArray.pop(); // last element is newline

var tempMSB = dataArray.pop();
var tempLSB = dataArray.pop();
var humidity = dataArray.pop();
var temp = 256* parseFloat(tempMSB)+ parseFloat(tempLSB);

var humidityMsg = {payload: humidity};
var tempMsg = {payload: temp};

return [humidityMsg, tempMsg];

Because of the way we have the gain set, some of the data needs dividing by 10 or 100 after that, hence the scale functions.

multisense

Onward …

My next steps for this:

1. Get a better understanding of what the rfm12b_read script does, and why the data can’t be read directly from the /dev/ or if it can, then what I was doing wrong when I tried it.

3. Understand the buffer object and therefore maybe be able to use some of the metadata as a check against corruption. Otherwise, avoid reading in the date and time etc. just to then throw it away.

The post Reading multiple sensors – rfm12b_linux and node-red appeared first on layer zero labs.

]]>
https://l0l.org.uk.archived.website/2014/03/reading-multiple-sensors-rfm12b_linux-and-node-red/feed/ 1
Node-red web page – an example to get you started https://l0l.org.uk.archived.website/2014/01/simple-node-red-web-page/ https://l0l.org.uk.archived.website/2014/01/simple-node-red-web-page/#comments Sat, 11 Jan 2014 19:16:33 +0000 https://l0l.org.uk.archived.website/?p=275 NB: I no longer think this is a good way to do this! It was a first go, and there is a lot wrong with it.  I intend to revisit the web-page idea at some point, and will post something better then. Now we use Freeboard to display data – there is a freenode node […]

The post Node-red web page – an example to get you started appeared first on layer zero labs.

]]>
NB: I no longer think this is a good way to do this! It was a first go, and there is a lot wrong with it.  I intend to revisit the web-page idea at some point, and will post something better then.

Now we use Freeboard to display data – there is a freenode node for node-red in the contrib section – it makes it super easy to setup and configure. See http://incredibleaquagdn.no-ip.info/?load=dashboard.json for an example of how it looks.

A simple node-red web page

In the aquaponics installation we’re working on, node-red is running on a raspberry pi controlling an aquaponics system. It receives mqtt messages every second containing the readings from various sensors.

I wanted to create a simple web page that displays the data from each sensor, updating every 2 seconds.

I’m quite new to the Internet of Things and to event-driven programming in general, so if you are already an expert you will probably think my solution is hacky for all the wrong reasons. If so feel free to comment … constructively 🙂 For example, I suspect a “proper” node-red web page solution might involve node-red pushing data to the page in real time, but I’m going to keep it simple here and let it poll for its data.

Components:

1. A web page (HTML and Javascript) that sends an HTTP request to node-red every 2 seconds  and displays the data returned

2. A node-red object that knows the latest values of all the sensors

3. An httpRequest node configured to accept the page’s requests, triggering a flow that grabs the sensor values and returns them to the page via a httpResponse.

Http request and response in node-red

I jumped in with the node-red bit first, being the most fun. To simulate the messages containing sensor data I mocked up some streams of data using injectors.

node-red web page stage 1

Data buffer

The data buffer keeps hold of the latest sensor data, passing it through to the http response when a request comes in. It works like this: when a message arrives on a sensor data topic, it updates its array of sensor values, and exits. But when it receives a message via the http request node, it adds the latest data into the message object.

context.data = context.data || new Object();
switch (msg.topic) {
    case "concavity":
        context.data.concavity = msg.payload;
        msg = null;
        break;
    case "altitude":
        context.data.altitude = msg.payload;
        msg = null;
        break;
    default:
        msg.data = context.data;
}
return msg;

 

Page template

This is the html for the full page.

Hello there 
Altitude: {{data.altitude}}
Concavity: {{data.concavity}}
Other configuration

The http request node is configured for the url /boo and the GET method. The http response node needs no configuration.

Full flow
[{"id":"66f381b0.990c8","type":"http response","name":"http out","x":657,"y":233,"z":"ad00793e.52ff88","wires":[]},{"id":"ec3dfdc9.13c2","type":"http in","name":"http in","url":"/boo","method":"get","x":129,"y":329,"z":"ad00793e.52ff88","wires":[["ab90d0fa.546f3"]]},{"id":"cad43099.352bd","type":"template","name":"Page Template","template":"Hello there <br />\n\nAltitude: {{data.altitude}}<br />\nConcavity: {{data.concavity}}","x":485,"y":232,"z":"ad00793e.52ff88","wires":[["66f381b0.990c8"]]},{"id":"1c8929d0.e376d6","type":"inject","name":"","topic":"altitude","payload":"3","repeat":"3","crontab":"","once":false,"x":140,"y":216,"z":"ad00793e.52ff88","wires":[["ab90d0fa.546f3"]]},{"id":"315341ba.ceacbe","type":"inject","name":"","topic":"concavity","payload":"65","repeat":"2","crontab":"","once":false,"x":138,"y":271,"z":"ad00793e.52ff88","wires":[["ab90d0fa.546f3"]]},{"id":"ab90d0fa.546f3","type":"function","name":"Data buffer","func":"context.data = context.data || new Object();\nswitch (msg.topic) {\n    case \"concavity\":\n        context.data.concavity = msg.payload;\n        msg = null;\n        break;\n    case \"altitude\":\n        context.data.altitude = msg.payload;\n        msg = null;\n        break;\n    default:\n    \tmsg.data = context.data;\n}\nreturn msg;","outputs":1,"x":319,"y":230,"z":"ad00793e.52ff88","wires":[["cad43099.352bd"]]},{"id":"261b1fb8.d9e4e","type":"inject","name":"","topic":"altitude","payload":"2","repeat":"2","crontab":"","once":false,"x":143,"y":169,"z":"ad00793e.52ff88","wires":[["ab90d0fa.546f3"]]}]

If you deploy this and point your browser to localhost:1880/boo then you should see the (very simple) page. It won’t update automatically, but if you keep refreshing you should see the altitude changing from 2 to 3.

Node-red really is awesome. It’s amazing how quickly you can get something up and running, end to end. This delightfully bare-bones way of getting started was inspired by this node-red web page suggestion by knolleary here

Auto-update using Javascript

Well I thought I was starting with the node-red bit and would have to go on to web servers and static templates and so on later. But in the course of looking for a simple way to add the auto-update functionality, I ended up with a totally node-red web page – everything about it is programmed in node-red.node-red web page auto-update

There are two urls serving http requests – /web and /data. When you go to /web it serves up a simple page with a placeholder div and a js script. The script sets a function to run every 2 seconds. The function sends a request to /data and replaces the text in the div with the response, i.e. the latest sensor data (here mocked out by injectors publishing timestamps).

Auto Update Script

The auto update script node is also just a template but it contains the script that will kick off the auto-updating. The URL is hard-coded.

<script>
    setInterval(function(){	
	    var theUrl = "http://localhost:1880/data";
	    var xmlHttp = new XMLHttpRequest();
	    xmlHttp.open( "GET", theUrl, false );
	    xmlHttp.send( null );
	    document. getElementById('data')
	    	.innerHTML = xmlHttp.responseText;
    },2000);
</script>
<div id="data">... Loading ...</div>

The result is that if you go to localhost:1880/web it should say “Loading …” for a few seconds and then start to display the data, updating every 2 seconds as required.

Future Improvements

Clearly this is just a proof of concept. Where to go next?

  • Appearance. Present the data in a nice format on the page.
  • Improve the code. The hard-coded url is yucky and the html markup is … minimal. Also something doesn’t feel right about having the js script as text in the template node, but maybe it’s fine.
  • Add the ability to send requests in the other direction, from the web page and have node-red act on them.
  • Add a download option for historical data
  • etc.

Comments welcome

Have a nice day

The post Node-red web page – an example to get you started appeared first on layer zero labs.

]]>
https://l0l.org.uk.archived.website/2014/01/simple-node-red-web-page/feed/ 17
Using the ACS712 Low Current Sensor https://l0l.org.uk.archived.website/2013/11/using-the-acs712-low-current-sensor/ https://l0l.org.uk.archived.website/2013/11/using-the-acs712-low-current-sensor/#respond Sat, 09 Nov 2013 22:05:41 +0000 https://l0l.org.uk.archived.website/?p=100 Gareth and I are using  ACS712 Low Current Sensors in our Aquaponics project. We’re using them to measure AC current. All we really need them to tell us is whether various pumps are on (and drawing 1/6 of an amp) or off. The raw value you get when you do an analogRead on the pin varies […]

The post Using the ACS712 Low Current Sensor appeared first on layer zero labs.

]]>
ACS712 Low Current SensorGareth and I are using  ACS712 Low Current Sensors in our Aquaponics project. We’re using them to measure AC current. All we really need them to tell us is whether various pumps are on (and drawing 1/6 of an amp) or off.

The raw value you get when you do an analogRead on the pin varies between 0 and 1024. When there is no current flowing, ideally the value should be 512. When current is flowing, it should oscillate around 512 as its centre point.

There are two pots on the ACS712 board – one for gain and one for offset. You can see them in this picture.

The offset pot should be set so that when no current is flowing, the raw reading is 512. The gain pot should be set so that when you apply the sort of current you want to measure, it varies considerably (remember we’re talking AC here) but doesn’t get too close to either extreme. Varying between 200 and 824 is a reasonable choice.

Hardware Calibration

For the hardware calibration stages, run a routine that outputs the raw value from the pin a few times a second. Three times is a good choice as 3 doesn’t go into 50Hz.

1. Set the offset pot

Turn off the current and fiddle with the offset pot until the reading is about 512. It varies a little even without the current being applied, so guesswork is involved.

Either there’s something about the ACS712 we don’t understand / are doing wrong, or the offset pot is vastly over-sensitive. Even with the gain set quite low, it jumps between 200 and 600 or so at the tiniest touch. I had to settle for an average of about 560 – I couldn’t get any closer. Turning up the gain at this stage would ideally make your setting more accurate, but in reality it doesn’t help.

2. Set the gain pot

Now, with the same routine running, apply a current (of the value you intend to measure) and start twiddling the gain pot until you see highs of around 800 and lows of around 200.

Software Calibration and Code

This is the code we are using to turn the oscillating values received from the ACS712 into an actual AC current reading:

float total = 0;
for (int i = 0; i < numberOfSamples; i++) {
float current = analogRead(pin) – 512;
total += current * current ;
}
value = abs(sqrt (total / numberOfSamples) – offset) * multiplier ;

The numberOfSamples variable is a class constant equal to 1000. The offset and multiplier are passed in by the calling code. We’re using three different sensors and they all need different ones, because it’s impossible to set the pots identically, but probably also due to differing lengths of wire.

The code works by adding up the squares of a thousand readings, then taking the root mean square. The multiplier is there to produce a reading in a real life unit – amps.

Because we couldn’t get rid of the offset in hardware, we have to compensate for it in software. I’m not convinced we’re doing it right; I can’t help thinking the offset should be taken off at the beginning, before all the squaring and averaging. But given that we’ve done it that way, here’s how to finish off the calibration.

1. Set the offset variable

At this point you need to run the code, rather than just output the raw readings. Start with your offset variable equal to 0 and your multiplier to 1, so that they have no effect.

Now turn off the current and watch the output. Set the offset variable to the number that gets it as close to zero as you can.

[Edit: It’s actually easier to do this if you remove the abs() from the code]

2. Set the multiplier variable

Now apply a known current. Find the multiplier that gives you a reading of that current.

If you have a better way to calibrate the ACS712, or better code to process the reading, please leave a comment and let us know!

The post Using the ACS712 Low Current Sensor appeared first on layer zero labs.

]]>
https://l0l.org.uk.archived.website/2013/11/using-the-acs712-low-current-sensor/feed/ 0