mirror of
https://github.com/karl0ss/orvibo-b25-server-kex.git
synced 2025-04-29 12:53:40 +01:00
commit
4516cd44c2
@ -1,12 +1,5 @@
|
||||
# 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
|
||||
|
84
Docker.js
84
Docker.js
@ -1,84 +0,0 @@
|
||||
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();
|
||||
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}`)
|
||||
});
|
@ -10,4 +10,4 @@ COPY . .
|
||||
|
||||
EXPOSE 3000 10001
|
||||
|
||||
CMD [ "node", "Docker.js" ]
|
||||
CMD [ "node", "index.js" ]
|
||||
|
77
Example.js
77
Example.js
@ -1,77 +0,0 @@
|
||||
const Orvibo = require('./Orvibo');
|
||||
const http = require('http');
|
||||
const url = require('url');
|
||||
|
||||
const httpPort = 3000;
|
||||
|
||||
// Create a settings object to pass PK key and map sockets to names
|
||||
const settings = {
|
||||
LOG_PACKET: false, //Show incoming packet data from the socket
|
||||
ORVIBO_KEY: '', // put your PK key here as plain text (See Readme)
|
||||
plugInfo : [
|
||||
// Add uid and a name so you can easily identify the connected sockets
|
||||
{
|
||||
uid :'53dd7fe74de7',
|
||||
name: "Lamp in Kitchen"
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
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}`)
|
||||
});
|
111
README.md
111
README.md
@ -1,20 +1,15 @@
|
||||
|
||||
# Orvibo B25 Smart Socket Server
|
||||
|
||||
A server to control the B25 range of wifi Smart Sockets
|
||||
|
||||
While building a home automation system I bought a couple of Orvibo smart sockets from ebay that were advertised as the S20 model.
|
||||
When they arrived they were actually the B25 (AUS) version and I could not find any node libraries to control them.
|
||||
# Orvibo B25 Smart Socket Server (Kex)
|
||||
|
||||
After a bit of searching, reading research by other people and some time with Wireshark I manged to setup
|
||||
a relay server that would decrypt the packets going back and forth between the sockets and the server and worked out the protocol.
|
||||
A server to control the B25 range of wifi Smart Sockets.
|
||||
|
||||
After that I created this project which is basically a server that the Orvibo sockets connect to instead of the actual one.
|
||||
Once the sockets have connected you can toggle them on and off
|
||||
This server was largely based on the work done by [Sandy Milne](https://github.com/sandysound).
|
||||
|
||||
## Getting Started
|
||||
|
||||
To run this server you will need to have Node.js installed. I run v6.11.0 but it may work with earlier versions.
|
||||
To run this server you will need to have Node.js installed. I run v11.
|
||||
|
||||
You will need to add the Orvibo PK key to decrypt and encrypt the initial packets.
|
||||
You can find this using helpful bash script from Grayda [getKey.sh](https://gist.github.com/Grayda/eb48093bcfb96bfeec9c58ea301f2668) (you may have to add www to to url to make it work)
|
||||
@ -23,31 +18,12 @@ Once you have this key you will need to add it the ``OrviboSettings.js`` file or
|
||||
|
||||
For each socket on your network you will need to add its MAC address (colons removed and lower cased) to the plugInfo array as a uid and give it a name field for easier identification.
|
||||
|
||||
You can see this in the Example.js file
|
||||
```
|
||||
// Create a settings object to pass PK key and map sockets to names
|
||||
const settings = {
|
||||
LOG_PACKET: false, //Show incoming packet data from the socket
|
||||
ORVIBO_KEY: '', // put your PK key here as plain text (See Readme)
|
||||
plugInfo : [
|
||||
// Add uid and a name so you can easily identify the connected sockets
|
||||
{
|
||||
uid :'53dd7fe74de7',
|
||||
name: "Lamp in Kitchen"
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
let orvibo = new Orvibo(settings);
|
||||
```
|
||||
|
||||
Because these new sockets don't use UDP packets to communicate like the older versions you will also need to redirect all traffic from the host name ``homemate.orvibo.com``
|
||||
on TCP port 10001 the computer running the server.
|
||||
|
||||
I used an Ubuntu machine running dnsmasq and set this server as my DNS server in my router but depending on your network you might have to do it differently. Most routers will let you modify your DNS settings under the WAN settings.
|
||||
|
||||
Make sure to set a static IP address to the computer that will be running the Ubuntu server (In following example, the ip of machine running this server is at 192.168.0.106)
|
||||
|
||||
```
|
||||
server=8.8.8.8
|
||||
address=/homemate.orvibo.com/192.168.0.106
|
||||
@ -55,10 +31,11 @@ address=/homemate.orvibo.com/192.168.0.106
|
||||
|
||||
To confirm your dnsmasq is working, when visiting ``homemate.orvibo.com:10001`` from your browser the server should return a response.
|
||||
|
||||
|
||||
You will know things are working when you hit the server in your browser (for Example.js this would be ``http://localhost:3000``) and start seeing your sockets in the array.
|
||||
|
||||
Just a note: If you try to add a socket after you've redirected the DNS you will be ale to setup WiFi and use it with this library but your phone will probably timeout when trying to add the device
|
||||
to the official Orvibo server.
|
||||
Just a note: If you try to add a socket after you've redirected the DNS you will be ale to setup WiFi and use it with this library but your phone will probably timeout when trying to add the device to the official Orvibo server.
|
||||
|
||||
|
||||
### Installing
|
||||
|
||||
@ -68,33 +45,13 @@ Clone the repo and then run
|
||||
```
|
||||
npm install
|
||||
```
|
||||
to install the dependencies (buffer-crc32)
|
||||
|
||||
or from npm just run
|
||||
|
||||
```
|
||||
npm i orvibo-b25-server
|
||||
```
|
||||
to install the dependencies
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
The best way to see how to use this library is to see ``Example.js``
|
||||
|
||||
To start the example http server run
|
||||
|
||||
```
|
||||
npm start
|
||||
```
|
||||
This will start the Orvibo socket server create a basic example HTTP server used for interacting with sockets.
|
||||
Calling this http server with no parameters will return the uid, state or the switch, 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
|
||||
|
||||
One thing to note is the Orvibo uses 1 as off and 0 as on for the socket state.
|
||||
|
||||
## Docker
|
||||
I have extened this project to also run in a docker container.
|
||||
|
||||
Easiest way to use this is to run it in a docker container.
|
||||
|
||||
PK and PlugArray can be passed in via enviroment variables.
|
||||
|
||||
@ -103,7 +60,7 @@ PK and PlugArray can be passed in via enviroment variables.
|
||||
|
||||
Example run command -
|
||||
|
||||
docker run --env orviboPK='OrviboPKkey' --env plugArray='uid:MACADDRESS1,name:PLUGNAME1,uid:MACADDRESS2,name:PLUGNAME2' -p 3000:3000 -p 10001:10001 karl0ss/orvibo-b25-server
|
||||
docker run --env orviboPK='OrviboPKkey' --env plugArray='uid:MACADDRESS,name:PLUGNAME' -p 3000:3000 -p 10001:10001 karl0ss/orvibo-b25-server
|
||||
|
||||
Docker-Compose example -
|
||||
|
||||
@ -120,44 +77,54 @@ Docker-Compose example -
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- orviboPK=OrviboPKkey
|
||||
- plugArray=uid:MACADDRESS1,name:PLUGNAME1,uid:MACADDRESS2,name:PLUGNAME2
|
||||
- plugArray=uid:MACADDRESS,name:PLUGNAME
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
Once you've got a socket connecting to the official app you can add it to the plugInfo array in the OrviboSettings.js or to your settings object you pass in.
|
||||
This will match to uid to a name so you can easily see which socket is which.
|
||||
|
||||
## Confirmed Working Models
|
||||
|
||||
A list of Orvibo devices, confirmed by contributors, that work with this project:
|
||||
|
||||
|
||||
| Device Name | Product ID | Confirmed By |
|
||||
| --- | --- | --- |
|
||||
| Orvibo Smart Socket (EU/AUS) | B25 | @sandysound |
|
||||
| Orvibo Smart Socket (US/CAD) | S25 | @wichopy |
|
||||
| Orvibo Smart Socket (UK/GB) | B25UK | @valchonedelchev |
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
I'm more than happy for other people to contribute to this library just send a pull request.
|
||||
|
||||
This project will probably work with other versions of the smart sockets that use the homemate app.
|
||||
If you manage to get it working let me know so I can add it here as supported.
|
||||
|
||||
Also if you'd like to contribute to help me buy additional Orvibo products to add to this server or the software has helped you in your own home automation projects and you just want to buy me a beer. You can sponsor it via my paypal account at
|
||||
[http://paypal.me/sandysounds](http://paypal.me/sandysounds)
|
||||
|
||||
## Authors
|
||||
|
||||
* **Sandy Milne** - [SandySound - Github](https://github.com/sandysound)
|
||||
|
||||
|
||||
|
||||
|
||||
* **Karl Hudgell** - [Karl0ss](https://github.com/karl0ss/)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
This project is licensed under the Apache 2.0 License - see the [LICENSE.md](LICENSE.md) file for details
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Big thanks to [Grayda](https://github.com/Grayda/) and [insertjokehere](https://github.com/insertjokehere) for all their research and hard work into how these sockets work
|
||||
|
||||
|
||||
|
||||
|
||||
Big thanks to [Grayda](https://github.com/Grayda/) and [insertjokehere](https://github.com/insertjokehere) and [Sandy Milne](https://github.com/sandysound)
|
||||
|
||||
|
||||
|
27
Utils.js
27
Utils.js
@ -1,27 +0,0 @@
|
||||
module.exports.generateRandomTextValue = function(length) {
|
||||
let chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
let result = '';
|
||||
for (let i = length; i > 0; --i) {
|
||||
result += chars[Math.floor(Math.random() * chars.length)];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports.generateRandomHexValue = function(length) {
|
||||
let chars = '0123456789abcdef';
|
||||
let result = '';
|
||||
for (let i = length; i > 0; --i) {
|
||||
result += chars[Math.floor(Math.random() * chars.length)];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports.generateRandomNumber = function(length) {
|
||||
let numbers = '0123456789';
|
||||
let result = '';
|
||||
for (let i = length; i > 0; --i) {
|
||||
result += numbers[Math.floor(Math.random() * numbers.length)];
|
||||
}
|
||||
return parseInt(result);
|
||||
};
|
||||
|
68
index.js
68
index.js
@ -1,2 +1,66 @@
|
||||
// Index file for npm
|
||||
module.exports = require('./Orvibo');
|
||||
const Orvibo = require('./server/utils/Orvibo');
|
||||
const utils = require('./server/utils/Utils')
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
app.set('view engine', 'pug');
|
||||
app.use(express.static(__dirname + '/server'));
|
||||
|
||||
const settings = {
|
||||
LOG_PACKET: true, //Show incoming packet data from the socket
|
||||
ORVIBO_KEY: process.env.orviboPK,
|
||||
plugInfo :
|
||||
utils.generatePlugArray(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();
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
let sockets = orvibo.getConnectedSocket();
|
||||
// let sockets = [{name: "Plug1", state: 1, uid: "222222"},{name: "Plug2", state: 0, uid: "111111"}]
|
||||
|
||||
if (req.query.uid != undefined) {
|
||||
orvibo.toggleSocket(req.query.uid);
|
||||
}
|
||||
|
||||
sockets = orvibo.getConnectedSocket();
|
||||
|
||||
utils.setState(sockets)
|
||||
|
||||
res.render('index', {
|
||||
title: 'Orvibo b25 Server',
|
||||
sockets
|
||||
})
|
||||
});
|
||||
|
||||
const server = app.listen(3000, () => {
|
||||
console.log(`Express running → PORT ${server.address().port}`);
|
||||
});
|
3269
package-lock.json
generated
3269
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
@ -1,15 +1,14 @@
|
||||
{
|
||||
"name": "orvibo-b25-server",
|
||||
"version": "1.2.0",
|
||||
"name": "orvibo-b25-server (Kex)",
|
||||
"version": "1.0.0",
|
||||
"description": "A server to control the Orvibo B25 range of smart sockets",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node Example.js"
|
||||
"start": "node index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sandysound/orvibo-b25-server.git"
|
||||
"url": "git+https://github.com/karl0ss/orvibo-b25-server.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Orvibo",
|
||||
@ -17,13 +16,15 @@
|
||||
"Smart",
|
||||
"Socket"
|
||||
],
|
||||
"author": "Sandy Milne <sandymilne@protonmail.ch>",
|
||||
"author": "Karl Hudgell",
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sandysound/orvibo-b25-server/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sandysound/orvibo-b25-server#readme",
|
||||
"homepage": "https://github.com/karl0ss/orvibo-b25-server#readme",
|
||||
"dependencies": {
|
||||
"buffer-crc32": "^0.2.13"
|
||||
"buffer-crc32": "^0.2.13",
|
||||
"express": "^4.17.1",
|
||||
"pug": "^2.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^1.19.1"
|
||||
}
|
||||
}
|
||||
|
83
server/css/style.css
Normal file
83
server/css/style.css
Normal file
@ -0,0 +1,83 @@
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: inherit; /* [1] */
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; /* [2] */
|
||||
}
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 80px;
|
||||
background-color: #525286;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-gap: 20px;
|
||||
}
|
||||
|
||||
.socket {
|
||||
text-align: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.button-off {
|
||||
background-color:#fc0000;
|
||||
-moz-border-radius:28px;
|
||||
-webkit-border-radius:28px;
|
||||
border-radius:28px;
|
||||
border:1px solid #000000;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
color:#ffffff;
|
||||
font-family:Arial;
|
||||
font-size:17px;
|
||||
padding:16px 31px;
|
||||
text-decoration:none;
|
||||
text-shadow:0px 1px 0px #000000;
|
||||
}
|
||||
.button-off:hover {
|
||||
background-color:red;
|
||||
}
|
||||
.button-off:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
|
||||
.button-on {
|
||||
background-color:#44c767;
|
||||
-moz-border-radius:28px;
|
||||
-webkit-border-radius:28px;
|
||||
border-radius:28px;
|
||||
border:1px solid black;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
color:#ffffff;
|
||||
font-family:Arial;
|
||||
font-size:17px;
|
||||
padding:16px 31px;
|
||||
text-decoration:none;
|
||||
text-shadow:0px 1px 0px #2f6627;
|
||||
}
|
||||
.button-on:hover {
|
||||
background-color:#5cbf2a;
|
||||
}
|
||||
.button-on:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
61
server/utils/Utils.js
Normal file
61
server/utils/Utils.js
Normal file
@ -0,0 +1,61 @@
|
||||
module.exports.generateRandomTextValue = function(length) {
|
||||
let chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
let result = '';
|
||||
for (let i = length; i > 0; --i) {
|
||||
result += chars[Math.floor(Math.random() * chars.length)];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports.generateRandomHexValue = function(length) {
|
||||
let chars = '0123456789abcdef';
|
||||
let result = '';
|
||||
for (let i = length; i > 0; --i) {
|
||||
result += chars[Math.floor(Math.random() * chars.length)];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports.generateRandomNumber = function(length) {
|
||||
let numbers = '0123456789';
|
||||
let result = '';
|
||||
for (let i = length; i > 0; --i) {
|
||||
result += numbers[Math.floor(Math.random() * numbers.length)];
|
||||
}
|
||||
return parseInt(result);
|
||||
};
|
||||
|
||||
module.exports.generatePlugArray = function(str) {
|
||||
const arr = str.split(',');
|
||||
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;
|
||||
}
|
||||
|
||||
module.exports.sleep = function(milliseconds) {
|
||||
var start = new Date().getTime();
|
||||
for (var i = 0; i < 1e7; i++) {
|
||||
if ((new Date().getTime() - start) > milliseconds){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.setState = function(sockets) {
|
||||
sockets.forEach(socket => {
|
||||
switch(socket.state) {
|
||||
case 1:
|
||||
socket.state = 'OFF'
|
||||
break;
|
||||
case 0:
|
||||
socket.state = 'ON'
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
}
|
12
views/default.pug
Normal file
12
views/default.pug
Normal file
@ -0,0 +1,12 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
title #{title}
|
||||
link(rel='stylesheet', href='css/style.css')
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||
body
|
||||
main
|
||||
block header
|
||||
header.header
|
||||
h1 #{title}
|
||||
block content
|
16
views/index.pug
Normal file
16
views/index.pug
Normal file
@ -0,0 +1,16 @@
|
||||
extends default
|
||||
|
||||
block content
|
||||
div.container
|
||||
each socket in sockets
|
||||
div.socket
|
||||
h2.socket-name
|
||||
| #{socket.name}
|
||||
h2.socket-name
|
||||
| #{socket.uid}
|
||||
if socket.state === 'OFF'
|
||||
a.button-off(href=`/?uid=${socket.uid}`)
|
||||
| #{socket.state}
|
||||
else
|
||||
a.button-on(href=`/?uid=${socket.uid}`)
|
||||
| #{socket.state}
|
Loading…
x
Reference in New Issue
Block a user