-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhue-lights-inline.template.mjs
executable file
·135 lines (114 loc) · 4.95 KB
/
hue-lights-inline.template.mjs
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env zx
// Required parameters:
// @raycast.schemaVersion 1
// @raycast.title Lights
// @raycast.mode inline
// @raycast.packageName Philips Hue
// Optional parameters:
// @raycast.icon 💡
// @raycast.refreshTime 2m
// Documentation:
// @raycast.author Jono Hewitt
// @raycast.authorURL https://github.com/jonohewitt
// @raycast.description Show inline summary of any Hue compatible lights. Choose to show on/off, brightness percentage, colour temperature or hue, saturation, brightness values. Recommended to have already assigned names to lights in the Hue app.
// This script requires:
// • A global install of zx. To install, run 'npm i -g zx' or 'yarn global add zx'.
// More info: https://github.com/google/zx
// • Your Hue Bridge local IP address, e.g 192.168.1.2
// • An authorised username, e.g 1028d66426293e821ecfd9ef1a0731df
// • Names to be assigned to the bulbs. You can do this in the Hue app.
// Follow the steps here for the bridge IP and how to create a username:
// https://developers.meethue.com/develop/get-started-2/
// Remember to remove .template from the filename after customising.
// Config:
const hueBridgeIP = '<enter bridge ip here>' // e.g 192.168.1.2
const userID = '<enter username here>' // e.g 1028d66426293e821ecfd9ef1a0731df
// 0 for On/Off
// 1 for brightness percentage,
// 2 for Hue, Saturation, Brightness if supported by full colour bulbs,
// or colour temperature in K and brightness percentage in temperature only lights, e.g 'White Ambiance'
const outputType = 1
// Optional:
// Specify which lights you want to include, in order, by their name (case sensitive).
// These names must have already been assigned to the lights via the Hue app.
// Use an empty array for all lights.
const chosenLights = [] // E.g ['Main', 'Desk']
// Optional:
// If you want to use a different bulb name to the name in your Hue settings, you can assign that here.
// The object key is the Hue name and the value is your arbitrary custom name.
const customNames = {} // E.g { Main: 'Ceiling', Desk: 'Lamp' }
// Code:
// Necessary to prevent fetch logging to the console automatically
$.verbose = false
// Collect data on all lights connected to the bridge
const lightsData = await fetch(`http://${hueBridgeIP}/api/${userID}/lights`, {
timeout: 500,
})
.then(res => res.json())
.catch(async () => {
// Sometimes your router might change the local IP address of the Hue bridge
// If this happens, the new IP address will be fetched and show inline until you update it
// Try to reserve an IP address for the bridge on your router to avoid this happening
const newIP = await fetch(`https://discovery.meethue.com`)
.then(res => res.json())
.then(data => data[0].internalipaddress)
.catch(() => {
console.error('Couldnt find a Hue bridge on your network!')
process.exit(1)
})
console.error(
`Hue bridge IP is now ${newIP}, update this in the script config!`
)
process.exit(1)
})
Object.keys(customNames)
.concat(chosenLights)
.forEach(lightName => {
if (!Object.entries(lightsData).find(bulb => bulb[1].name === lightName)) {
console.error(
`"${lightName}" isn't a bulb name yet! Check chosenLights & customNames`
)
process.exit(1)
}
})
const reducer = (output, bulb) => {
output += `${customNames[bulb.name] || bulb.name}: `
if (bulb.state.reachable && bulb.state.on) {
// Conditions are stacked with logical OR operators so that no bulb is asked for values it doesn't support
if (outputType === 0 || bulb.type === 'On/off light') {
output += 'On, '
} else if (outputType === 1 || bulb.type === 'Dimmable light') {
// Convert brightness from (0-254) to (0-100%)
output += `${Math.round((bulb.state.bri / 254) * 100)}%, `
} else if (outputType === 2) {
if (bulb.type === 'Color temperature light') {
// Convert colour temperature from mired units to kelvin units
output += `${Math.round(1000000 / bulb.state.ct)} K, ${Math.round(
(bulb.state.bri / 254) * 100
)}%, `
} else if (
bulb.type === 'Color light' ||
bulb.type === 'Extended color light'
) {
// Convert hue from (0-65535) to (0-360°)
output += `${Math.round((bulb.state.hue / 65535) * 360)}°, ${Math.round(
(bulb.state.sat / 254) * 100
)}%, ${Math.round((bulb.state.bri / 254) * 100)}% — `
}
}
} else if (bulb.state.reachable) output += 'Off, '
// Usually this means the light has been turned off manually at a switch
else output += 'Unreachable, '
return output
}
const inlineOutput = Object.entries(lightsData)
.map(entry => entry[1])
.filter(light => !chosenLights.length || chosenLights.includes(light.name))
.sort((a, b) => {
if (chosenLights.length) {
return chosenLights.indexOf(a.name) - chosenLights.indexOf(b.name)
}
})
.reduce(reducer, '')
.slice(0, -2)
console.log(inlineOutput || 'No lights found, check your configuration!')