Skip to content

Commit

Permalink
Version 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
readeral committed Aug 26, 2018
1 parent 65f6ffd commit fdff379
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 91 deletions.
4 changes: 3 additions & 1 deletion apps/nuimo-app.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

<script type="text/javascript">
RED.nodes.registerType('nuimo-app', {
category: 'advanced',
category: 'nuimo',
color: '#C0C0C0',
defaults: {
name: {
Expand Down Expand Up @@ -326,6 +326,8 @@ <h4>App Matrix Image</h4>
<option value="0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,1,1,0,0,1,1,1,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0">Musical notes</option>
<option value="0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0">Light globe</option>
<option value="0,0,1,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,1,1,1,0,1,1,1,0,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,1,1,1,1,0,0">Chrome logo</option>
<option value="0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0">Clock</option>
<option value="0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0">Alarm clock</option>
<option value="0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0">Up arrow</option>
<option value="0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0">Down arrow</option>
<option value="0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1,1,0,1,0,1,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0">Star</option>
Expand Down
54 changes: 30 additions & 24 deletions config/nuimo-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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");
Expand All @@ -15,14 +16,16 @@ let Timeout = require('../Timeout');
let Nuimo = require('nuimojs'),
nuimo = new Nuimo();

var node = this;

var longPress;

nuimo.on("discover", (device) => {
node.writeMatrix = (instructions) => {
device.setLEDMatrix(instructions.matrix, instructions.brightness, instructions.timeout, instructions.options);
}
node.getActive = () => {
activeApp = globalContext.get("activeApp");
}
device.on("connect", () => {
node.warn("Nuimo connected");
node.emit('connected',device.batteryLevel);
Expand All @@ -41,50 +44,53 @@ let Timeout = require('../Timeout');
},400);
});
device.on("release", () => {
activeApp = globalContext.get("activeApp");
console.log(activeApp);
console.log(sensitivity[1]);
Timeout.clear('extender');
console.log(Date.now() - longPress);
if (Date.now() - longPress < sensitivity[1]) {
node.emit('press', activeApp)
} else {
node.emit('longPress')
}
})
device.on("touch", (direction) => {
activeApp = globalContext.get("activeApp");
switch (direction) {
case (Nuimo.Area.LEFT):
node.emit("touch", "LEFT", activeApp);
console.log("Touched left"); break;
node.emit("touch", "LEFT", activeApp); break;
case (Nuimo.Area.RIGHT):
node.emit("touch", "RIGHT", activeApp);
console.log("Touched right"); break;
node.emit("touch", "RIGHT", activeApp); break;
case (Nuimo.Area.TOP):
node.emit("touch", "TOP", activeApp);
console.log("Touched top"); break;
node.emit("touch", "TOP", activeApp); break;
case (Nuimo.Area.BOTTOM):
node.emit("touch", "BOTTOM", activeApp);
console.log("Touched bottom"); break;
node.emit("touch", "BOTTOM", activeApp); break;
case (Nuimo.Area.LONGLEFT):
node.emit("touch", "LONGLEFT", activeApp);
console.log("Long touched left"); break;
node.emit("touch", "LONGLEFT", activeApp); break;
case (Nuimo.Area.LONGRIGHT):
node.emit("touch", "LONGRIGHT", activeApp);
console.log("Long touched right"); break;
node.emit("touch", "LONGRIGHT", activeApp); break;
case (Nuimo.Area.LONGTOP):
node.emit("touch", "LONGTOP", activeApp);
console.log("Long touched top"); break;
node.emit("touch", "LONGTOP", activeApp); break;
case (Nuimo.Area.LONGBOTTOM):
node.emit("touch", "LONGBOTTOM", activeApp);
console.log("Long touched bottom"); break;
node.emit("touch", "LONGBOTTOM", activeApp); break;
}
})
device.on("swipe", (direction) => {
switch (direction) {
case (Nuimo.Swipe.LEFT):
node.emit("swipe", "LEFT", activeApp); break;
case (Nuimo.Swipe.RIGHT):
node.emit("swipe", "RIGHT", activeApp); break;
case (Nuimo.Swipe.UP):
node.emit("swipe", "UP", activeApp); break;
case (Nuimo.Swipe.DOWN):
node.emit("swipe", "DOWN", activeApp); break;
}
})
device.on("fly", (direction, speed) => {
node.emit("fly", direction, activeApp);
})
device.on("distance", (distance) => {
node.emit("distance", distance, activeApp);
})

device.on("rotate", (amount) => {
activeApp = globalContext.get("activeApp");
console.log(`Rotated by ${amount}`);
node.emit("rotate", amount, activeApp, sensitivity[0]);
});

Expand Down
2 changes: 1 addition & 1 deletion interface/nuimo-interface.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script type="text/javascript">
RED.nodes.registerType('nuimo-interface', {
category: 'advanced',
category: 'nuimo',
color: '#C0C0C0',
defaults: {
name: { value: "" },
Expand Down
119 changes: 68 additions & 51 deletions interface/nuimo-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ module.exports = function(RED) {
var tempOption = 0;
var selectionMode;


//
// HELPER FUNCTIONS AND DEFINITIONS
//

//import the config node
nuimo = RED.nodes.getNode(config.nuimoConfig);

Expand All @@ -15,8 +20,24 @@ module.exports = function(RED) {

globalContext.set("sensitivity", [config.nuimoRotation, config.selectTimeout])

//handle input - if a normal message, it's passed through,
//else it receives app definitions and adds them to apps array
function setActiveApp(value, callback) {
globalContext.set("activeApp", value)
if (callback) {
callback()
}
nuimo.getActive()
}


//
// APP REGISTRATION
//

//The following code 'registers' app nodes outputs into an array called
//'apps'. This is the means by which the Nuimo can control multiple devices

//The node handles input as expected - if a normal message, it's passed
//through, otherwise it receives app definitions and adds them to apps array
this.on("input", function(msg) {
if (msg.hasOwnProperty("image")) {
//Pushes new apps to apps array. Apps that duplicate an existign name are ignored
Expand All @@ -26,19 +47,24 @@ module.exports = function(RED) {
}
node.send(msg);
});
//adds updated apps list to flow context
//The registered apps are then added to the flow context, ready to be used
//in the config options of Nuimo listener nodes
flowContext.set("apps", apps);
//if global context doesn't include the activeApp variable,
//the variable is created and set to the first app in app array
//the tempOption (for app selection mode) is either set to
//first app in array or, if activeApp exists, to activeApp
if (!globalContext.get("activeApp")) {
globalContext.set("activeApp", apps[0]);
} else {
tempOption = apps.indexOf(apps.filter(item => item.name == globalContext.get("activeApp").name));
setActiveApp(apps[0]);
}

//
// NODE STATUS
//

//Nuimo connection and battery level output as a status icon

//When the nuimo is connected or the battery level changes
//it calls batteryStatus() to update the status with a colour and %
//representation of the battery status
nuimo.on("connected", (batteryLevel) => {
batteryStatus(batteryLevel);
})
Expand All @@ -58,33 +84,24 @@ module.exports = function(RED) {
}
}

//When the nuimo button is long-pressed (over 2.5 seconds)
//the nuimo is placed into 'app selection' mode and the
//active app is replaced with pending to ensure all nuimo events
//are ignored until a new app is selected
nuimo.on("longPress", () => {
tempOption = apps.indexOf(apps.filter(item => item.name == globalContext.get("activeApp").name)[0]);
console.log(tempOption);
globalContext.set("activeApp", "pending");
//
// SELECTION MODE CODE
//

//When the nuimo button is long-pressed (timing defined by interface config)
//the nuimo is placed into 'app selection mode' and the global activeApp
//variable is replaced with 'pending' to ensure all nuimo events are ignored
//until a new app is selected
//tempOption gets defined (as an integer) to tell the nuimo what to display
nuimo.on("longPress", () => {
var initial = apps.filter(item => item.name == globalContext.get("activeApp").name)[0];
tempOption = (apps.indexOf(initial) < 0 ? 0 : apps.indexOf(initial));
setActiveApp("pending");
appSelectionMode(tempOption);
//when a normal press is registered while in 'app selection' mode,
//the displayed app is stored in the activeApp variable.
});
nuimo.on("press", (activeApp) => {
if (activeApp == "pending" && selectionMode) {
clearInterval(flash);
selectionMode = false;
globalContext.set("activeApp", apps[tempOption]);
nuimo.writeMatrix({ matrix: apps[tempOption].image, brightness: 255, timeout: 2000, onionSkinning: true});
}
});
function appSelectionMode(opt) {
console.log(opt);
console.log(apps[opt]);
selectionMode = true;
var thing = apps[opt].image
var instructions = { matrix: thing, brightness: 255, timeout: 500, onionSkinning: true};
var instructions = { matrix: apps[opt].image, brightness: 255, timeout: 500, onionSkinning: true};
nuimo.writeMatrix(instructions);
flash = setInterval( opt => {
nuimo.writeMatrix(instructions);
Expand All @@ -94,50 +111,50 @@ module.exports = function(RED) {
//cAcc for clockwise accumulator, acAcc for anti-clockwise
var cAcc = 0;
var acAcc = 0;
//Once the accumulator reaches the threshold, nextApp/prevApp are called to:
// - clear the appSelectionMode interval
// - reset the relevant accumulator
// - update the tempOption variable
// - calling appSelectionMode with the new tempOption
nuimo.on("rotate", (amount) => {
if (selectionMode) {
if (amount > 0) {
acAcc = 0;
if (amount > 50) {
cAcc += 1;
if (cAcc >= 5) {
cAcc = 0;
nextApp()
console.log("nextApp!")
}
if (cAcc >= 5) nextApp();
}
} else {
cAcc = 0;
if (amount < -50) {
acAcc += 1;
if (acAcc >= 5) {
acAcc = 0;
console.log("prevApp!")
}
//nextApp();
if (acAcc >= 5) prevApp();
}
//prevApp();
}
}
});
function nextApp() {
clearInterval(flash);
if (tempOption == (apps.length - 1)) {
tempOption = 0;
} else {
tempOption += 1;
}
cAcc = 0;
tempOption == (apps.length - 1) ? tempOption = 0 : tempOption += 1;
appSelectionMode(tempOption);
}
function prevApp() {
clearInterval(flash);
if (tempOption == 0) {
tempOption = (apps.length - 1);
} else {
tempOption -= 1;
}
acAcc = 0;
tempOption == 0 ? tempOption = (apps.length - 1) : tempOption -= 1;
appSelectionMode(tempOption);
}
//when a normal press is registered while in 'app selection' mode,
//the displayed app is stored in the activeApp variable
nuimo.on("press", (activeApp) => {
if (activeApp == "pending" && selectionMode) {
clearInterval(flash);
selectionMode = false;
setActiveApp(apps[tempOption]);
nuimo.writeMatrix({ matrix: apps[tempOption].image, brightness: 255, timeout: 2000, onionSkinning: true});
}
});
}
RED.nodes.registerType("nuimo-interface",nuimoInterfaceNode);
RED.httpAdmin.get("/applist", RED.auth.needsPermission("nuimo-interface.read"), function(req,res) {
Expand Down
2 changes: 1 addition & 1 deletion listener/nuimo-listener.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script type="text/javascript">
RED.nodes.registerType('nuimo-listener', {
category: 'advanced',
category: 'nuimo',
color: '#C0C0C0',
defaults: {
name: { value: ""},
Expand Down
43 changes: 35 additions & 8 deletions listener/nuimo-listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,54 @@ module.exports = function(RED) {
//event, in order to use the 'press' event to create and reserve
//a 'longPress' action for app switching. There should be no notable
//impact on the end user, but if you find one, please raise a github issue
console.log(appChoice + " - variable");
console.log(activeApp.name);
if (appChoice == activeApp.name) {
var msg = { payload:"I got pressed!" }
node.send(msg);
}
})
nuimo.on("rotate", (amount, activeApp) => {
console.log(appChoice);
if (appChoice == activeApp.name) {
var msg = { payload:`I rotated ${amount}!`, degrees: amount }
node.send(msg);
}
})
nuimo.on("touch", (region, activeApp) => {
console.log(appChoice);
if (appChoice == activeApp.name) {
var msg = {};
msg.topic = "touch";
msg.region = region;
msg.activeApp = activeApp;
var msg = {
topic: "touch",
region: region,
activeApp: activeApp
};
node.send(msg);
}
})
nuimo.on("swipe", (direction, activeApp) => {
if (appChoice == activeApp.name) {
var msg = {
topic: "swipe",
direction: direction,
activeApp: activeApp
};
node.send(msg);
}
})
nuimo.on("fly", (direction, activeApp) => {
if (appChoice == activeApp.name) {
var msg = {
topic: "fly",
direction: direction,
activeApp: activeApp
};
node.send(msg);
}
})
nuimo.on("distance", (distance, activeApp) => {
if (appChoice == activeApp.name) {
var msg = {
topic: "distance",
direction: distance,
activeApp: activeApp
};
node.send(msg);
}
})
Expand Down
2 changes: 1 addition & 1 deletion matrix/nuimo-set-matrix.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script type="text/javascript">
RED.nodes.registerType('nuimo-set-matrix', {
category: 'advanced',
category: 'nuimo',
color: '#C0C0C0',
defaults: {
name: { value: "" },
Expand Down
Loading

0 comments on commit fdff379

Please sign in to comment.