initial commit
This commit is contained in:
commit
011ab550cf
21
README.md
Normal file
21
README.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# TP-Link Bulb Web
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
$ npm install
|
||||||
|
or
|
||||||
|
$ yarn
|
||||||
|
|
||||||
|
## Start
|
||||||
|
|
||||||
|
You can provide the listening port and bulb ip address, if not are defaults
|
||||||
|
|
||||||
|
$ npm start 3000 10.0.0.130
|
||||||
|
or
|
||||||
|
$ yarn start 3000 10.0.0.130
|
||||||
|
|
||||||
|
![](screen.png)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
59
index.js
Normal file
59
index.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const TPLSmartDevice = require('tplink-lightbulb'),
|
||||||
|
express = require('express'),
|
||||||
|
app = express(),
|
||||||
|
morgan = require('morgan'),
|
||||||
|
rfs = require('rotating-file-stream'),
|
||||||
|
colorsys = require('colorsys'),
|
||||||
|
accessLogStream = rfs('access.log', { interval: '1d', path: __dirname + '/logs' }),
|
||||||
|
router = express.Router(),
|
||||||
|
ip = process.argv[3] || '10.0.0.130',
|
||||||
|
bulb = new TPLSmartDevice(ip)
|
||||||
|
|
||||||
|
app.use(morgan('combined', { stream: accessLogStream }))
|
||||||
|
.use('/api', router)
|
||||||
|
.use(express.static(__dirname + '/public'))
|
||||||
|
.listen(process.argv[2] || 3000)
|
||||||
|
|
||||||
|
router.use('/on/:brightness', (req, res, next) => {
|
||||||
|
bulb.power(true, 0, { brightness: parseInt(req.params.brightness) })
|
||||||
|
.then(r => res.json(r))
|
||||||
|
.catch(console.error)
|
||||||
|
})
|
||||||
|
.use('/on', (req, res, next) => {
|
||||||
|
bulb.power(true, 0, { brightness: 100 })
|
||||||
|
.then(r => res.json(r))
|
||||||
|
.catch(console.error)
|
||||||
|
})
|
||||||
|
.use('/off', (req, res, next) => {
|
||||||
|
bulb.power(false, 0)
|
||||||
|
.then(r => res.json(r))
|
||||||
|
.catch(console.error)
|
||||||
|
})
|
||||||
|
.use('/color/hex/:color', (req, res, next) => {
|
||||||
|
let color = colorsys.hexToHsl(req.params.color)
|
||||||
|
bulb.power(true, 0, {
|
||||||
|
hue: color.h,
|
||||||
|
saturation: color.s,
|
||||||
|
brightness: color.l,
|
||||||
|
color_temp: 0
|
||||||
|
})
|
||||||
|
.then(r => res.json(r))
|
||||||
|
.catch(console.error)
|
||||||
|
})
|
||||||
|
.use('/color/chsb/:colortemp/:hue/:saturation/:brightness', (req, res, next) => {
|
||||||
|
bulb.power(true, 0, {
|
||||||
|
color_temp: parseInt(req.params.colortemp),
|
||||||
|
hue: parseInt(req.params.hue),
|
||||||
|
saturation: parseInt(req.params.saturation),
|
||||||
|
brightness: parseInt(req.params.brightness)
|
||||||
|
})
|
||||||
|
.then(r => res.json(r))
|
||||||
|
.catch(console.error)
|
||||||
|
})
|
||||||
|
.use('/info', (req, res, next) => {
|
||||||
|
bulb.info()
|
||||||
|
.then(r => res.json(r.light_state))
|
||||||
|
.catch(console.error)
|
||||||
|
})
|
30
package.json
Normal file
30
package.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "tplink-bulb-web",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"readme": "README.md",
|
||||||
|
"description": "TP-Link Bulb Web",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"install": "cp node_modules/jquery/dist/jquery.min.js public/assets/js/ && cp node_modules/bootstrap/dist/js/bootstrap.min.js public/assets/js/ && cp node_modules/bootstrap/dist/css/bootstrap.min.css public/assets/css/ && cp node_modules/bootstrap/dist/css/bootstrap.min.css.map public/assets/css/",
|
||||||
|
"start": "node index.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://gitlab.com/manalejandro/tplink-bulb-web"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://gitlab.com/manalejandro/tplink-bulb-web/issues"
|
||||||
|
},
|
||||||
|
"author": "manalejandro@gmail.com",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bootstrap": "3.3.7",
|
||||||
|
"colorsys": "^1.0.21",
|
||||||
|
"express": "^4.16.3",
|
||||||
|
"jquery": "^3.3.1",
|
||||||
|
"morgan": "^1.9.0",
|
||||||
|
"rotating-file-stream": "^1.3.6",
|
||||||
|
"tplink-lightbulb": "^1.4.2"
|
||||||
|
}
|
||||||
|
}
|
0
public/assets/css/.gitignore
vendored
Normal file
0
public/assets/css/.gitignore
vendored
Normal file
BIN
public/assets/images/lb130-off.jpg
Normal file
BIN
public/assets/images/lb130-off.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
public/assets/images/lb130.jpg
Normal file
BIN
public/assets/images/lb130.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
41
public/assets/js/main.js
Normal file
41
public/assets/js/main.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
function setData(data) {
|
||||||
|
if (data.on_off)
|
||||||
|
$('.bulb').attr('src', 'assets/images/lb130.jpg')
|
||||||
|
else
|
||||||
|
$('.bulb').attr('src', 'assets/images/lb130-off.jpg')
|
||||||
|
$('.brightness').text(data.brightness || 0)
|
||||||
|
$('.hue').text(data.hue || 0)
|
||||||
|
$('.saturation').text(data.saturation || 0)
|
||||||
|
$('.colortemp').text(data.color_temp || 0)
|
||||||
|
$('#brightness').val(data.brightness || 0)
|
||||||
|
$('#hue').val(data.hue || 0)
|
||||||
|
$('#saturation').val(data.saturation || 0)
|
||||||
|
$('#colortemp').val(data.color_temp || 0)
|
||||||
|
}
|
||||||
|
function setCHSB() {
|
||||||
|
$.getJSON('/api/color/chsb/' + $('#colortemp').val() + '/' + $('#hue').val() + '/' + $('#saturation').val() + '/' + $('#brightness').val(), setData)
|
||||||
|
}
|
||||||
|
function setColor() {
|
||||||
|
$.getJSON('/api/color/hex/' + $('#color').val().replace('#', ''))
|
||||||
|
}
|
||||||
|
$('.on').on('click', function () {
|
||||||
|
if (parseInt($('.brightness').text()) > 0)
|
||||||
|
url = '/api/on/' + $('.brightness').text()
|
||||||
|
else
|
||||||
|
url = '/api/on'
|
||||||
|
$.getJSON(url, setData)
|
||||||
|
})
|
||||||
|
$('.off').on('click', function () {
|
||||||
|
$.getJSON('/api/off', setData)
|
||||||
|
})
|
||||||
|
$('form#chsb').on('submit', function (event) {
|
||||||
|
event.preventDefault()
|
||||||
|
setCHSB()
|
||||||
|
})
|
||||||
|
$('form#colorform').on('submit', function (event) {
|
||||||
|
event.preventDefault()
|
||||||
|
setColor()
|
||||||
|
})
|
||||||
|
$.getJSON('/api/info', setData)
|
||||||
|
})
|
79
public/index.html
Normal file
79
public/index.html
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>TP-Link Bulb Web</title>
|
||||||
|
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
|
||||||
|
<script src="assets/js/jquery.min.js"></script>
|
||||||
|
<script src="assets/js/bootstrap.min.js"></script>
|
||||||
|
<script src="assets/js/main.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="text-center col-md-12">
|
||||||
|
<h2>TP-Link Bulb Web</h2>
|
||||||
|
<div class="col-md-8 col-md-offset-2 container">
|
||||||
|
<p>
|
||||||
|
<img class="bulb img-responsive center-block">
|
||||||
|
</p>
|
||||||
|
<p class="lead">
|
||||||
|
<button class="on btn btn-success">ON</button>
|
||||||
|
<button class="off btn btn-warning">OFF</button>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="text-primary">Brightness:
|
||||||
|
<span class="brightness"></span>
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-success">Hue:
|
||||||
|
<span class="hue"></span>
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-warning">Saturation:
|
||||||
|
<span class="saturation"></span>
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
<span class="text-info">Color Temp:
|
||||||
|
<span class="colortemp"></span>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<form class="form-horizontal" id="chsb">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2 col-md-offset-4" for="brightness">Brightness (0-100)</label>
|
||||||
|
<div class="col-md-1">
|
||||||
|
<input class="form-control" id="brightness" type="number" min="0" max="100">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2 col-md-offset-4" for="hue">Hue (0-360)</label>
|
||||||
|
<div class="col-md-1">
|
||||||
|
<input class="form-control" id="hue" type="number" min="0" max="360">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2 col-md-offset-4" for="saturation">Saturation (0-100)</label>
|
||||||
|
<div class="col-md-1">
|
||||||
|
<input class="form-control" id="saturation" type="number" min="0" max="100">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2 col-md-offset-4" for="colortemp">Color Temp (0-7000)</label>
|
||||||
|
<div class="col-md-1">
|
||||||
|
<input class="form-control" id="colortemp" type="number" min="0" max="7000">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="setCHSB btn btn-primary">Set</button>
|
||||||
|
</form>
|
||||||
|
<p> </p>
|
||||||
|
<form class="form-horizontal" id="colorform">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2 col-md-offset-4" for="brightness">Color Hex</label>
|
||||||
|
<div class="col-md-1">
|
||||||
|
<input class="form-control" id="color" type="color" value="#FFFFFF">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="setColor btn btn-success">Set Color</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
BIN
screen.png
Normal file
BIN
screen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
Loading…
Reference in New Issue
Block a user