Skip to content

Commit

Permalink
matrix scale features
Browse files Browse the repository at this point in the history
  • Loading branch information
readeral committed Sep 2, 2018
1 parent 07a89ab commit 533bd1e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 31 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,23 @@ When it comes to processing the input from the Nuimo, I've left this largely up
- Distance (when the sensor is activated with a long touch on the top)
You receive unadulterated event data from the Nuimo for all these actions, with the exception of button press. 'Press' is actually triggered on 'Release' in order to implement the long-press app switcher function. This means you're unable to program your own button holding rules, but I hope this trade-off is a small price to pay for a nicer app switcher. Maybe down the track I'll program the option to change how the app switcher is invoked.

## Using the matrix node
The matrix node allows your Nuimo to respond to changes in your smart home environment, like increased volume or brightness, or alerting you to something's completion.

At the most basic level you can define the matrix's output using it's editor interface and GUI input, or you can pass a payload with instructions on how to update the display, using it's inbuilt methods or completely raw.

The matrix node will respond first to payload instructions before defaulting back to the editor interface options.

See the editor help on the matrix node for more information.

### Known issues yet to be fixed
- Currently node-red needs to be stopped and restarted if the latest deploy was a 'full' deploy, due to the config node (which maintains the bluetooth connection) not cleaning up properly. **To get around this problem on the regular, make use of the Modified Flows deployment option**, unless you've made changes to the config node, in which case you'll have to restart Node Red. (N.b This is related to an [outstanding pull request on the Noble BLE library](https://github.com/noble/noble/pull/577), so likely won't be resolved until it is merged )
- If activeApp (in the global context) is updated programatically rather than through the Nuimo controller, then you lose the ability to bring up the app switcher. Until this is resolved, avoid changing that variable via function nodes.

### Future plans
- Implement an optional 'translator' for raw rotation data making it a bit easier to use.
- Further to this, implement a 'momentum' feature that picks up on increased rotation speed

### Contribution guide
- If you'd like to be a maintainer, just let me know! :)
- Requests for tests are warmly encouraged, [pending a discussion on a suitable testing approach](https://github.com/readeral/node-red-contrib-nuimo-controller/issues/1).
Expand Down
11 changes: 6 additions & 5 deletions config/nuimo-config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
//Needs to 'hold' the bluetooth connection and expose it to the various 'normal' nodes

module.exports = function(RED) {
let Timeout = require('../Timeout');
function nuimoConfigNode(n) {
RED.nodes.createNode(this,n);
var globalContext = this.context().global;
var node = this;

if (!globalContext.get("activeApp")) {
globalContext.set("activeApp", "pending");
}
var activeApp = globalContext.get("activeApp");
var activeApp = globalContext.get("activeApp") || "pending";
var sensitivity = globalContext.get("sensitivity") || [70, 800];

let Timeout = require('../Timeout');
let Nuimo = require('nuimojs'),
nuimo = new Nuimo();

Expand Down Expand Up @@ -46,8 +43,10 @@ let Timeout = require('../Timeout');
device.on("release", () => {
Timeout.clear('extender');
if (Date.now() - longPress < sensitivity[1]) {
longPress = null;
node.emit('press', activeApp)
} else {
longPress = null;
node.emit('longPress')
}
})
Expand Down Expand Up @@ -97,13 +96,15 @@ let Timeout = require('../Timeout');
device.connect();

node.on('close', function() {
device.disconnect();
device.removeAllListeners();
});
});

nuimo.scan();

node.on('close', function () {

nuimo.stop();
nuimo.removeAllListeners();
delete nuimo;
Expand Down
19 changes: 18 additions & 1 deletion matrix/nuimo-set-matrix.html
Original file line number Diff line number Diff line change
Expand Up @@ -347,5 +347,22 @@ <h4>App Matrix Image</h4>
</script>

<script type="text/x-red" data-help-name="nuimo-set-matrix">
<p>A node for creating a matrix to pass through to the Nuimo output node. The matrix value is passed via msg.setMatrix property</p>
<h2>A node for creating a matrix to pass through to the Nuimo output node.</h2>
<h4>Editor settings</h4>
<p>Setting the parameters on the node editor should be relatively straightforward:</p>
<p>To define an LED array output for your app, click the circles in the grid to 'turn on' or 'turn off' that pixel. You can start from a preset available in the drop down, or copy in your own comma-delimited string of 1s and 0s into the String input field.</p>
<br />
<h4>Inbuilt options</h4>
<p><b>msg.int</b> - Passing a msg.int will display an integer on the nuimo. All output is in two-digit form, so single digit parameters will be prefixed by a '0'. All other settings will either be inherited from the node editor, or via custom parameters below.</p>
<p><b>msg.scale</b> - Passing an array on the msg.scale property displays a vertical line, according to the height and width you provide: [height, width]. Height is 1 to 9, Width can be odd numbers from 1 to 9.</p>
<br />
<h4>Custom matrix setting via msg</h4>
<p>If you''d like to set the matrix via a msg, the values are set by the following properties:
<ul>
<li>Matrix layout is passed via msg.setMatrix property</li>
<li>Brightness is set by msg.brightness</li>
<li>Timeout is set by msg.timeout</li>
<li>Onion skinning is set by msg.onionSkinning</li>
</ul>
<p>All of these values are then available on msg.instructions on the output</p>
</script>
70 changes: 45 additions & 25 deletions matrix/nuimo-set-matrix.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ module.exports = function(RED) {

function nuimoSetMatrixNode(config) {
RED.nodes.createNode(this,config);
var node = this;
//import the config node
nuimo = RED.nodes.getNode(config.nuimoConfig);

var appMatrixImage = config.appMatrixImage.replace(/\s/g,'').split(',');

var numbers = [
const numbers = [
[[1,1,1],[1,0,1],[1,0,1],[1,0,1],[1,1,1]],
[[0,0,1],[0,0,1],[0,0,1],[0,0,1],[0,0,1]],
[[1,1,1],[0,0,1],[1,1,1],[1,0,0],[1,1,1]],
Expand All @@ -24,43 +25,62 @@ module.exports = function(RED) {
];

function buildNumberArray(num) {
if (num > 0 && num <= 99) {
if (num > -1 && num <= 99) {
if (num < 10) {
var first = numbers[0];
var second = numbers[num];
} else {
var first = numbers[Number(num.toString().split('')[0])]
var second = numbers[Number(num.toString().split('')[1])]
var first = numbers[Number(num.toString().split('')[0])];
var second = numbers[Number(num.toString().split('')[1])];
}
var output = [];
output.push(numbers[10], numbers[10], numbers[10]);
var step;
for (step = 0; step < 5; step++) {
// Runs 5 times, with values of step 0 through 4.
output.push(0);
output.push(first[step]);
output.push(0);
output.push(second[step]);
output.push(0);
var output = Array(27).fill(0);
for (var step = 0; step < 5; step++) {
output = output.concat(0, first[step], 0, second[step], 0);
}
output.push(numbers[10]);
var merged = output.join().split(',')
return merged;
} else if (num == 0) {
return [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0];
} else {
return [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,1,0,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,0,0,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0];
return output.concat(numbers[10]);
}
return [0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,1,1,1,0,1,1,1,0,
0,1,0,1,0,1,0,1,0,
0,1,1,1,0,1,1,1,0,
0,0,0,1,0,0,0,1,0,
0,1,1,1,0,1,1,1,0,
0,0,0,0,0,0,0,0,0];
};

var node = this;
function scale(scale) {
var height = scale[0], width = scale[1];
const line = (width) => ({
1: [0,0,0,0,1,0,0,0,0],
3: [0,0,0,1,1,1,0,0,0],
5: [0,0,1,1,1,1,1,0,0],
7: [0,1,1,1,1,1,1,1,0],
9: [1,1,1,1,1,1,1,1,1],
0: [0,0,0,0,0,0,0,0,0]
})[width];
var output = [];
for (var step = 9; step > 0; step--) {
output = (step > height) ? output.concat(line(0)) : output.concat(line(width));
}
return output;
}

this.on('input', function(msg) {
if (msg.int) {
if (msg.int || msg.payload.int) {
appMatrixImage = buildNumberArray(msg.int);
}
msg.instructions = { matrix: appMatrixImage, brightness: config.brightness, timeout: config.timeout, options: {onionSkinning: config.onionSkinning}};
nuimo.writeMatrix(msg.instructions);
if (msg.scale || msg.payload.scale) {
var params = msg.scale || msg.payload.scale;
appMatrixImage = scale(params);
}
var brightness = msg.brightness || msg.payload.brightness || config.brightness;
var timeout = msg.timeout || msg.payload.timeout || config.timeout;
var onionSkinning = msg.onionSkinning || msg.payload.onionSkinning || config.onionSkinning;
msg.instructions = { matrix: appMatrixImage, brightness: brightness, timeout: timeout, options: {onionSkinning: onionSkinning}};
node.send(msg);
nuimo.writeMatrix(msg.instructions);
});
}
RED.nodes.registerType("nuimo-set-matrix",nuimoSetMatrixNode);
Expand Down

0 comments on commit 533bd1e

Please sign in to comment.