Comparing version 0.0.0 to 0.0.1
@@ -1,2 +0,2 @@ | ||
var Board, Promise, SerialPort, assert, events, serialport, | ||
var Board, Promise, SerialPort, assert, events, rfcontrol, serialport, | ||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, | ||
@@ -18,2 +18,4 @@ __hasProp = {}.hasOwnProperty, | ||
rfcontrol = require('rfcontroljs'); | ||
Board = (function(_super) { | ||
@@ -38,3 +40,3 @@ __extends(Board, _super); | ||
var args, cmd; | ||
console.log("data:", JSON.stringify(line)); | ||
_this.emit("data", line); | ||
if (line === "ready") { | ||
@@ -185,15 +187,18 @@ return; | ||
Board.prototype._handleRFControl = function(cmd, args) { | ||
var pulseLengths, pulses; | ||
var a, info, r, results, strSeq, _i, _j, _len, _len1, _ref; | ||
assert(args.length === 10); | ||
assert(args[0] === 'receive'); | ||
pulseLengths = args.slice(1, 9).map(function(v) { | ||
return parseInt(v, 10); | ||
}).filter(function(v) { | ||
return v !== 0; | ||
}); | ||
pulses = args[9]; | ||
this.emit('rfReceive', { | ||
pulseLengths: pulseLengths, | ||
pulses: pulses | ||
}); | ||
strSeq = args[1]; | ||
_ref = args.slice(2, 10); | ||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
a = _ref[_i]; | ||
strSeq += " " + a; | ||
} | ||
info = rfcontrol.prepareCompressedPulses(strSeq); | ||
this.emit('rfReceive', info); | ||
results = rfcontrol.parsePulseSquence(info.pulseLengths, info.pulses); | ||
for (_j = 0, _len1 = results.length; _j < _len1; _j++) { | ||
r = results[_j]; | ||
this.emit('rf', r); | ||
} | ||
}; | ||
@@ -200,0 +205,0 @@ |
{ | ||
"name": "homeduino", | ||
"version": "0.0.0", | ||
"version": "0.0.1", | ||
"description": "Node.js library for interfacing with the homeduino ardunio library", | ||
"main": "index.js", | ||
"files": [ | ||
"lib", | ||
"test", | ||
"src", | ||
"gulpfile.coffee", | ||
"gulpfile.js", | ||
"index.js", | ||
"LICENSE", | ||
"README.md" | ||
], | ||
"scripts": { | ||
@@ -11,3 +21,3 @@ "test": "echo \"Error: no test specified\" && exit 1" | ||
"type": "git", | ||
"url": "git://github.com/sweetpi/homeduino.git" | ||
"url": "git://github.com/pimatic/homeduinojs.git" | ||
}, | ||
@@ -17,7 +27,8 @@ "author": "Oliver Schneider <oliverschneider89+sweetpi@gmail.com>", | ||
"bugs": { | ||
"url": "https://github.com/sweetpi/homeduino/issues" | ||
"url": "https://github.com/pimatic/homeduinojs/issues" | ||
}, | ||
"dependencies": { | ||
"serialport": "~1.4.5", | ||
"bluebird": "~2.2.2" | ||
"bluebird": "~2.2.2", | ||
"rfcontroljs": "git+https://github.com/pimatic/rfcontroljs.git" | ||
}, | ||
@@ -24,0 +35,0 @@ "devDependencies": { |
110
README.md
@@ -1,93 +0,61 @@ | ||
rfcontroljs | ||
homeduinojs | ||
=========== | ||
rfcontroljs is a node.js module written to parse and construct 433mhz On-off keying (OOK) | ||
signals for various devices switches or weather stations. | ||
Node.js library for using [homeduino](https://github.com/sweetpi/homeduino). | ||
It works well together with the [RFControl](https://github.com/pimatic/RFControl) Arduino library | ||
for receving the signals. | ||
API | ||
--- | ||
The Processing Pipeline | ||
----------------------- | ||
### connect | ||
### 1. Receiving | ||
```CoffeeScript | ||
The arduino is connecte via serial bus to the processing computer (for example a raspberry pi) | ||
and waits for rf signal. | ||
Board = require('../index').Board | ||
board = new Board('/dev/ttyUSB0', 9600) | ||
> Mostly all 433mhzw OOK signals from devices are send multiple times directly in row and have a | ||
> longer footer pulse in between. They differ by the pulse lengths used to encode the data and footer | ||
> and the pulse count. | ||
[RFControl](https://github.com/pimatic/RFControl) running on the arduino detects the start of a | ||
signal by its longer footer pulse and verifies it one time by comparing it with the next signal. | ||
It does nothing know about the specific protocol, it just uses the stated fact above. Also we aren't | ||
interested in if the pulse was a high or low pulse (presence or absence of a carrier wave), | ||
because the information is decoded in the pulse lengths. | ||
We will call the received sequence of pulse lengths now **timings sequence**. For example a timing | ||
sequence in microseconds could look like this: | ||
board.connect().then( -> | ||
#do stuff | ||
).done() | ||
``` | ||
288 972 292 968 292 972 292 968 292 972 920 344 288 976 920 348 | ||
284 976 288 976 284 976 288 976 288 976 916 348 284 980 916 348 | ||
284 976 920 348 284 976 920 348 284 980 280 980 284 980 916 348 | ||
284 9808 | ||
``` | ||
You can clearly see the two different pulse lengths (around 304 and 959 microseconds) for the data | ||
encoding and the longer footer pulse (9808 microseconds). | ||
### readDHT(type, pin) | ||
All observed protocols have less than 8 different pulse length and all pulse length do differ by at | ||
least a factor of 2. This makes a further compression and simplification possible: We map each | ||
pulse length to a number from 0 to 7 (a bucket) and calculate for a better accuracy the average of | ||
all timings mapped to each of the bucket. The result is something like that: | ||
Read a dht sensor | ||
```CoffeeScript | ||
board.readDHT(22, 13).then( (ret) -> | ||
console.log ret.temperature, ret.humidity | ||
).done() | ||
``` | ||
buckets: 304, 959, 9808 | ||
pulses: 01010101011001100101010101100110011001100101011002 | ||
``` | ||
To make the representation unique, we choose the buckets in ascending order (respectively we are | ||
sorting it after receiving from the arduino). | ||
### rfControlStartReceiving(pin) | ||
We call the sorted buckets **pulse lengths**, the compressed timings **pulse sequence** and the | ||
length of the pulse sequence (inclusive footer) **pulse count**. | ||
```CoffeeScript | ||
### 2. Protocol Matching | ||
board.on "rfReceive", (event) -> | ||
console.log 'received:', event.pulseLengths, event.pulses | ||
We detect possible protocols by two criteria. The pulse length must match with a small tolerance | ||
and the pulse count must match. | ||
board.on "rf", (event) -> | ||
console.log "#{event.protocol}: ", event.values | ||
### 3. Protocol Parsing | ||
If a protocol matches, its `parse` function is called with the pulse sequence. Most protocols are | ||
parsed almost the same way. First the pulse squence must be converted to a binary representation. | ||
In almost all cases there exist a mapping from pulse sequences to a binary `0` and `1`. In this | ||
example the pulse sequence `0110` represents a binary `0` and `0101` maps to a binary `1`: | ||
```CoffeeScript | ||
pulsesToBinaryMapping = { | ||
'0110': '0' #binary 0 | ||
'0101': '1' #binary 1 | ||
'02': '' #footer | ||
} | ||
binary = helper.map(pulses, pulsesToBinaryMapping) | ||
board.connect().then( -> | ||
console.log "board ready" | ||
board.rfControlStartReceiving(0).then( -> | ||
console.log "receiving..." | ||
).done() | ||
).done() | ||
``` | ||
The binary reprsentation now looks like this: | ||
### pin read and writes | ||
``` | ||
110011000010 | ||
``` | ||
As last step the protocol dependend information must be extracted from the binary representation: | ||
```CoffeeScript | ||
result = { | ||
houseCode: helper.binaryToNumber(binary, 0, 5) | ||
unitCode: helper.binaryToNumber(binary, 6, 10) | ||
state: helper.binaryToBoolean(binary, 12) | ||
} | ||
board.digitalWrite(4, 1).done() | ||
board.analogWrite(1, 10).done() | ||
board.digitalRead(4).then( (value) -> | ||
console.log value | ||
).done() | ||
board.analogRead(4).then( (value) -> | ||
console.log value | ||
).done() | ||
board.pinMode(1, 0).done() | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Git dependency
Supply chain riskContains a dependency which resolves to a remote git URL. Dependencies fetched from git URLs are not immutable and can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
192
49402
3
10
61
1