...
 
Commits (2)
BSD 3-Clause License
Copyright (c) 2017, Otso Jousimaa
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# node-red
Node red trials, may or may not suit any purpose.
# RuuviTag node
## About
Listens to node-red-contrib-noble messages, and parses RuuviTag weather station data in high resolution mode.
Puts sensor data to msg.payload as JSON, contains: temperature, humidity, pressure, accelerationX, accelerationY, accelerationZ, battery. Units are:
- Temperature: Celcius
- Humidity: RH-%
- Pressure: Pascal
- Acceleration: milli-G
- Battery: mV
Currently version 0.0.3, i.e. alpha-quality. All comments and suggestions are welcome, please open pull-requests (and comment that BSD-3 is ok) if you
want to contribute. Suggestions for improvement can be given as github issues.
## Installing
Clone the repository to you computer, and in the root of project (i.e. folder with package.json) run
`sudo npm link `.
Then in your node red directory (typically ~/.node-red) run ` npm link node-red-contrib-ruuvitag `.
Project additionally depends on node-red-contrib-noble, but there is no proper dependency management yet.
Run manually ` sudo npm install -g node-red-contrib-noble `. You also need bluetooth stack used by noble,
for details please see [noble install instructions](https://github.com/kmi/node-red-contrib-noble).
Please update your machine if you're having syntax errors, see issue #1 for details.
## Usage
Allow duplicates in noble configuration, and set scan=true to noble node. Connect noble output to RuuviTag input,
and parse RuuviTag data as you wish.
![Example flow](./images/nodered_ruuvinode_flow.png)
To setup physical RuuviTags in high-resolution binary mode, install latest "Weather Station" firmware and
press "B" once to enter into high resolution mode. Red Led should be blinking approximately once per second once your tag is in correct mode.
For details please see (ruuvi website)[https://ruu.vi].
{
"_from": "git://github.com/ojousima/node-red.git#c5012850b1a4f0bae8131da895633b228c145c76",
"_id": "node-red-contrib-ruuvitag@0.0.2",
"_inBundle": false,
"_location": "/node-red-contrib-ruuvitag",
"_phantomChildren": {},
"_requested": {
"type": "git",
"raw": "node-red-contrib-ruuvitag@git://github.com/ojousima/node-red.git#c5012850b1a4f0bae8131da895633b228c145c76",
"name": "node-red-contrib-ruuvitag",
"escapedName": "node-red-contrib-ruuvitag",
"rawSpec": "git://github.com/ojousima/node-red.git#c5012850b1a4f0bae8131da895633b228c145c76",
"saveSpec": "git://github.com/ojousima/node-red.git#c5012850b1a4f0bae8131da895633b228c145c76",
"fetchSpec": "git://github.com/ojousima/node-red.git",
"gitCommittish": "c5012850b1a4f0bae8131da895633b228c145c76"
},
"_requiredBy": [
"/"
],
"_resolved": "git://github.com/ojousima/node-red.git#c5012850b1a4f0bae8131da895633b228c145c76",
"_spec": "node-red-contrib-ruuvitag@git://github.com/ojousima/node-red.git#c5012850b1a4f0bae8131da895633b228c145c76",
"_where": "/home/donald/git/rigado-devkit",
"bundleDependencies": false,
"dependencies": {},
"deprecated": false,
"description": "RuuviTag data parser",
"keywords": [
"test"
],
"name": "node-red-contrib-ruuvitag",
"node-red": {
"nodes": {
"ruuvitag": "ruuvi-node/ruuvitag.js"
}
},
"version": "0.0.2"
}
<script type="text/javascript">
RED.nodes.registerType('ruuvitag',{
category: 'advanced',
color: '#a6bbcf',
defaults: {
name: {value:""}
},
inputs:1,
outputs:1,
icon: "ruuvitag.png",
label: function() {
return this.name||"RuuviTag";
}
});
</script>
<script type="text/x-red" data-template-name="ruuvitag">
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="RuuviTag">
</div>
</script>
<script type="text/x-red" data-help-name="ruuvitag">
<p>Takes node-red-contrib-noble scan object as input and replaces payload with JSON containing parsed data from Ruuvitag.</p>
<p>Payload fields (i.e. msg.payload.) are temperature, humidity, pressure, accelerationX, accelerationX, accelerationX, battery. Units are:</p>
<ul>
<li>Temperature: Celcius</li>
<li>Humidity: RH-%</li>
<li>Pressure: Pascal</li>
<li>Acceleration: milli-G</li>
<li>Battery: mV</li>
</ul>
<p>You might also be interested in other noble message data, such as msg.rssi or msg.peripheralUUID</p>
</script>
"use strict";
module.exports = function(RED) {
function RuuviTagNode(config) {
RED.nodes.createNode(this,config);
var node = this;
node.on('input', function(msg) {
//Expects noble manufacturer data
if(!msg.advertisement || !msg.advertisement.manufacturerData){
return null;
}
let manufacturerDataString = msg.advertisement.manufacturerData.toString('hex');
let ruuviData = parseRuuviData(manufacturerDataString);
if(!ruuviData){
return null;
}
msg.payload = JSON.stringify(ruuviData);
node.send(msg);
});
}
RED.nodes.registerType("ruuvitag",RuuviTagNode);
}
var parseRuuviData = function(manufacturerDataString){
let formatStart = 4;
let formatEnd = 6;
let formatRAW = "03";
let dataFormat = manufacturerDataString.substring(formatStart, formatEnd);
let dataObject = {};
switch(dataFormat)
{
case formatRAW:
dataObject = parseRawRuuvi(manufacturerDataString)
break;
default:
//console.log("Unknown dataformat: " + dataFormat);
dataObject = null;
}
return dataObject;
}
//https://github.com/ruuvi/ruuvi-sensor-protocols
var parseRawRuuvi = function(manufacturerDataString){
let humidityStart = 6;
let humidityEnd = 8;
let temperatureStart = 8;
let temperatureEnd = 12;
let pressureStart = 12;
let pressureEnd = 16;
let accelerationXStart = 16;
let accelerationXEnd = 20;
let accelerationYStart = 20;
let accelerationYEnd = 24;
let accelerationZStart = 24;
let accelerationZEnd = 28;
let batteryStart = 28;
let batteryEnd = 32;
let robject = {};
let humidity = manufacturerDataString.substring(humidityStart, humidityEnd);
//console.log(humidity);
humidity = parseInt(humidity, 16);
humidity/= 2; //scale
robject.humidity = humidity;
let temperatureString = manufacturerDataString.substring(temperatureStart, temperatureEnd);
let temperature = parseInt(temperatureString.substring(0, 2), 16); //Full degrees
temperature += parseInt(temperatureString.substring(2, 4), 16)/100; //Decimals
if(temperature > 128){ // Ruuvi format, sign bit + value
temperature = temperature-128;
temperature = 0 - temperature;
}
robject.temperature = +temperature.toFixed(2); // Round to 2 decimals, format as a number
let pressure = parseInt(manufacturerDataString.substring(pressureStart, pressureEnd), 16); // uint16_t pascals
pressure += 50000; //Ruuvi format
robject.pressure = pressure;
let accelerationX = parseInt(manufacturerDataString.substring(accelerationXStart, accelerationXEnd), 16); // milli-g
if(accelerationX > 32767){ accelerationX -= 65536;} //two's complement
let accelerationY = parseInt(manufacturerDataString.substring(accelerationYStart, accelerationYEnd), 16); // milli-g
if(accelerationY > 32767){ accelerationY -= 65536;} //two's complement
let accelerationZ = parseInt(manufacturerDataString.substring(accelerationZStart, accelerationZEnd), 16); // milli-g
if(accelerationZ > 32767){ accelerationZ -= 65536;} //two's complement
robject.accelerationX = accelerationX;
robject.accelerationY = accelerationY;
robject.accelerationZ = accelerationZ;
let battery = parseInt(manufacturerDataString.substring(batteryStart, batteryEnd), 16); // milli-g
robject.battery = battery;
return robject;
}
This diff is collapsed.
{
"name": "rigado-devkit",
"version": "1.0.0",
"version": "1.0.1",
"description": "",
"main": "index.js",
"scripts": {
......@@ -9,7 +9,8 @@
"node-red": {
"nodes": {
"noble-connect": "noble-connect/node-red-noble-connect.js",
"noble-scan": "noble-scan/node-red-contrib-noble.js"
"noble-scan": "noble-scan/node-red-contrib-noble.js",
"node-red-contrib-ruuvitag": "node-red-contrib-ruuvitag/ruuvi-node/ruuvitag.js"
}
},
"keywords": [],
......