This repository has been archived by the owner on Jul 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cli.js
executable file
·110 lines (102 loc) · 3.25 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
const { discovery, v3 } = require('node-hue-api')
const commander = require('commander')
const convert = require('color-convert')
const fs = require('fs')
const os = require("os")
const path = require('path')
const { program, Option } = commander
const api = v3.api
const settingsFromFile = () => {
try {
const data = fs.readFileSync(path.resolve(__dirname, 'busylight.json'))
return JSON.parse(data)
} catch (err) {
console.error(err)
}
}
const stateFromOptions = ({color, brightness}) => {
if (color === "off") return { on: false }
const xyz = convert.keyword.xyz(color)
const sum = xyz[0] + xyz[1] + xyz[2]
const xy = [xyz[0] / sum, xyz[1] / sum]
const state = { on: true, bri: brightness, hue: 255, sat: 254, ct: 500, xy: xy }
return state
}
const init = async (options) => {
try {
const results = await discovery.nupnpSearch()
if (results.length === 0) throw new Error('nupnpSearch: No devices found')
// const results = await discovery.mdnsSearch()
// if (results.length === 0) throw new Error('mdnsSearch: No devices found')
const host = results[0].ipaddress
const local = await api.createLocal(host).connect()
const user = await local.users.createUser(options.init, os.hostname())
fs.writeFileSync('busylight.json', JSON.stringify(user))
} catch (err) {
console.error(err)
}
}
const main = async (options) => {
try {
const settings = settingsFromFile()
const results = await discovery.nupnpSearch()
if (results.length === 0) throw new Error('nupnpSearch: No devices found')
// const results = await discovery.mdnsSearch()
// if (results.length === 0) throw new Error('mdnsSearch: No devices found')
console.log(results)
const host = results[0].ipaddress
const secure = await api.createLocal(host).connect(settings.username)
if (options.list) {
const lights = await secure.lights.getAll()
for (const light of lights) {
console.log(light.data.name)
}
return
}
const light = (await secure.lights.getLightByName(options.light))[0]
const state = stateFromOptions(options)
await secure.lights.setLightState(light.id, state)
} catch (err) {
console.log(err)
throw err
}
}
const parseBrightness = (value, _) => {
const number = parseInt(value, 10)
if (isNaN(number))
throw new commander.InvalidArgumentError('Not a number')
if (number <= 0 || number >= 255)
throw new commander.InvalidArgumentError('Brightness must be [1, 255)')
return number
}
program
.addOption(
new Option('--init <app-name>', description="Create a new busylight app")
)
.addOption(
new Option('-c, --color <css-color-name>', description="Set device color")
.default('white')
)
.addOption(
new Option('-b, --brightness <integer>', description="Set device brightness")
.default(100)
.argParser(parseBrightness)
)
.addOption(
new Option('-l, --light <name>', description="Select a device")
)
.addOption(
new Option('--list', description="List all local device names")
)
program.parse()
const options = program.opts()
if (options.init) {
init(options)
} else {
// three attempts before giving up
fn = main.bind(undefined, options)
fn()
.catch(() => fn())
.catch(() => fn())
.catch(() => fn())
}