| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
=head1 NAME |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
Device::Osram::Lightify::API - API Documentation |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 API Overview |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
The starting point for using this module is that you have a hub with |
|
9
|
|
|
|
|
|
|
an IP address upon your local LAN, which is able to communicate successfully |
|
10
|
|
|
|
|
|
|
with any installed bulbs you have. |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
The module itself is responsible for talking to your hub, and sending |
|
13
|
|
|
|
|
|
|
commands to it to initiate actions, or perform introspection, so you'll |
|
14
|
|
|
|
|
|
|
need the IP address of your hub available. |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=cut |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 Overview |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
The communication to/from the hub is carried out via short binary |
|
21
|
|
|
|
|
|
|
communication with the hub over TCP/IP on port 4000. |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=cut |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 Light Discovery |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
To discover the lights which are available to your hub we connect and |
|
28
|
|
|
|
|
|
|
send the following binary string to it: |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=for example begin |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
0x0B 0x00 0x00 0x13 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=for example end |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
Once sent we then read back a header. The header contains 11 bytes |
|
37
|
|
|
|
|
|
|
of reply. From this header we read the 10th byte which will tell us |
|
38
|
|
|
|
|
|
|
the number of bulbs which are available. |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
Once we know the number of lights we can then read 50 bytes for each |
|
41
|
|
|
|
|
|
|
one, and this block of data can be parsed to show the current state |
|
42
|
|
|
|
|
|
|
of that specific bulb. |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=for example begin |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
01 - ID byte 1 |
|
47
|
|
|
|
|
|
|
02 - ID byte 2 |
|
48
|
|
|
|
|
|
|
03 - MAC Address 1 |
|
49
|
|
|
|
|
|
|
04 - MAC Address 2 |
|
50
|
|
|
|
|
|
|
05 - MAC Address 3 |
|
51
|
|
|
|
|
|
|
05 - MAC Address 4 |
|
52
|
|
|
|
|
|
|
06 - MAC Address 5 |
|
53
|
|
|
|
|
|
|
07 - MAC Address 6 |
|
54
|
|
|
|
|
|
|
08 - MAC Address 7 |
|
55
|
|
|
|
|
|
|
09 - MAC Address 8 |
|
56
|
|
|
|
|
|
|
10 - Bulb Type |
|
57
|
|
|
|
|
|
|
11 - Firmware Version 1 |
|
58
|
|
|
|
|
|
|
12 - Firmware Version 2 |
|
59
|
|
|
|
|
|
|
13 - Firmware Version 3 |
|
60
|
|
|
|
|
|
|
14 - Firmware Version 4 |
|
61
|
|
|
|
|
|
|
15 - Online/Offline |
|
62
|
|
|
|
|
|
|
16 - Group ID 1 |
|
63
|
|
|
|
|
|
|
17 - Group ID 2 |
|
64
|
|
|
|
|
|
|
18 - Status 0 == off, 1 == on |
|
65
|
|
|
|
|
|
|
19 - Brightness (0-100) |
|
66
|
|
|
|
|
|
|
20 - Temperature 1 |
|
67
|
|
|
|
|
|
|
21 - Temperature 2 |
|
68
|
|
|
|
|
|
|
22 - R |
|
69
|
|
|
|
|
|
|
23 - G |
|
70
|
|
|
|
|
|
|
24 - B |
|
71
|
|
|
|
|
|
|
25 - W |
|
72
|
|
|
|
|
|
|
26 - Name 1 |
|
73
|
|
|
|
|
|
|
27 - Name 2 |
|
74
|
|
|
|
|
|
|
28 - Name 3 |
|
75
|
|
|
|
|
|
|
29 - Name 4 |
|
76
|
|
|
|
|
|
|
30 - Name 5 |
|
77
|
|
|
|
|
|
|
31 - Name 6 |
|
78
|
|
|
|
|
|
|
.. - Name 15 |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=for example end |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
B<NOTE> The returned 50 bytes are NULL-terminated/padded. |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
You'll almost certainly want to make sure you can parse this stuff, |
|
85
|
|
|
|
|
|
|
because users will want to operate upon bulbs by name - and the API |
|
86
|
|
|
|
|
|
|
only allows you to operate on specific devices by MAC-address, so at |
|
87
|
|
|
|
|
|
|
the very least you must be able to lookup `NAME -> MAC`. |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=cut |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head1 Broadcast |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
There are two simple commands which will turn B<all> lights on, or off, |
|
95
|
|
|
|
|
|
|
these are simple to get started with because you don't need to set the |
|
96
|
|
|
|
|
|
|
MAC address of the bulb inside the command. |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
To turn all bulbs on send this: |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=for example begin |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
0x0f 0x00 0x00 0x32 0x01 0x00 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x01 |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=for example end |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
To turn all bulbs off send this: |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=for example begin |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
0x0f 0x00 0x00 0x32 0x01 0x00 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x00 |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=for example end |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Once sent read back 20 bytes to get your result. |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=cut |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=head1 Light-Specific Commands |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
The rest of the commands are going to be bulb-specific, and involve |
|
122
|
|
|
|
|
|
|
sending a command with the MAC address of the destination device inside |
|
123
|
|
|
|
|
|
|
their bodies. |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
It seems to be the case that we need to set a session ID with each |
|
126
|
|
|
|
|
|
|
command, to avoid issues with commands being dropped as previously-seen |
|
127
|
|
|
|
|
|
|
or otherwise prevent replay-attacks. |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
I've denoted such bytes as SS SS SS SS in the following commands. |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=cut |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 On/Off |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
To set a specific bulb ON or OFF you need to send the following |
|
136
|
|
|
|
|
|
|
magic string: |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=for example begin |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
0F 00 00 32 SS SS SS SS NN NN NN NN NN NN NN NN ON |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=for example end |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
Here `NN` should be replaced with the MAC address of the device you |
|
145
|
|
|
|
|
|
|
wish to control, backwards, and the last byte C<ON> should be replaced |
|
146
|
|
|
|
|
|
|
by C<0x00> to turn the device off, and C<0x01> to turn it on. |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
Once set read back 20 bytes to get your result. |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=cut |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head2 Brightness |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
To set a specific brightness for a bulb you need to send the following |
|
155
|
|
|
|
|
|
|
magic string: |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=for example begin |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
11 00 00 31 SS SS SS SS NN NN NN NN NN NN NN NN XX 00 00 |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=for example end |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
Here `NN` should be replaced with the MAC address of the device you |
|
164
|
|
|
|
|
|
|
wish to control, backwards, and the byte C<XX> should be replaced |
|
165
|
|
|
|
|
|
|
with the brighness level you wish to set, in the range 0-100. |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
Once sent read back 20 bytes to get your result. |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=cut |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=head2 Colour |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
To set specific RGBW values for a bulb you need to send the following |
|
174
|
|
|
|
|
|
|
magic string: |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=for example begin |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
14 00 00 36 SS SS SS SS NN NN NN NN NN NN NN NN RR GG BB WW 00 00 |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=for example end |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Here `NN` should be replaced with the MAC address of the device you |
|
183
|
|
|
|
|
|
|
wish to control, backwards, and the bytes RR,GG,BB,WW should be updated |
|
184
|
|
|
|
|
|
|
with the appropriate values. |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Once sent read back 20 bytes to get your result. |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=cut |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
|
|
191
|
1
|
|
|
1
|
|
13321
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
31
|
|
|
192
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
32
|
|
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
1; |
|
195
|
|
|
|
|
|
|
|