Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugs/detection #61

Merged
merged 4 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ node_js:
- "10"
- "9"
- "8"
- "7"
- "6"

cache:
directories:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ RUN npm install
## link dev code
RUN npm link /usr/src/alexa-node/

USER node-red
# USER node-red

15 changes: 6 additions & 9 deletions alexa/alexa-helper.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
'use strict';

module.exports = {
hubPort: ( process.env.ALEXA_PORT != undefined
&&
hubPort: ( process.env.ALEXA_PORT != undefined &&
parseInt(process.env.ALEXA_PORT)
)
|| 60000,
) ||
60000,
controllerNode: undefined,
isDebug: ( process.env.DEBUG
&&
isDebug: ( process.env.DEBUG &&
process.env.DEBUG.indexOf('node-red-contrib-alexa-home') > 0
)
|| false,
) ||
false,
bri_default: process.env.BRI_DEFAULT || 254,
maxItemCount: 20,
prefixUUID: 'f6543a06-da50-11ba-8d8f-',
};
10 changes: 10 additions & 0 deletions alexa/alexa-home-controller.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
<i class="icon-tag"></i> Port</label>
<input type="text" id="node-input-port" placeholder="60000">
</div>
<div class="form-row">
<label for="node-input-maxItems">
<i class="icon-tag"></i> MaxItems</label>
<input type="text" id="node-input-maxItems" placeholder="25">
</div>
</script>
<script type="text/javascript">

Expand All @@ -23,6 +28,11 @@
value: 60000,
required: true,
validate: RED.validators.number()
},
maxItems: {
value: 25,
required: true,
validate: RED.validators.number()
}
},
inputs: 0,
Expand Down
96 changes: 59 additions & 37 deletions alexa/alexa-home-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ module.exports = function(RED) {
*/
function AlexaHomeController(config) {
RED.nodes.createNode(this, config);

const node = this;
alexaHome.controllerNode = node;

node.name = config.controllername;
if (config.port === undefined || config.port === null) {
node.port = alexaHome.hubPort;
} else {
node.port = parseInt(config.port);
}
node.maxItems = config.maxItems;
node._commands = new Map();
node._hub = [];
node._hub.push(new AlexaHub(this, node.port, this._hub.length));
Expand Down Expand Up @@ -53,25 +54,30 @@ module.exports = function(RED) {
}
}
});
node.setConnectionStatusMsg('green', 'ok');
node.setConnectionStatusMsg('green', 'Ok');
}

AlexaHomeController.prototype.getDevices = function() {
return this._commands;
const node = this;
return node._commands;
};

AlexaHomeController.prototype.getDevice = function(uuid) {
if (this._commands.has(uuid)) {
return this._commands.get(uuid);
const node = this;

if (node._commands.has(uuid)) {
return node._commands.get(uuid);
}
return undefined;
};

AlexaHomeController.prototype.registerCommand = function(deviceNode) {
const node = this;
deviceNode.updateController(this);

deviceNode.updateController(node);
node._commands.set(node.formatUUID(deviceNode.id), deviceNode);
const currentNeed = Math.ceil(node._commands.size / alexaHome.maxItemCount);
const itemCount = node.maxItems <= 0 ? node._commands.size : node.maxItems;
const currentNeed = Math.ceil(node._commands.size / itemCount);
if (currentNeed <= node._hub.length && node._hub.length > 0) {
return;
}
Expand All @@ -81,11 +87,13 @@ module.exports = function(RED) {

AlexaHomeController.prototype.deregisterCommand = function(deviceNode) {
const node = this;
node._commands.delete(this.formatUUID(deviceNode.id));

node._commands.delete(node.formatUUID(deviceNode.id));
if (node._commands.size == 0) {
return;
}
const currentNeed = Math.ceil(node._commands.size / alexaHome.maxItemCount);
const itemCount = node.maxItems <= 0 ? node._commands.size : node.maxItems;
const currentNeed = Math.ceil(node._commands.size / itemCount);
if (currentNeed >= node._hub.length) {
return;
}
Expand Down Expand Up @@ -114,12 +122,14 @@ module.exports = function(RED) {
return content;
};
AlexaHomeController.prototype.handleIndex = function(id, request, response) {
RED.log.debug(this.name + '/' + id + ' - Handling index request');
const node = this;

RED.log.debug(node.name + '/' + id + ' - Handling index request');
const template = fs.readFileSync(__dirname +
'/templates/index.html', 'utf8').toString();
const data = {
id: id,
uuid: this.formatHueBridgeUUID(this.id),
uuid: node.formatHueBridgeUUID(node.id),
baseUrl: 'http://' + request.headers['host'],
};
const content = Mustache.render(template, data);
Expand All @@ -129,15 +139,17 @@ module.exports = function(RED) {
response.end(content);
};
AlexaHomeController.prototype.handleSetup = function(id, request, response) {
RED.log.debug(this.name + '/' + id + ' - Handling setup request');
const node = this;

RED.log.debug(node.name + '/' + id + ' - Handling setup request');
const template = fs.readFileSync(__dirname +
'/templates/setup.xml', 'utf8').toString();
const data = {
uuid: this.formatHueBridgeUUID(this.id),
uuid: node.formatHueBridgeUUID(node.id),
baseUrl: 'http://' + request.headers['host'],
};
const content = Mustache.render(template, data);
this.setConnectionStatusMsg('green', 'setup requested');
node.setConnectionStatusMsg('green', 'setup requested');
response.writeHead(200, {
'Content-Type': 'application/xml; charset=UTF-8',
});
Expand All @@ -147,7 +159,9 @@ module.exports = function(RED) {
AlexaHomeController.prototype.handleRegistration = function(id,
request,
response) {
RED.log.debug(this.name + '/' + id + ' - Handling registration request');
const node = this;

RED.log.debug(node.name + '/' + id + ' - Handling registration request');
const template = fs.readFileSync(__dirname +
'/templates/registration.json', 'utf8').toString();

Expand All @@ -159,7 +173,7 @@ module.exports = function(RED) {
username: username,
};
const content = Mustache.render(template, data);
this.setConnectionStatusMsg('green', 'registration succeded');
node.setConnectionStatusMsg('green', 'registration succeded');
response.set({
'Content-Type': 'application/json',
});
Expand All @@ -170,7 +184,9 @@ module.exports = function(RED) {
AlexaHomeController.prototype.handleItemList = function(id,
request,
response) {
RED.log.debug(this.name + '/' + id +
const node = this;

RED.log.debug(node.name + '/' + id +
' - handling api item list request: ' + request.params.itemType);
if (request.params.itemType !== 'lights') {
response.status(200).end('{}');
Expand All @@ -179,57 +195,61 @@ module.exports = function(RED) {
const template = fs.readFileSync(__dirname +
'/templates/items/list.json', 'utf8').toString();
const data = {
lights: this.generateAPIDeviceList(id),
lights: node.generateAPIDeviceList(id),
date: new Date().toISOString().split('.').shift(),
};
const content = Mustache.render(template, data);
RED.log.debug(this.name + + '/' + id +
RED.log.debug(node.name + + '/' + id +
' - listing ' + request.params.username +
' #' + data.lights.length + ' api information to ' +
request.connection.remoteAddress);
this.setConnectionStatusMsg('yellow', request.params.itemType +
' list requested: ' + this._commands.size);
node.setConnectionStatusMsg('yellow', request.params.itemType +
' list requested: ' + node._commands.size);
response.set({
'Content-Type': 'application/json',
});
response.send(this.stripSpace(content));
response.send(node.stripSpace(content));
};

AlexaHomeController.prototype.handleApiCall = function(id,
request,
response) {
RED.log.debug(this.name + '/' + id + ' - Hanlding API listing request');
const node = this;

RED.log.debug(node.name + '/' + id + ' - Hanlding API listing request');
const responseTemplate = fs.readFileSync(__dirname +
'/templates/response.json', 'utf8').toString();
const lights = fs.readFileSync(__dirname +
'/templates/items/list.json', 'utf8').toString();
const data = {
lights: this.generateAPIDeviceList(id),
lights: node.generateAPIDeviceList(id),
address: request.hostname,
username: request.params.username,
date: new Date().toISOString().split('.').shift(),
};
const content = Mustache.render(responseTemplate, data, {
itemsTemplate: lights,
});
RED.log.debug(this.name + + '/' + id + ' - Sending ' +
RED.log.debug(node.name + + '/' + id + ' - Sending ' +
request.params.username + ' #' + data.lights.length +
' api information to ' + request.connection.remoteAddress);
this.setConnectionStatusMsg('yellow', 'api requested');
node.setConnectionStatusMsg('yellow', 'api requested');
response.set({
'Content-Type': 'application/json',
});
response.send(this.stripSpace(content));
response.send(node.stripSpace(content));
};

AlexaHomeController.prototype.generateAPIDeviceList = function(id) {
const deviceList = [];
const startItem = (id * alexaHome.maxItemCount) + 1;
const endItem = ((id + 1) * alexaHome.maxItemCount) + 1;
const node = this;
const itemCount = node.maxItems <= 0 ? node._commands.size : node.maxItems;
const startItem = (id * itemCount) + 1;
const endItem = ((id + 1) * itemCount) + 1;
let count = 0;
RED.log.debug(this.name + '/' + id + ' - starting at ' + (startItem - 1) +
' till ' + (endItem - 1) + ' at #' + this._commands.size);
for (const [uuid, dev] of this._commands) {
RED.log.debug(node.name + '/' + id + ' - starting at ' + (startItem - 1) +
' till ' + (endItem - 1) + ' at #' + node._commands.size);
for (const [uuid, dev] of node._commands) {
count += 1;
if (count < startItem) {
continue;
Expand All @@ -241,7 +261,7 @@ module.exports = function(RED) {
id: uuid,
name: dev.name,
};
const deviceData = this.generateAPIDevice(uuid, dev);
const deviceData = node.generateAPIDevice(uuid, dev);
deviceList.push(Object.assign({}, deviceData, device));
}
return deviceList;
Expand All @@ -268,13 +288,14 @@ module.exports = function(RED) {
response.status(200).end('{}');
return;
}
const node = this;

const template = fs.readFileSync(__dirname +
'/templates/items/set-state.json', 'utf8').toString();
const username = request.params.username;
let uuid = request.params.id;
uuid = uuid.replace('/', '');
const targetNode = this.getDevice(uuid);
const targetNode = node.getDevice(uuid);
if (targetNode === undefined) {
RED.log.warn('control item - unknown alexa node of type ' +
request.params.itemType + ' was requested: ' + uuid);
Expand All @@ -301,7 +322,7 @@ module.exports = function(RED) {
}
targetNode.processCommand(msg);

const data = this.generateAPIDevice(uuid, targetNode);
const data = node.generateAPIDevice(uuid, targetNode);
const output = Mustache.render(template, data).replace(/\s/g, '');
response.set({
'Content-Type': 'application/json',
Expand All @@ -314,21 +335,22 @@ module.exports = function(RED) {
response.status(200).end('{}');
return;
}
const node = this;

const template = fs.readFileSync(__dirname +
'/templates/items/get-state.json', 'utf8').toString();

// const username = request.params.username;
const uuid = request.params.id;

const targetNode = this.getDevice(uuid);
const targetNode = node.getDevice(uuid);
if (targetNode === undefined) {
RED.log.warn('unknown alexa node of type ' +
request.params.itemType + ' was requested: ' + uuid);
response.status(502).end();
return;
}
const data = this.generateAPIDevice(uuid, targetNode);
const data = node.generateAPIDevice(uuid, targetNode);
data.name = targetNode.name;
data.date = new Date().toISOString().split('.').shift();
const output = Mustache.render(template, data).replace(/\s/g, '');
Expand Down
14 changes: 7 additions & 7 deletions alexa/alexa-home.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,20 @@ module.exports = function(RED) {

// set color
if (msg.payload.xy) {
RED.log.debug(this.name + ' - Setting values on xy: ' + msg.payload.xy);
RED.log.debug(node.name + ' - Setting values on xy: ' + msg.payload.xy);
node.setConnectionStatusMsg('blue', 'xy: ' + msg.payload.xy);
msg.payload.command = 'color';
}
// Dimming or Temperature command
if (msg.payload.bri) {
RED.log.debug(this.name + ' - Setting values on bri');
RED.log.debug(node.name + ' - Setting values on bri');
msg.payload.on = msg.payload.bri > 0;
msg.payload.command = 'dim';
node.setConnectionStatusMsg('blue',
'bri:' + msg.payload.bri
);
} else {
RED.log.debug(this.name + ' - Setting values on On/Off');
RED.log.debug(node.name + ' - Setting values on On/Off');
let isOn = false;
if (typeof msg.payload === 'object') {
isOn = msg.payload.on;
Expand Down Expand Up @@ -126,8 +126,8 @@ module.exports = function(RED) {
}

msg.payload.bri_normalized = Math.round(msg.payload.bri / 254.0 * 100.0);
msg.device_name = this.name;
msg.light_id = this.id;
msg.device_name = node.name;
msg.light_id = node.id;

node.state = msg.payload.on;
node.bri = msg.payload.bri;
Expand All @@ -136,11 +136,11 @@ module.exports = function(RED) {
node.xy = [0, 0];
}
if (msg.inputTrigger && !msg.output) {
RED.log.debug(this.name + ' - Set values on input');
RED.log.debug(node.name + ' - Set values on input');
return;
}

RED.log.debug(this.name + ' - sending values');
RED.log.debug(node.name + ' - sending values');

node.send(msg);
};
Expand Down
Loading