Merge pull request #1 from karl0ss/Docker

Docker
This commit is contained in:
Karl Hudgell 2019-07-14 15:50:27 +01:00 committed by GitHub
commit 3bbdbcde9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 161 additions and 22 deletions

2
.dockerignore Normal file
View File

@ -0,0 +1,2 @@
node_modules
npm-debug.log

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
.idea/ .idea/
node_modules node_modules
.vscode/launch.json

12
CHANGELOG.md Normal file
View File

@ -0,0 +1,12 @@
# CHANGELOG
## 1.1.0
* Add try-catch around packet decryption to guard against a service crash resulting from an occasional packet decryption error.
* Pluralize getConnectedSocket + alias previous name
* Enhance settings handling
* Enhance Orvibo logging
## 1.0.0
Initial release

86
Docker.js Normal file
View File

@ -0,0 +1,86 @@
const Orvibo = require('./Orvibo');
const http = require('http');
const url = require('url');
const httpPort = 3000;
const createArray = str => {
// split on each comma
const arr = str.split(',');
// put back elements by pairs
const pairs = [];
for (let i=0; i<arr.length; i+=2) {
let o = {};
o.uid = arr[i].split(':')[1];
o.name = arr[i+1].split(':')[1];
pairs.push(o);
}
return pairs;
}
// Create a settings object to pass PK key and map sockets to names
const settings = {
LOG_PACKET: true, //Show incoming packet data from the socket
ORVIBO_KEY: process.env.orviboPK,
plugInfo : [
createArray(process.env.plugArray)
],
};
let orvibo = new Orvibo(settings);
// When a socket first connects and initiates the handshake it will emit the connected event with the uid of the socket;
orvibo.on('plugConnected', ({uid, name}) => {
console.log(`Connected ${uid} name = ${name}`);
});
// If the socket state is updated this event will fire
orvibo.on('plugStateUpdated', ({uid, state , name}) => {
console.log(`Plug ${name} ${uid} updated state ${state}`);
});
// The plug sends a hearbeat to let the server know it's still alive
orvibo.on('gotHeartbeat', ({uid, name}) => {
console.log(`Plug ${name} ${uid} sent heartbeat`);
});
// Called when the plug disconnects
orvibo.on('plugDisconnected', ({uid, name }) => {
console.log(`Plug ${uid} - ${name} disconnected`);
});
// Called when the plug disconnects with an error ie it's been unplugged
orvibo.on('plugDisconnectedWithError', ({uid, name }) => {
console.log(`Plug ${uid} - ${name} disconnected with error`);
});
// Start the Orvibo socket server
orvibo.startServer();
// Create a basic example HTTP server
// If there are no parameters it will return the uid, state, modelId and name of the socket
// You can then use the uid to toggle the state of the switch like
// http://localhost:3000?uid=5dcf7ff76e7a
const requestHandler = (request, response) => {
response.writeHead(200, {'Content-Type': 'application/json'});
let q = url.parse(request.url, true).query;
if (q.uid != null) {
orvibo.toggleSocket(q.uid);
}
// Get all currently connected sockets, their names and states
// let sockets = orvibo.getConnectedSocket();
let sockets = [{"name":"3D Printer","state":1,"uid":"5ccf7f22fba4","modelId":"f8b11bed724647e98bd07a66dca6d5b6"}]
response.end(JSON.stringify(sockets));
};
const httpServer = http.createServer(requestHandler);
httpServer.listen(httpPort, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`http server is listening on ${httpPort}`)
});

13
Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000 10001
CMD [ "node", "Docker.js" ]

View File

@ -5,20 +5,21 @@ const Utils = require('./Utils');
const Settings = require('./OrviboSettings'); const Settings = require('./OrviboSettings');
const EventEmitter = require('events').EventEmitter; const EventEmitter = require('events').EventEmitter;
let logger = console;
let ORVIBO_KEY = Settings.ORVIBO_KEY; let ORVIBO_KEY = Settings.ORVIBO_KEY;
let LOG_PACKET = Settings.LOG_PACKET; let LOG_PACKET = Settings.LOG_PACKET;
let PLUG_INFO = Settings.plugInfo; let PLUG_INFO = Settings.plugInfo;
const Orvibo = function(userSettings) { const Orvibo = function(userSettings = {}) {
// Allow user to pass in settings // Allow user to pass in settings
if (userSettings != null) { if('ORVIBO_KEY' in userSettings) ORVIBO_KEY = userSettings.ORVIBO_KEY;
ORVIBO_KEY = userSettings.ORVIBO_KEY; if('plugInfo' in userSettings) PLUG_INFO = userSettings.plugInfo;
LOG_PACKET = userSettings.LOG_PACKET; if('PLUG_INFO' in userSettings) PLUG_INFO = userSettings.PLUG_INFO;
PLUG_INFO = userSettings.plugInfo; if('LOG_PACKET' in userSettings) LOG_PACKET = userSettings.LOG_PACKET;
}
if (ORVIBO_KEY === '') { if (ORVIBO_KEY === '') {
console.log('Please pass Orvibo PK key details via the constructor or add to OrviboSettings.js file. See Readme'); logger.log('Please pass Orvibo PK key details via the constructor or add to OrviboSettings.js file. See Readme');
process.exit(1); process.exit(1);
} }
}; };
@ -75,6 +76,7 @@ let handshakeHandler = function(plugPacket, socket, socketData) {
name: getNameForUid(uid) name: getNameForUid(uid)
}); });
respondAndSetData(pkData, socket, PacketBuilder.handshakePacket); respondAndSetData(pkData, socket, PacketBuilder.handshakePacket);
logger.log(`Connected ${pkData.uid} name = ${pkData.name}`);
this.emit('plugConnected', {uid:pkData.uid, name: pkData.name}); this.emit('plugConnected', {uid:pkData.uid, name: pkData.name});
}; };
@ -84,6 +86,7 @@ let heartbeatHandler = function(plugPacket, socket, socketData) {
uid: plugPacket.getUid() uid: plugPacket.getUid()
}); });
respondAndSetData(pkData, socket, PacketBuilder.heartbeatPacket); respondAndSetData(pkData, socket, PacketBuilder.heartbeatPacket);
logger.log(`Plug ${pkData.name} ${pkData.uid} sent heartbeat`);
this.emit('gotHeartbeat', {uid:pkData.uid, name: pkData.name}); this.emit('gotHeartbeat', {uid:pkData.uid, name: pkData.name});
}; };
@ -94,6 +97,7 @@ let stateUpdateHandler = function(plugPacket, socket, socketData) {
state: plugPacket.getValue1() state: plugPacket.getValue1()
}); });
respondAndSetData(pkData, socket, PacketBuilder.comfirmStatePacket); respondAndSetData(pkData, socket, PacketBuilder.comfirmStatePacket);
logger.log(`Plug ${pkData.name} ${pkData.uid} updated state ${pkData.state}`);
this.emit('plugStateUpdated', {uid:pkData.uid, state: pkData.state, name: pkData.name}); this.emit('plugStateUpdated', {uid:pkData.uid, state: pkData.state, name: pkData.name});
}; };
@ -125,7 +129,7 @@ Orvibo.prototype.startServer = function() {
let self = this; let self = this;
let handlers = this.handlers(); let handlers = this.handlers();
console.log(`Starting server Orvibo socket server on port ${port}`); logger.log(`Starting server Orvibo socket server on port ${port}`);
this.server = net.createServer(function(socket) { this.server = net.createServer(function(socket) {
@ -139,17 +143,22 @@ Orvibo.prototype.startServer = function() {
let plugPacket = new Packet(data); let plugPacket = new Packet(data);
if (!plugPacket.validCRC()) { if (!plugPacket.validCRC()) {
console.log('Got invalid CRC'); logger.log('Got invalid CRC');
return; return;
} }
if (plugPacket.packetTypeText() === 'pk') { try {
plugPacket.processPacket(ORVIBO_KEY); if (plugPacket.packetTypeText() === 'pk') {
} else { plugPacket.processPacket(ORVIBO_KEY);
plugPacket.processPacket(socketData.encryptionKey); } else {
plugPacket.processPacket(socketData.encryptionKey);
}
} catch(err) {
logger.log('Failed to parse packet: ' + err);
return;
} }
LOG_PACKET && plugPacket.logPacket("Socket -> "); LOG_PACKET && plugPacket.logPacket('Socket -> ');
let handler = handlers[plugPacket.getCommand()]; let handler = handlers[plugPacket.getCommand()];
if (handler != null) { if (handler != null) {
@ -161,14 +170,15 @@ Orvibo.prototype.startServer = function() {
socket.on('end', function () { socket.on('end', function () {
let pkData = getData(socket.id); let pkData = getData(socket.id);
logger.log(`Plug ${pkData.uid} - ${pkData.name} disconnected`);
self.emit('plugDisconnected', {uid: pkData.uid, name: pkData.name}); self.emit('plugDisconnected', {uid: pkData.uid, name: pkData.name});
delete packetData[socket.id]; delete packetData[socket.id];
plugConnections.splice(plugConnections.indexOf(socket), 1); plugConnections.splice(plugConnections.indexOf(socket), 1);
}); });
socket.on('error', (err) => { socket.on('error', (err) => {
console.log(err); logger.log(err);
console.log('error with socket ' + socket.id); logger.log(`Plug ${socket.id} - ${socket.name} disconnected with error`);
self.emit('plugDisconnectedWithError', getData(socket.id)); self.emit('plugDisconnectedWithError', getData(socket.id));
delete packetData[socket.id]; delete packetData[socket.id];
plugConnections.splice(plugConnections.indexOf(socket), 1); plugConnections.splice(plugConnections.indexOf(socket), 1);
@ -190,7 +200,7 @@ Orvibo.prototype.toggleSocket = function(uid) {
} }
} }
if (socketId === null) { if (socketId === null) {
console.log('Could not find socket ' + uid); logger.log('Could not find socket ' + uid);
return; return;
} }
let socket = plugConnections.find(s => s.id === socketId); let socket = plugConnections.find(s => s.id === socketId);
@ -209,11 +219,11 @@ Orvibo.prototype.toggleSocket = function(uid) {
socket.write(packet); socket.write(packet);
} else { } else {
console.log('Can not find socket '); logger.log('Can not find socket ');
} }
}; };
Orvibo.prototype.getConnectedSocket = function() { Orvibo.prototype.getConnectedSockets = function() {
let sockets = []; let sockets = [];
for (const key of Object.keys(packetData)) { for (const key of Object.keys(packetData)) {
let socketData = getData(key); let socketData = getData(key);
@ -227,4 +237,10 @@ Orvibo.prototype.getConnectedSocket = function() {
return sockets; return sockets;
}; };
module.exports = Orvibo; Orvibo.prototype.getConnectedSocket = Orvibo.prototype.getConnectedSockets;
Orvibo.prototype.setLogger = function(newLogger) {
logger = newLogger;
};
module.exports = Orvibo;

View File

@ -108,6 +108,15 @@ A list of Orvibo devices, confirmed by contributors, that work with this project
| Orvibo Smart Socket (US/CAD) | S25 | @wichopy | | Orvibo Smart Socket (US/CAD) | S25 | @wichopy |
| Orvibo Smart Socket (UK/GB) | B25UK | @valchonedelchev | | Orvibo Smart Socket (UK/GB) | B25UK | @valchonedelchev |
## Docker
I have extened this project to also run in a docker container.
PK and PlugArray can be passed in via enviroment variables.
orviboPK = 'xxxxx'
plugArray = 'uid:MACADDRESS,name:PRINTERNAME'
## Contributing ## Contributing
I'm more than happy for other people to contribute to this library just send a pull request. I'm more than happy for other people to contribute to this library just send a pull request.

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "orvibo-b25-server", "name": "orvibo-b25-server",
"version": "1.0.0", "version": "1.1.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "orvibo-b25-server", "name": "orvibo-b25-server",
"version": "1.0.1", "version": "1.2.0",
"description": "A server to control the Orvibo B25 range of smart sockets", "description": "A server to control the Orvibo B25 range of smart sockets",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {