homebridge-dyson-solarcycle-morph 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +134 -0
- package/config.schema.json +34 -0
- package/dist/accessory.js +11 -0
- package/dist/accessory.js.map +1 -1
- package/dist/config.d.ts +27 -0
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -1
- package/dist/dyson/crypto.d.ts +10 -3
- package/dist/dyson/crypto.js +42 -4
- package/dist/dyson/crypto.js.map +1 -1
- package/dist/dyson/lamp.d.ts +109 -0
- package/dist/dyson/lamp.js +337 -15
- package/dist/dyson/lamp.js.map +1 -1
- package/dist/dyson/protocol.d.ts +79 -0
- package/dist/dyson/protocol.js +126 -2
- package/dist/dyson/protocol.js.map +1 -1
- package/docs/PROTOCOL.md +132 -9
- package/homebridge-ui/public/index.html +102 -0
- package/homebridge-ui/server.js +84 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,43 @@ All notable changes to this project are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.4.0] — 2026-09-21
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **The lamp can be told where it is.** Each light takes a latitude and a
|
|
13
|
+
longitude, and the plugin puts them in the lamp when they are not already
|
|
14
|
+
there. This is what daylight tracking runs on: the lamp turns coordinates
|
|
15
|
+
into sunrise and sunset and follows those. The MyDyson app sets them once
|
|
16
|
+
from the GPS of the phone the lamp was set up on and never asks again, so a
|
|
17
|
+
lamp that has moved house goes on tracking the daylight of the old one. Leave
|
|
18
|
+
the fields empty and nothing is written.
|
|
19
|
+
|
|
20
|
+
- **A *Use my current location* button on the settings page**, which fills both
|
|
21
|
+
fields in for every light. Your browser is asked first and only answers over
|
|
22
|
+
HTTPS; since the Homebridge UI is usually served over plain HTTP, the
|
|
23
|
+
coordinates are otherwise looked up from the address the machine reaches the
|
|
24
|
+
internet from. That is accurate to the nearest town — a degree of longitude
|
|
25
|
+
is four minutes of sunrise — and wrong behind a VPN, so what it fills in is
|
|
26
|
+
worth a glance before saving.
|
|
27
|
+
|
|
28
|
+
- **The lamp's age adjustment can be set from here too.** A year of birth per
|
|
29
|
+
light, and the lamp trims the brightness of its Study and Relax modes to suit
|
|
30
|
+
it. It needs two things to be true — the lamp holding the year, and its own
|
|
31
|
+
age-adjustment switch being on — so both are settings here, with the switch on
|
|
32
|
+
by default. The year is the one thing this lamp keeps encrypted; it stores a
|
|
33
|
+
year and nothing else, and only the Dyson account that set it can change it,
|
|
34
|
+
which the plugin reports rather than fighting.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **A setting the lamp refused is no longer reported as set.** The attribute
|
|
39
|
+
channel is the one part of this lamp that acknowledges a write, and nothing
|
|
40
|
+
here was reading the acknowledgement. It turns out the lamp refuses one now
|
|
41
|
+
and then for no reason that four measured comparisons could isolate, so these
|
|
42
|
+
writes are now checked and repeated up to three times, and a refusal that
|
|
43
|
+
survives that is said out loud instead of logged as a success.
|
|
44
|
+
|
|
8
45
|
## [1.3.1] — 2026-09-21
|
|
9
46
|
|
|
10
47
|
### Changed
|
package/README.md
CHANGED
|
@@ -150,6 +150,9 @@ Everything except the lights is optional.
|
|
|
150
150
|
| **Lights → Name** | What the lamp is called in the Home app |
|
|
151
151
|
| **Lights → BLE MAC address** | Filled in by the scan |
|
|
152
152
|
| **Lights → Serial number** | Filled in by the scan. Identifies the accessory, so changing it creates a new one |
|
|
153
|
+
| **Lights → Latitude**, **Longitude** | Where the lamp stands, in decimal degrees. Optional; set both or neither |
|
|
154
|
+
| **Lights → Year of birth** | Turns on the lamp's age adjustment. Optional |
|
|
155
|
+
| **Lights → Apply the age adjustment** | The lamp's own switch for it. On by default |
|
|
153
156
|
| **Lights → Expose daylight tracking** | The Daylight switch. On by default |
|
|
154
157
|
| **Lights → Expose auto brightness** | The Auto Brightness switch. On by default |
|
|
155
158
|
| **Lights → Expose movement mode** | The Movement switch. On by default |
|
|
@@ -160,6 +163,137 @@ Turning all four switches off leaves the lamp on its own: there is then nothing
|
|
|
160
163
|
for the second accessory to hold, so it is not created, and an existing one is
|
|
161
164
|
removed.
|
|
162
165
|
|
|
166
|
+
### The config block
|
|
167
|
+
|
|
168
|
+
The settings page writes this for you. It is worth knowing the shape anyway, for
|
|
169
|
+
editing `config.json` by hand and for reading what the UI produced:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"platform": "DysonSolarcycleMorph",
|
|
174
|
+
"name": "Dyson Solarcycle Morph",
|
|
175
|
+
"lights": [
|
|
176
|
+
{
|
|
177
|
+
"name": "Desk",
|
|
178
|
+
"mac": "F0:B1:A7:75:B1:D1",
|
|
179
|
+
"serial": "E5T-EU-NFA1279A",
|
|
180
|
+
"latitude": 48.6719,
|
|
181
|
+
"longitude": 9.2807,
|
|
182
|
+
"yearOfBirth": 1974,
|
|
183
|
+
"ageAdjust": true,
|
|
184
|
+
"daylightSwitch": true,
|
|
185
|
+
"autoBrightnessSwitch": true,
|
|
186
|
+
"movementSwitch": true,
|
|
187
|
+
"presetSwitches": true
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
"dysonAccount": { "email": "you@example.com", "country": "DE" },
|
|
191
|
+
"adapter": "hci0"
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
`platform` is how Homebridge finds the plugin, and each light needs a `name`, a
|
|
196
|
+
`mac` and a `serial`. Everything else can be left out; the switches then take
|
|
197
|
+
the defaults below, and the location and year of birth are simply not touched on
|
|
198
|
+
the lamp. The example above shows every key at once, which no real config needs.
|
|
199
|
+
|
|
200
|
+
| Key | Type | Default | |
|
|
201
|
+
|---|---|---|---|
|
|
202
|
+
| `platform` | string | — | Must be `DysonSolarcycleMorph` |
|
|
203
|
+
| `name` | string | `Dyson Solarcycle Morph` | The log prefix. The settings page insists on it |
|
|
204
|
+
| `lights[].name` | string | — | The name in the Home app |
|
|
205
|
+
| `lights[].mac` | string | — | `AA:BB:CC:DD:EE:FF` |
|
|
206
|
+
| `lights[].serial` | string | — | The accessory's identity; changing it makes a new accessory |
|
|
207
|
+
| `lights[].latitude` | number | unset | Decimal degrees, -90 to 90 |
|
|
208
|
+
| `lights[].longitude` | number | unset | Decimal degrees, -180 to 180 |
|
|
209
|
+
| `lights[].yearOfBirth` | integer | unset | 1900 to this year |
|
|
210
|
+
| `lights[].ageAdjust` | boolean | `true` | Only read when `yearOfBirth` is set |
|
|
211
|
+
| `lights[].daylightSwitch` | boolean | `true` | |
|
|
212
|
+
| `lights[].autoBrightnessSwitch` | boolean | `true` | |
|
|
213
|
+
| `lights[].movementSwitch` | boolean | `true` | |
|
|
214
|
+
| `lights[].presetSwitches` | boolean | `true` | Adds three switches, not one |
|
|
215
|
+
| `dysonAccount.email` | string | unset | Used by the settings page, never by the plugin |
|
|
216
|
+
| `dysonAccount.country` | string | `GB` | Two letters |
|
|
217
|
+
| `dysonAccount.password` | string | unset | Only while authorising; **Forget password** clears it |
|
|
218
|
+
| `adapter` | string | system default | e.g. `hci1` |
|
|
219
|
+
|
|
220
|
+
**A light with something wrong with it is skipped, and the rest still load** —
|
|
221
|
+
the message names the entry and the key. Two combinations are refused rather
|
|
222
|
+
than half-applied, because half of either would quietly do the wrong thing:
|
|
223
|
+
|
|
224
|
+
- `latitude` without `longitude`, or the other way round. A lamp told only its
|
|
225
|
+
latitude would put itself on the Greenwich meridian and track the wrong sunset
|
|
226
|
+
all year.
|
|
227
|
+
- `ageAdjust` without `yearOfBirth`. There would be nothing to adjust for.
|
|
228
|
+
|
|
229
|
+
**No key for the lamp appears here.** Pairing puts it in the plugin's storage
|
|
230
|
+
directory instead — see [What is stored, and where](#what-is-stored-and-where).
|
|
231
|
+
A `lights[].ltk` and `lights[].accountId` pair is accepted to override what is
|
|
232
|
+
stored, which exists for migrating an older setup; supply both or neither.
|
|
233
|
+
|
|
234
|
+
### Where the lamp is
|
|
235
|
+
|
|
236
|
+
Daylight tracking follows sunrise and sunset, and the lamp works those out from
|
|
237
|
+
its coordinates. The MyDyson app sets them once, from the GPS of the phone the
|
|
238
|
+
lamp was set up on, and never asks again — so a lamp added through the app
|
|
239
|
+
already knows, and one that has moved house still believes it is at the old
|
|
240
|
+
address.
|
|
241
|
+
|
|
242
|
+
The two fields exist to set the coordinates without the app, and to correct them
|
|
243
|
+
afterwards. Leave them empty and the plugin does not touch what the lamp holds —
|
|
244
|
+
it still reads them on connecting and puts them in the debug log, which is the
|
|
245
|
+
way to find out what the app put there:
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
Lamp F0:B1:A7:75:B1:D1 places itself at 48.67190, 9.28070
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Fill them in and it writes yours whenever the lamp disagrees, and says so:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
Location of F0:B1:A7:75:B1:D1 set to 48.67190, 9.28070 (was 50.11090, 8.68210)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Use my current location** on the settings page fills both fields in for every
|
|
258
|
+
light. It asks your browser first, which only answers on a page served over
|
|
259
|
+
HTTPS — the Homebridge UI is usually plain HTTP, and then the coordinates are
|
|
260
|
+
looked up instead from the address this machine reaches the internet from,
|
|
261
|
+
through [ipwho.is](https://ipwho.is) or [geojs.io](https://geojs.io). That is
|
|
262
|
+
accurate to the nearest town, which is all a sunrise needs, and wrong if the
|
|
263
|
+
connection goes out through a VPN. Nothing is sent to either service: they read
|
|
264
|
+
the public address the request arrives from, which is what every site this
|
|
265
|
+
machine contacts already sees. Check what it filled in before saving.
|
|
266
|
+
|
|
267
|
+
### Age adjustment
|
|
268
|
+
|
|
269
|
+
The lamp can trim the brightness of its **Study and Relax modes** to suit the
|
|
270
|
+
eyes of whoever mainly uses it, which it works out from a birth year. In the
|
|
271
|
+
MyDyson app's words: *"Light requirements change as a person ages. You can add a
|
|
272
|
+
birth year for the main intended user, and the brightness of Study mode and
|
|
273
|
+
Relax mode will automatically adjust."*
|
|
274
|
+
|
|
275
|
+
Two things have to be true for it to do anything, and the plugin handles both:
|
|
276
|
+
the lamp has to hold the year, and its age-adjustment switch has to be on. Set
|
|
277
|
+
**Year of birth** and the plugin writes it and turns the switch on; turn **Apply
|
|
278
|
+
the age adjustment** off to leave the year in place and stop the lamp acting on
|
|
279
|
+
it. Leave the year empty and neither setting is touched.
|
|
280
|
+
|
|
281
|
+
The lamp stores a year and nothing else — no day, no month — and it is the one
|
|
282
|
+
setting on this lamp kept encrypted, under a key derived from your lamp's own
|
|
283
|
+
long-term key. It also keeps it to the Dyson account that set it, which the app
|
|
284
|
+
explains as *"for privacy reasons, age adjust is only available to this light's
|
|
285
|
+
owner"*. If a different account got there first the plugin says so and changes
|
|
286
|
+
nothing:
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
The age adjustment on F0:B1:A7:75:B1:D1 was set by a different Dyson account
|
|
290
|
+
and only that account can change it.
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Clearing the year altogether is not something the plugin does; the MyDyson app's
|
|
294
|
+
own age-adjustment screen has a remove option for that.
|
|
295
|
+
|
|
296
|
+
|
|
163
297
|
## If something goes wrong
|
|
164
298
|
|
|
165
299
|
**The lamp shows as *No Response*.** There is no Bluetooth link at that moment.
|
package/config.schema.json
CHANGED
|
@@ -60,6 +60,36 @@
|
|
|
60
60
|
"default": true,
|
|
61
61
|
"description": "Adds the lamp's Study, Relax and Precision modes as switches. Only one can be on at a time, which the lamp itself enforces."
|
|
62
62
|
},
|
|
63
|
+
"latitude": {
|
|
64
|
+
"title": "Latitude",
|
|
65
|
+
"type": "number",
|
|
66
|
+
"minimum": -90,
|
|
67
|
+
"maximum": 90,
|
|
68
|
+
"placeholder": "48.6719",
|
|
69
|
+
"description": "Decimal degrees. The lamp works out sunrise and sunset from this, which is what daylight tracking follows."
|
|
70
|
+
},
|
|
71
|
+
"longitude": {
|
|
72
|
+
"title": "Longitude",
|
|
73
|
+
"type": "number",
|
|
74
|
+
"minimum": -180,
|
|
75
|
+
"maximum": 180,
|
|
76
|
+
"placeholder": "9.2807",
|
|
77
|
+
"description": "Decimal degrees. Set both or neither \u2014 a lamp is not told half a location."
|
|
78
|
+
},
|
|
79
|
+
"yearOfBirth": {
|
|
80
|
+
"title": "Year of birth",
|
|
81
|
+
"type": "integer",
|
|
82
|
+
"minimum": 1900,
|
|
83
|
+
"placeholder": "1974",
|
|
84
|
+
"description": "Age adjustment: the lamp trims the brightness of its Study and Relax modes to suit the main user\u2019s eyes. The lamp stores the year only, encrypted, and keeps it to the Dyson account that set it. Leave empty to leave the setting alone."
|
|
85
|
+
},
|
|
86
|
+
"ageAdjust": {
|
|
87
|
+
"title": "Apply the age adjustment",
|
|
88
|
+
"type": "boolean",
|
|
89
|
+
"default": true,
|
|
90
|
+
"condition": { "functionBody": "return model.lights && model.lights[arrayIndices[0]] && model.lights[arrayIndices[0]].yearOfBirth;" },
|
|
91
|
+
"description": "The lamp\u2019s own switch for it. Turning this off leaves the year in place but stops the lamp acting on it."
|
|
92
|
+
},
|
|
63
93
|
"daylightSwitch": {
|
|
64
94
|
"title": "Expose daylight tracking",
|
|
65
95
|
"type": "boolean",
|
|
@@ -114,6 +144,10 @@
|
|
|
114
144
|
"lights[].name",
|
|
115
145
|
"lights[].mac",
|
|
116
146
|
"lights[].serial",
|
|
147
|
+
"lights[].latitude",
|
|
148
|
+
"lights[].longitude",
|
|
149
|
+
"lights[].yearOfBirth",
|
|
150
|
+
"lights[].ageAdjust",
|
|
117
151
|
"lights[].daylightSwitch",
|
|
118
152
|
"lights[].autoBrightnessSwitch",
|
|
119
153
|
"lights[].movementSwitch",
|
package/dist/accessory.js
CHANGED
|
@@ -46,6 +46,17 @@ export class MorphAccessory {
|
|
|
46
46
|
ltk: config.ltk,
|
|
47
47
|
accountId: config.accountId,
|
|
48
48
|
adapter: platform.config.adapter,
|
|
49
|
+
// Both or neither: validation refuses half a location, so one of them
|
|
50
|
+
// being present means the other is too.
|
|
51
|
+
location: config.latitude !== undefined && config.longitude !== undefined
|
|
52
|
+
? { latitude: config.latitude, longitude: config.longitude }
|
|
53
|
+
: undefined,
|
|
54
|
+
// The switch only means anything next to a year, so the pair travels
|
|
55
|
+
// together and defaults to on: setting a year and leaving the adjustment
|
|
56
|
+
// off would be asking for nothing to happen.
|
|
57
|
+
ageAdjust: config.yearOfBirth === undefined
|
|
58
|
+
? undefined
|
|
59
|
+
: { yearOfBirth: config.yearOfBirth, enabled: config.ageAdjust !== false },
|
|
49
60
|
log: platform.log,
|
|
50
61
|
});
|
|
51
62
|
this.describe(accessories.light, config.serial);
|
package/dist/accessory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../src/accessory.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../src/accessory.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -32,7 +32,34 @@ export interface LightConfig {
|
|
|
32
32
|
* Expose the lamp's preset modes as switches. On by default.
|
|
33
33
|
*/
|
|
34
34
|
presetSwitches?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Where the lamp is, in decimal degrees. Both or neither.
|
|
37
|
+
*
|
|
38
|
+
* The lamp works out sunrise and sunset from these, which is what daylight
|
|
39
|
+
* tracking follows. The MyDyson app sets them from the phone's GPS when the
|
|
40
|
+
* lamp is first configured, so an existing lamp already has them; these exist
|
|
41
|
+
* to set them without the app, and to correct them after a move.
|
|
42
|
+
*/
|
|
43
|
+
latitude?: number;
|
|
44
|
+
longitude?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Birth year of the main intended user, for the lamp's age adjustment.
|
|
47
|
+
*
|
|
48
|
+
* The lamp trims the brightness of its Study and Relax modes to suit older
|
|
49
|
+
* eyes. It stores the year only — no day, no month — encrypted, and keeps it
|
|
50
|
+
* to the Dyson account that set it. Leave this out and the plugin does not go
|
|
51
|
+
* near the setting.
|
|
52
|
+
*/
|
|
53
|
+
yearOfBirth?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Whether the lamp applies the age adjustment. Only consulted when
|
|
56
|
+
* {@link yearOfBirth} is set, and on by default when it is: a year with the
|
|
57
|
+
* adjustment off does nothing at all.
|
|
58
|
+
*/
|
|
59
|
+
ageAdjust?: boolean;
|
|
35
60
|
}
|
|
61
|
+
/** The oldest year the MyDyson app will offer, and so the oldest accepted here. */
|
|
62
|
+
export declare const EARLIEST_YEAR_OF_BIRTH = 1900;
|
|
36
63
|
/**
|
|
37
64
|
* Whether any switch at all is wanted for this lamp.
|
|
38
65
|
*
|
package/dist/config.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** The oldest year the MyDyson app will offer, and so the oldest accepted here. */
|
|
2
|
+
export const EARLIEST_YEAR_OF_BIRTH = 1900;
|
|
1
3
|
/**
|
|
2
4
|
* Whether any switch at all is wanted for this lamp.
|
|
3
5
|
*
|
|
@@ -40,6 +42,29 @@ export function validateLightConfig(light, index) {
|
|
|
40
42
|
if ((light.ltk === undefined) !== (light.accountId === undefined)) {
|
|
41
43
|
problems.push(`${where} sets only one of ltk/accountId — supply both to override the stored credentials, or neither`);
|
|
42
44
|
}
|
|
45
|
+
// A lamp told only its latitude would place itself on the Greenwich meridian
|
|
46
|
+
// and track the wrong sunset all year, so half a location is refused rather
|
|
47
|
+
// than half-applied.
|
|
48
|
+
if ((light.latitude === undefined) !== (light.longitude === undefined)) {
|
|
49
|
+
problems.push(`${where} sets only one of latitude/longitude — supply both, or neither`);
|
|
50
|
+
}
|
|
51
|
+
if (light.yearOfBirth !== undefined) {
|
|
52
|
+
const thisYear = new Date().getFullYear();
|
|
53
|
+
const year = light.yearOfBirth;
|
|
54
|
+
if (!Number.isInteger(year) || year < EARLIEST_YEAR_OF_BIRTH || year > thisYear) {
|
|
55
|
+
problems.push(`${where}.yearOfBirth must be a whole year between ${EARLIEST_YEAR_OF_BIRTH} and ${thisYear} ` +
|
|
56
|
+
`(got ${JSON.stringify(light.yearOfBirth)})`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (light.ageAdjust !== undefined) {
|
|
60
|
+
problems.push(`${where} sets ageAdjust with no yearOfBirth — there is nothing to adjust for`);
|
|
61
|
+
}
|
|
62
|
+
for (const [field, limit] of [['latitude', 90], ['longitude', 180]]) {
|
|
63
|
+
const value = light[field];
|
|
64
|
+
if (value !== undefined && (typeof value !== 'number' || !Number.isFinite(value) || Math.abs(value) > limit)) {
|
|
65
|
+
problems.push(`${where}.${field} must be a number between -${limit} and ${limit} (got ${JSON.stringify(value)})`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
43
68
|
return problems;
|
|
44
69
|
}
|
|
45
70
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/dyson/crypto.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
/** Derive the 16-byte AES key the re-authentication handshake uses. */
|
|
2
|
+
export declare function deriveAesKey(ltk: Buffer): Buffer;
|
|
3
|
+
/** Derive the 16-byte AES key the lamp's sealed settings use. */
|
|
4
|
+
export declare function deriveSensitiveKey(ltk: Buffer): Buffer;
|
|
1
5
|
/**
|
|
2
|
-
*
|
|
6
|
+
* Undo {@link sealBlock}, checking the MAC before trusting the plaintext.
|
|
3
7
|
*
|
|
4
|
-
*
|
|
8
|
+
* @param sealed `IV(16) || ciphertext || HMAC-SHA256(ciphertext)(32)`.
|
|
9
|
+
* @returns The plaintext, or `undefined` if it is malformed or the MAC does not
|
|
10
|
+
* match — which for a lamp's setting means the key is wrong, not that an
|
|
11
|
+
* attacker is about, and is worth handling rather than throwing over.
|
|
5
12
|
*/
|
|
6
|
-
export declare function
|
|
13
|
+
export declare function unsealBlock(key: Buffer, sealed: Buffer): Buffer | undefined;
|
|
7
14
|
/**
|
|
8
15
|
* Encrypt-then-MAC one or more AES blocks.
|
|
9
16
|
*
|
package/dist/dyson/crypto.js
CHANGED
|
@@ -9,20 +9,58 @@
|
|
|
9
9
|
import { createCipheriv, createDecipheriv, createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
10
10
|
/** HKDF `info` string, matching `g20/b.d` in the MyDyson Android app. */
|
|
11
11
|
const HKDF_INFO = Buffer.from('USER_AUTH_AES\x00\x00\x00', 'binary');
|
|
12
|
+
/**
|
|
13
|
+
* HKDF `info` for the lamp's sealed settings, from `q50/a.java`'s static
|
|
14
|
+
* initialiser.
|
|
15
|
+
*
|
|
16
|
+
* The year of birth is the one thing on this lamp that is stored encrypted, and
|
|
17
|
+
* it is deliberately not readable with the key the handshake uses: same LTK,
|
|
18
|
+
* same derivation, different `info`.
|
|
19
|
+
*/
|
|
20
|
+
const HKDF_INFO_SENSITIVE = Buffer.from('SENSITIVE_STATE\x00', 'binary');
|
|
12
21
|
/** Every encrypted block in this protocol is exactly one AES block. */
|
|
13
22
|
const BLOCK = 16;
|
|
14
23
|
/**
|
|
15
|
-
* Derive the 16-byte AES key from the long-term key.
|
|
16
|
-
*
|
|
17
24
|
* HKDF-SHA256 with an empty salt, truncated to the first expansion block.
|
|
25
|
+
*
|
|
26
|
+
* An empty salt and 32 zero bytes are the same thing to HMAC, which pads a
|
|
27
|
+
* short key with zeros, so this matches `t50/b.java` substituting the latter.
|
|
18
28
|
*/
|
|
19
|
-
|
|
29
|
+
function hkdf(ltk, info) {
|
|
20
30
|
const prk = createHmac('sha256', Buffer.alloc(0)).update(ltk).digest();
|
|
21
31
|
const block1 = createHmac('sha256', prk)
|
|
22
|
-
.update(Buffer.concat([
|
|
32
|
+
.update(Buffer.concat([info, Buffer.from([0x01])]))
|
|
23
33
|
.digest();
|
|
24
34
|
return block1.subarray(0, BLOCK);
|
|
25
35
|
}
|
|
36
|
+
/** Derive the 16-byte AES key the re-authentication handshake uses. */
|
|
37
|
+
export function deriveAesKey(ltk) {
|
|
38
|
+
return hkdf(ltk, HKDF_INFO);
|
|
39
|
+
}
|
|
40
|
+
/** Derive the 16-byte AES key the lamp's sealed settings use. */
|
|
41
|
+
export function deriveSensitiveKey(ltk) {
|
|
42
|
+
return hkdf(ltk, HKDF_INFO_SENSITIVE);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Undo {@link sealBlock}, checking the MAC before trusting the plaintext.
|
|
46
|
+
*
|
|
47
|
+
* @param sealed `IV(16) || ciphertext || HMAC-SHA256(ciphertext)(32)`.
|
|
48
|
+
* @returns The plaintext, or `undefined` if it is malformed or the MAC does not
|
|
49
|
+
* match — which for a lamp's setting means the key is wrong, not that an
|
|
50
|
+
* attacker is about, and is worth handling rather than throwing over.
|
|
51
|
+
*/
|
|
52
|
+
export function unsealBlock(key, sealed) {
|
|
53
|
+
const ciphertextLength = sealed.length - BLOCK - 32;
|
|
54
|
+
if (ciphertextLength <= 0 || ciphertextLength % BLOCK !== 0) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const ciphertext = sealed.subarray(BLOCK, BLOCK + ciphertextLength);
|
|
58
|
+
const mac = createHmac('sha256', key).update(ciphertext).digest();
|
|
59
|
+
if (!timingSafeEqual(mac, sealed.subarray(BLOCK + ciphertextLength))) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return openBlock(key, sealed.subarray(0, BLOCK), ciphertext);
|
|
63
|
+
}
|
|
26
64
|
/**
|
|
27
65
|
* Encrypt-then-MAC one or more AES blocks.
|
|
28
66
|
*
|
package/dist/dyson/crypto.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/dyson/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzG,yEAAyE;AACzE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;AAErE,uEAAuE;AACvE,MAAM,KAAK,GAAG,EAAE,CAAC;AAEjB
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/dyson/crypto.ts"],"names":[],"mappings":"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"}
|
package/dist/dyson/lamp.d.ts
CHANGED
|
@@ -31,6 +31,22 @@ export interface LampState {
|
|
|
31
31
|
*/
|
|
32
32
|
preset: Preset | 'none';
|
|
33
33
|
}
|
|
34
|
+
/** Where the lamp is, in decimal degrees. */
|
|
35
|
+
export interface LampLocation {
|
|
36
|
+
latitude: number;
|
|
37
|
+
longitude: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The lamp's age adjustment: Study and Relax get dimmer or brighter to suit the
|
|
41
|
+
* eyes of someone born in a given year.
|
|
42
|
+
*
|
|
43
|
+
* Two settings on the lamp, and the switch is the one that decides: a year with
|
|
44
|
+
* it off changes nothing.
|
|
45
|
+
*/
|
|
46
|
+
export interface LampAgeAdjust {
|
|
47
|
+
yearOfBirth: number;
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
}
|
|
34
50
|
export interface LampOptions {
|
|
35
51
|
/** BLE MAC, e.g. `AA:BB:CC:DD:EE:FF`. */
|
|
36
52
|
mac: string;
|
|
@@ -40,6 +56,17 @@ export interface LampOptions {
|
|
|
40
56
|
accountId: string;
|
|
41
57
|
/** Optional HCI adapter name, e.g. `hci0`. Defaults to the system default. */
|
|
42
58
|
adapter?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Where the lamp stands. Put into the lamp on connecting when it does not
|
|
61
|
+
* already hold it; left alone entirely when absent, since a lamp set up
|
|
62
|
+
* through the MyDyson app already knows.
|
|
63
|
+
*/
|
|
64
|
+
location?: LampLocation;
|
|
65
|
+
/**
|
|
66
|
+
* Age adjustment for this lamp. Left alone entirely when absent, since only
|
|
67
|
+
* the owner of the lamp can set it and it is nobody else's business.
|
|
68
|
+
*/
|
|
69
|
+
ageAdjust?: LampAgeAdjust;
|
|
43
70
|
log?: Logger;
|
|
44
71
|
}
|
|
45
72
|
export interface Logger {
|
|
@@ -58,6 +85,10 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
58
85
|
private readonly aesKey;
|
|
59
86
|
private readonly accountId;
|
|
60
87
|
private readonly adapterName;
|
|
88
|
+
private readonly location;
|
|
89
|
+
private readonly ageAdjust;
|
|
90
|
+
/** Key for the lamp's one encrypted setting; not the handshake's. */
|
|
91
|
+
private readonly sensitiveKey;
|
|
61
92
|
private readonly log;
|
|
62
93
|
private bluetooth?;
|
|
63
94
|
private adapter?;
|
|
@@ -67,6 +98,18 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
67
98
|
private writeTypes;
|
|
68
99
|
private readonly assembler;
|
|
69
100
|
private readonly waiters;
|
|
101
|
+
/**
|
|
102
|
+
* Reassembles the attribute channel.
|
|
103
|
+
*
|
|
104
|
+
* Most values here fit in one notification, but the sealed year of birth is
|
|
105
|
+
* 64 bytes and arrives in four, so the stream has to be put back together
|
|
106
|
+
* before anything can be read out of it.
|
|
107
|
+
*/
|
|
108
|
+
private readonly attributeAssembler;
|
|
109
|
+
/** Outstanding attribute questions, keyed by attribute id. */
|
|
110
|
+
private readonly attributeWaiters;
|
|
111
|
+
/** Outstanding attribute writes, keyed by attribute id. */
|
|
112
|
+
private readonly ackWaiters;
|
|
70
113
|
/** Serialises all GATT access. */
|
|
71
114
|
private readonly operations;
|
|
72
115
|
private readonly writes;
|
|
@@ -203,6 +246,18 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
203
246
|
* never closer than {@link MIN_WRITE_GAP_MS} behind the previous one.
|
|
204
247
|
*/
|
|
205
248
|
private write;
|
|
249
|
+
/**
|
|
250
|
+
* Write one logical message, its fragments back to back.
|
|
251
|
+
*
|
|
252
|
+
* The pacer exists to keep two commands apart; it has no business between the
|
|
253
|
+
* pieces of one. It never mattered while every message here fitted in a
|
|
254
|
+
* single fragment, and the sealed year of birth is the first that does not.
|
|
255
|
+
* Both the app and this client's own auth channel write fragments
|
|
256
|
+
* consecutively — the name of the app's constant says which gap it means,
|
|
257
|
+
* `DELAY_BETWEEN_WRITING_MESSAGES_MILLS`.
|
|
258
|
+
*/
|
|
259
|
+
private writeMessage;
|
|
260
|
+
private writeValue;
|
|
206
261
|
/**
|
|
207
262
|
* LTK re-authentication: prove we hold the key without contacting the cloud.
|
|
208
263
|
*
|
|
@@ -225,6 +280,60 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
225
280
|
* {@link publishFromLamp} to work it out from the tracking instead.
|
|
226
281
|
*/
|
|
227
282
|
private readDaylight;
|
|
283
|
+
/**
|
|
284
|
+
* Make sure the lamp knows where it is.
|
|
285
|
+
*
|
|
286
|
+
* The lamp turns its coordinates into sunrise and sunset, and daylight
|
|
287
|
+
* tracking follows those, so a lamp with the wrong location tracks the wrong
|
|
288
|
+
* day. They are normally set once by the MyDyson app from the phone's GPS and
|
|
289
|
+
* then never revisited — including after the lamp moves house.
|
|
290
|
+
*
|
|
291
|
+
* Read first, write only on a difference: these are settings rather than
|
|
292
|
+
* controls, and rewriting them every connection would be churn on a channel
|
|
293
|
+
* shared with the mode switches.
|
|
294
|
+
*/
|
|
295
|
+
private syncLocation;
|
|
296
|
+
/**
|
|
297
|
+
* Put the configured age adjustment in the lamp.
|
|
298
|
+
*
|
|
299
|
+
* Two settings, and the order matters: the year first, then the switch, so
|
|
300
|
+
* the adjustment is never turned on around a year the lamp does not have yet.
|
|
301
|
+
*
|
|
302
|
+
* The year is the one thing this lamp stores encrypted, under a key of its
|
|
303
|
+
* own derived from the same long-term key. Reading it back gives a status
|
|
304
|
+
* saying whether it is ours to read at all — the lamp keeps the adjustment to
|
|
305
|
+
* the account that set it, which the app explains as "for privacy reasons,
|
|
306
|
+
* age adjust is only available to this light's owner".
|
|
307
|
+
*/
|
|
308
|
+
private syncAgeAdjust;
|
|
309
|
+
/** Read and unseal the lamp's year of birth. */
|
|
310
|
+
private readYearOfBirth;
|
|
311
|
+
/**
|
|
312
|
+
* Ask the lamp for one attribute and wait for the answer.
|
|
313
|
+
*
|
|
314
|
+
* @returns The value, or `undefined` if the lamp refused the question or did
|
|
315
|
+
* not answer it — neither of which is an error worth raising, only a reason
|
|
316
|
+
* to leave the setting alone.
|
|
317
|
+
*/
|
|
318
|
+
private readAttribute;
|
|
319
|
+
/**
|
|
320
|
+
* Write one attribute and wait for the lamp to say whether it took it.
|
|
321
|
+
*
|
|
322
|
+
* Retried, because this lamp refuses writes for no reason anyone here has
|
|
323
|
+
* been able to pin down. Twelve writes of the sealed year of birth from a
|
|
324
|
+
* standalone probe were all accepted; the same bytes from the plugin were
|
|
325
|
+
* refused once and accepted once. Pacing, write type and the age-adjustment
|
|
326
|
+
* switch were each measured across three or more trials per arm and each made
|
|
327
|
+
* no difference. That is the same shape as this lamp's connects, where four
|
|
328
|
+
* strategies measured alike and repetition was the answer.
|
|
329
|
+
*
|
|
330
|
+
* @returns Whether the lamp acknowledged with a status of zero. A refusal and
|
|
331
|
+
* a silence are both `false`: either way the setting is not what was asked
|
|
332
|
+
* for, and saying otherwise is worse than saying nothing.
|
|
333
|
+
*/
|
|
334
|
+
private writeAttribute;
|
|
335
|
+
/** Ask the lamp for one coordinate, in degrees. */
|
|
336
|
+
private readCoordinate;
|
|
228
337
|
private refreshState;
|
|
229
338
|
/** Read what the lamp currently reports. Values it will not give up are absent. */
|
|
230
339
|
private readState;
|