mirror of
https://github.com/karl0ss/orvibo-b25-server-kex.git
synced 2025-04-29 12:53:40 +01:00
commit
3bbdbcde9b
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
npm-debug.log
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
.idea/
|
||||
node_modules
|
||||
.vscode/launch.json
|
||||
|
12
CHANGELOG.md
Normal file
12
CHANGELOG.md
Normal 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
86
Docker.js
Normal 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
13
Dockerfile
Normal 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" ]
|
54
Orvibo.js
54
Orvibo.js
@ -5,20 +5,21 @@ const Utils = require('./Utils');
|
||||
const Settings = require('./OrviboSettings');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
|
||||
let logger = console;
|
||||
|
||||
let ORVIBO_KEY = Settings.ORVIBO_KEY;
|
||||
let LOG_PACKET = Settings.LOG_PACKET;
|
||||
let PLUG_INFO = Settings.plugInfo;
|
||||
|
||||
const Orvibo = function(userSettings) {
|
||||
const Orvibo = function(userSettings = {}) {
|
||||
// Allow user to pass in settings
|
||||
if (userSettings != null) {
|
||||
ORVIBO_KEY = userSettings.ORVIBO_KEY;
|
||||
LOG_PACKET = userSettings.LOG_PACKET;
|
||||
PLUG_INFO = userSettings.plugInfo;
|
||||
}
|
||||
if('ORVIBO_KEY' in userSettings) ORVIBO_KEY = userSettings.ORVIBO_KEY;
|
||||
if('plugInfo' in userSettings) PLUG_INFO = userSettings.plugInfo;
|
||||
if('PLUG_INFO' in userSettings) PLUG_INFO = userSettings.PLUG_INFO;
|
||||
if('LOG_PACKET' in userSettings) LOG_PACKET = userSettings.LOG_PACKET;
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
@ -75,6 +76,7 @@ let handshakeHandler = function(plugPacket, socket, socketData) {
|
||||
name: getNameForUid(uid)
|
||||
});
|
||||
respondAndSetData(pkData, socket, PacketBuilder.handshakePacket);
|
||||
logger.log(`Connected ${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()
|
||||
});
|
||||
respondAndSetData(pkData, socket, PacketBuilder.heartbeatPacket);
|
||||
logger.log(`Plug ${pkData.name} ${pkData.uid} sent heartbeat`);
|
||||
this.emit('gotHeartbeat', {uid:pkData.uid, name: pkData.name});
|
||||
};
|
||||
|
||||
@ -94,6 +97,7 @@ let stateUpdateHandler = function(plugPacket, socket, socketData) {
|
||||
state: plugPacket.getValue1()
|
||||
});
|
||||
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});
|
||||
};
|
||||
|
||||
@ -125,7 +129,7 @@ Orvibo.prototype.startServer = function() {
|
||||
let self = this;
|
||||
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) {
|
||||
|
||||
@ -139,17 +143,22 @@ Orvibo.prototype.startServer = function() {
|
||||
let plugPacket = new Packet(data);
|
||||
|
||||
if (!plugPacket.validCRC()) {
|
||||
console.log('Got invalid CRC');
|
||||
logger.log('Got invalid CRC');
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugPacket.packetTypeText() === 'pk') {
|
||||
plugPacket.processPacket(ORVIBO_KEY);
|
||||
} else {
|
||||
plugPacket.processPacket(socketData.encryptionKey);
|
||||
try {
|
||||
if (plugPacket.packetTypeText() === 'pk') {
|
||||
plugPacket.processPacket(ORVIBO_KEY);
|
||||
} 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()];
|
||||
if (handler != null) {
|
||||
@ -161,14 +170,15 @@ Orvibo.prototype.startServer = function() {
|
||||
|
||||
socket.on('end', function () {
|
||||
let pkData = getData(socket.id);
|
||||
logger.log(`Plug ${pkData.uid} - ${pkData.name} disconnected`);
|
||||
self.emit('plugDisconnected', {uid: pkData.uid, name: pkData.name});
|
||||
delete packetData[socket.id];
|
||||
plugConnections.splice(plugConnections.indexOf(socket), 1);
|
||||
});
|
||||
|
||||
socket.on('error', (err) => {
|
||||
console.log(err);
|
||||
console.log('error with socket ' + socket.id);
|
||||
logger.log(err);
|
||||
logger.log(`Plug ${socket.id} - ${socket.name} disconnected with error`);
|
||||
self.emit('plugDisconnectedWithError', getData(socket.id));
|
||||
delete packetData[socket.id];
|
||||
plugConnections.splice(plugConnections.indexOf(socket), 1);
|
||||
@ -190,7 +200,7 @@ Orvibo.prototype.toggleSocket = function(uid) {
|
||||
}
|
||||
}
|
||||
if (socketId === null) {
|
||||
console.log('Could not find socket ' + uid);
|
||||
logger.log('Could not find socket ' + uid);
|
||||
return;
|
||||
}
|
||||
let socket = plugConnections.find(s => s.id === socketId);
|
||||
@ -209,11 +219,11 @@ Orvibo.prototype.toggleSocket = function(uid) {
|
||||
socket.write(packet);
|
||||
|
||||
} else {
|
||||
console.log('Can not find socket ');
|
||||
logger.log('Can not find socket ');
|
||||
}
|
||||
};
|
||||
|
||||
Orvibo.prototype.getConnectedSocket = function() {
|
||||
Orvibo.prototype.getConnectedSockets = function() {
|
||||
let sockets = [];
|
||||
for (const key of Object.keys(packetData)) {
|
||||
let socketData = getData(key);
|
||||
@ -227,4 +237,10 @@ Orvibo.prototype.getConnectedSocket = function() {
|
||||
return sockets;
|
||||
};
|
||||
|
||||
Orvibo.prototype.getConnectedSocket = Orvibo.prototype.getConnectedSockets;
|
||||
|
||||
Orvibo.prototype.setLogger = function(newLogger) {
|
||||
logger = newLogger;
|
||||
};
|
||||
|
||||
module.exports = Orvibo;
|
@ -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 (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
|
||||
|
||||
I'm more than happy for other people to contribute to this library just send a pull request.
|
||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "orvibo-b25-server",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "orvibo-b25-server",
|
||||
"version": "1.0.1",
|
||||
"version": "1.2.0",
|
||||
"description": "A server to control the Orvibo B25 range of smart sockets",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user