homebridge-dyson-solarcycle-morph 0.2.2 → 0.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 +44 -0
- package/README.md +19 -6
- package/config.schema.json +22 -1
- package/dist/accessory.d.ts +3 -0
- package/dist/accessory.js +54 -0
- package/dist/accessory.js.map +1 -1
- package/dist/config.d.ts +13 -0
- package/dist/config.js.map +1 -1
- package/dist/dyson/lamp.d.ts +66 -6
- package/dist/dyson/lamp.js +152 -29
- package/dist/dyson/lamp.js.map +1 -1
- package/dist/dyson/pace.d.ts +40 -0
- package/dist/dyson/pace.js +53 -0
- package/dist/dyson/pace.js.map +1 -0
- package/dist/dyson/protocol.d.ts +54 -2
- package/dist/dyson/protocol.js +95 -2
- package/dist/dyson/protocol.js.map +1 -1
- package/dist/dyson/reconcile.d.ts +4 -4
- package/dist/dyson/reconcile.js +4 -4
- package/docs/PROTOCOL.md +224 -17
- package/package.json +1 -1
- package/tools/daylight-test.js +585 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,50 @@ 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
|
+
## [0.4.0] — 2026-09-18
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **The lamp's Auto and movement switches reach HomeKit.** Auto brightness, where
|
|
13
|
+
the lamp trims its own output to keep the room level, and movement mode, where
|
|
14
|
+
it lights on movement and goes out once the room is still, are both switches
|
|
15
|
+
now. They show the true state and follow the buttons on the lamp itself. Turn
|
|
16
|
+
either off per light with `autoBrightnessSwitch` and `movementSwitch`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- The README lists the three mode switches in one place, with the settings that
|
|
21
|
+
turn each off and how the Movement switch differs from the motion sensor.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- The notes said the lamp trimmed brightness to track daylight from its location
|
|
26
|
+
and the time of day. Daylight mode moves colour temperature; what moves
|
|
27
|
+
brightness is auto brightness and the ramp towards a newly written value.
|
|
28
|
+
|
|
29
|
+
## [0.3.0] — 2026-09-18
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- Daylight tracking is a switch. It reports what the lamp is actually doing,
|
|
34
|
+
following the button on the lamp's base and the MyDyson app as well as
|
|
35
|
+
HomeKit, and it can be turned on and off. Setting a colour temperature ends
|
|
36
|
+
the tracking, which is the lamp's own behaviour, and the switch follows that
|
|
37
|
+
too. Turn it off per light with `daylightSwitch`.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- A write arriving immediately behind another was discarded, silently. HomeKit
|
|
42
|
+
sets brightness and colour temperature together whenever a scene is applied,
|
|
43
|
+
and the second of the two was being lost: on a CF06, colour temperature
|
|
44
|
+
reached its target in 1 of 8 attempts written back to back, and 8 of 8 when
|
|
45
|
+
spaced 100 ms apart. Control writes are now paced.
|
|
46
|
+
- The lamp is no longer taken out of daylight mode before every brightness and
|
|
47
|
+
colour-temperature write. It never needed to be — values land while the lamp
|
|
48
|
+
is tracking — and the write that was supposed to do it was never a valid
|
|
49
|
+
command in the first place. Brightness changes now leave daylight tracking
|
|
50
|
+
running; colour-temperature changes still end it, which is the lamp's doing.
|
|
51
|
+
|
|
8
52
|
## [0.2.2] — 2026-09-17
|
|
9
53
|
|
|
10
54
|
### Added
|
package/README.md
CHANGED
|
@@ -91,9 +91,9 @@ Home app the same way you paired Homebridge itself.
|
|
|
91
91
|
## Everyday use
|
|
92
92
|
|
|
93
93
|
**Brightness will not always land exactly where you put it.** The lamp ramps
|
|
94
|
-
towards a value rather than jumping, and
|
|
95
|
-
|
|
96
|
-
as designed.
|
|
94
|
+
towards a value rather than jumping to it, and with auto brightness on it keeps
|
|
95
|
+
trimming the level to suit the room. Asking for 100% and seeing 88% is the lamp
|
|
96
|
+
working as designed. The Auto Brightness switch turns the trimming off.
|
|
97
97
|
|
|
98
98
|
**Changes made at the lamp show up in the Home app**, usually at once and at
|
|
99
99
|
worst within a minute.
|
|
@@ -180,9 +180,22 @@ succeeds roughly two times in three, whatever you do, so the plugin simply tries
|
|
|
180
180
|
several times in quick succession. Only a cycle that never succeeds is worth
|
|
181
181
|
looking at.
|
|
182
182
|
|
|
183
|
-
**
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
**The lamp's three modes appear as switches**, alongside the light itself:
|
|
184
|
+
|
|
185
|
+
| switch | what it does | turn it off with |
|
|
186
|
+
| --- | --- | --- |
|
|
187
|
+
| Daylight | shifts colour temperature through the day | `daylightSwitch` |
|
|
188
|
+
| Auto Brightness | trims the level to suit the room | `autoBrightnessSwitch` |
|
|
189
|
+
| Movement | lights on movement, goes out once the room is still | `movementSwitch` |
|
|
190
|
+
|
|
191
|
+
All three show what the lamp is actually doing, and follow the buttons on its
|
|
192
|
+
base and the MyDyson app as well as HomeKit. Daylight has one behaviour worth
|
|
193
|
+
knowing: setting a colour temperature ends the tracking, so its switch turns
|
|
194
|
+
itself off when you do. That is the lamp's own doing, not the plugin's.
|
|
195
|
+
|
|
196
|
+
The lamp also has a motion sensor, which is a different thing from the Movement
|
|
197
|
+
switch: the sensor reports what the lamp sees, the switch decides whether the
|
|
198
|
+
lamp acts on it. It is off by default — `motionSensor` adds it.
|
|
186
199
|
|
|
187
200
|
**Setup without the Homebridge UI.** `dyson-morph-pair` does the same pairing
|
|
188
201
|
from a terminal. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
package/config.schema.json
CHANGED
|
@@ -50,6 +50,24 @@
|
|
|
50
50
|
"type": "boolean",
|
|
51
51
|
"default": false,
|
|
52
52
|
"description": "Adds the lamp's built-in motion detector as a HomeKit motion sensor."
|
|
53
|
+
},
|
|
54
|
+
"autoBrightnessSwitch": {
|
|
55
|
+
"title": "Expose auto brightness",
|
|
56
|
+
"type": "boolean",
|
|
57
|
+
"default": true,
|
|
58
|
+
"description": "Adds a switch for the lamp's \"Auto\" setting, which trims brightness to keep the room at a steady level."
|
|
59
|
+
},
|
|
60
|
+
"movementSwitch": {
|
|
61
|
+
"title": "Expose movement mode",
|
|
62
|
+
"type": "boolean",
|
|
63
|
+
"default": true,
|
|
64
|
+
"description": "Adds a switch for the lamp's movement mode, where it lights on movement and goes out once the room has been still. Not the same as the motion sensor above, which only reports what the lamp sees."
|
|
65
|
+
},
|
|
66
|
+
"daylightSwitch": {
|
|
67
|
+
"title": "Expose daylight tracking",
|
|
68
|
+
"type": "boolean",
|
|
69
|
+
"default": true,
|
|
70
|
+
"description": "Adds a switch for the lamp's daylight tracking, which adjusts colour temperature to the time of day. It reports the true state, following the button on the lamp base and the MyDyson app, and setting a colour temperature by hand ends the tracking as the lamp itself decides."
|
|
53
71
|
}
|
|
54
72
|
}
|
|
55
73
|
}
|
|
@@ -99,7 +117,10 @@
|
|
|
99
117
|
"lights[].name",
|
|
100
118
|
"lights[].mac",
|
|
101
119
|
"lights[].serial",
|
|
102
|
-
"lights[].motionSensor"
|
|
120
|
+
"lights[].motionSensor",
|
|
121
|
+
"lights[].daylightSwitch",
|
|
122
|
+
"lights[].autoBrightnessSwitch",
|
|
123
|
+
"lights[].movementSwitch"
|
|
103
124
|
]
|
|
104
125
|
}
|
|
105
126
|
]
|
package/dist/accessory.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export declare class MorphAccessory {
|
|
|
15
15
|
private readonly config;
|
|
16
16
|
private readonly lightbulb;
|
|
17
17
|
private readonly motion?;
|
|
18
|
+
private readonly daylight?;
|
|
19
|
+
private readonly autoBrightness?;
|
|
20
|
+
private readonly movement?;
|
|
18
21
|
private readonly lamp;
|
|
19
22
|
constructor(platform: MorphPlatform, accessory: PlatformAccessory, config: ResolvedLightConfig);
|
|
20
23
|
start(): Promise<void>;
|
package/dist/accessory.js
CHANGED
|
@@ -15,6 +15,9 @@ export class MorphAccessory {
|
|
|
15
15
|
config;
|
|
16
16
|
lightbulb;
|
|
17
17
|
motion;
|
|
18
|
+
daylight;
|
|
19
|
+
autoBrightness;
|
|
20
|
+
movement;
|
|
18
21
|
lamp;
|
|
19
22
|
constructor(platform, accessory, config) {
|
|
20
23
|
this.platform = platform;
|
|
@@ -57,7 +60,50 @@ export class MorphAccessory {
|
|
|
57
60
|
this.lightbulb.updateCharacteristic(Characteristic.On, state.on);
|
|
58
61
|
this.lightbulb.updateCharacteristic(Characteristic.Brightness, state.brightness);
|
|
59
62
|
this.lightbulb.updateCharacteristic(Characteristic.ColorTemperature, kelvinToMired(state.kelvin));
|
|
63
|
+
this.daylight?.updateCharacteristic(Characteristic.On, state.daylight);
|
|
64
|
+
this.autoBrightness?.updateCharacteristic(Characteristic.On, state.autoBrightness);
|
|
65
|
+
this.movement?.updateCharacteristic(Characteristic.On, state.movement);
|
|
60
66
|
});
|
|
67
|
+
if (config.daylightSwitch !== false) {
|
|
68
|
+
// A switch rather than a characteristic on the lightbulb: HomeKit renders
|
|
69
|
+
// only the characteristics it knows, so a custom one would be invisible in
|
|
70
|
+
// the Home app and reachable only from third-party clients.
|
|
71
|
+
// By subtype, not by type: this accessory carries more than one Switch,
|
|
72
|
+
// and a lookup by type alone would find whichever came first.
|
|
73
|
+
this.daylight =
|
|
74
|
+
this.accessory.getServiceById(Service.Switch, 'daylight') ??
|
|
75
|
+
this.accessory.addService(Service.Switch, `${config.name} Daylight`, 'daylight');
|
|
76
|
+
this.daylight.setCharacteristic(Characteristic.Name, `${config.name} Daylight`);
|
|
77
|
+
this.daylight
|
|
78
|
+
.getCharacteristic(Characteristic.On)
|
|
79
|
+
.onGet(() => this.live(() => this.lamp.getState().daylight))
|
|
80
|
+
// Reports the mode faithfully but cannot change it; see setDaylight.
|
|
81
|
+
// The rejection is what makes the Home app put the switch back rather
|
|
82
|
+
// than leave it showing a state the lamp is not in.
|
|
83
|
+
.onSet((value) => this.handleSet('daylight mode', () => this.lamp.setDaylight(value)));
|
|
84
|
+
}
|
|
85
|
+
if (config.autoBrightnessSwitch !== false) {
|
|
86
|
+
this.autoBrightness =
|
|
87
|
+
this.accessory.getServiceById(Service.Switch, 'auto') ??
|
|
88
|
+
this.accessory.addService(Service.Switch, `${config.name} Auto Brightness`, 'auto');
|
|
89
|
+
this.autoBrightness.setCharacteristic(Characteristic.Name, `${config.name} Auto Brightness`);
|
|
90
|
+
this.autoBrightness
|
|
91
|
+
.getCharacteristic(Characteristic.On)
|
|
92
|
+
.onGet(() => this.live(() => this.lamp.getState().autoBrightness))
|
|
93
|
+
.onSet((value) => this.handleSet('auto brightness', () => this.lamp.setAutoBrightness(value)));
|
|
94
|
+
}
|
|
95
|
+
if (config.movementSwitch !== false) {
|
|
96
|
+
// Not the motion sensor below: that reports what the lamp sees, this
|
|
97
|
+
// decides whether the lamp acts on it.
|
|
98
|
+
this.movement =
|
|
99
|
+
this.accessory.getServiceById(Service.Switch, 'movement') ??
|
|
100
|
+
this.accessory.addService(Service.Switch, `${config.name} Movement`, 'movement');
|
|
101
|
+
this.movement.setCharacteristic(Characteristic.Name, `${config.name} Movement`);
|
|
102
|
+
this.movement
|
|
103
|
+
.getCharacteristic(Characteristic.On)
|
|
104
|
+
.onGet(() => this.live(() => this.lamp.getState().movement))
|
|
105
|
+
.onSet((value) => this.handleSet('movement mode', () => this.lamp.setMovement(value)));
|
|
106
|
+
}
|
|
61
107
|
if (config.motionSensor) {
|
|
62
108
|
this.motion =
|
|
63
109
|
this.accessory.getService(Service.MotionSensor) ??
|
|
@@ -73,6 +119,11 @@ export class MorphAccessory {
|
|
|
73
119
|
this.lightbulb.updateCharacteristic(Characteristic.On, state.on);
|
|
74
120
|
this.lightbulb.updateCharacteristic(Characteristic.Brightness, state.brightness);
|
|
75
121
|
this.lightbulb.updateCharacteristic(Characteristic.ColorTemperature, kelvinToMired(state.kelvin));
|
|
122
|
+
// Follows the lamp leaving daylight mode on its own, which it does as soon
|
|
123
|
+
// as colour temperature is set by hand.
|
|
124
|
+
this.daylight?.updateCharacteristic(Characteristic.On, state.daylight);
|
|
125
|
+
this.autoBrightness?.updateCharacteristic(Characteristic.On, state.autoBrightness);
|
|
126
|
+
this.movement?.updateCharacteristic(Characteristic.On, state.movement);
|
|
76
127
|
});
|
|
77
128
|
}
|
|
78
129
|
async start() {
|
|
@@ -108,6 +159,9 @@ export class MorphAccessory {
|
|
|
108
159
|
this.lightbulb.updateCharacteristic(characteristic, error);
|
|
109
160
|
}
|
|
110
161
|
this.motion?.updateCharacteristic(Characteristic.MotionDetected, error);
|
|
162
|
+
this.daylight?.updateCharacteristic(Characteristic.On, error);
|
|
163
|
+
this.autoBrightness?.updateCharacteristic(Characteristic.On, error);
|
|
164
|
+
this.movement?.updateCharacteristic(Characteristic.On, error);
|
|
111
165
|
}
|
|
112
166
|
/**
|
|
113
167
|
* Apply a write, reporting failure to HomeKit rather than swallowing it.
|
package/dist/accessory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../src/accessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG3F;;;;;;;GAOG;AACH,MAAM,OAAO,cAAc;
|
|
1
|
+
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../src/accessory.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -17,6 +17,19 @@ export interface LightConfig {
|
|
|
17
17
|
accountId?: string;
|
|
18
18
|
/** Expose the built-in motion sensor as a separate HomeKit service. */
|
|
19
19
|
motionSensor?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Expose daylight tracking as a switch. On by default: it is the lamp's
|
|
22
|
+
* defining feature and there is no other way to turn it back on from HomeKit
|
|
23
|
+
* once setting a colour temperature has ended it.
|
|
24
|
+
*/
|
|
25
|
+
daylightSwitch?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Expose the lamp's "Auto" brightness as a switch. On by default: it is a
|
|
28
|
+
* mode the lamp has and HomeKit would otherwise neither see nor reach.
|
|
29
|
+
*/
|
|
30
|
+
autoBrightnessSwitch?: boolean;
|
|
31
|
+
/** Expose movement-triggered lighting as a switch. On by default. */
|
|
32
|
+
movementSwitch?: boolean;
|
|
20
33
|
}
|
|
21
34
|
/** A lamp whose credentials are known, from the config or the credential store. */
|
|
22
35
|
export type ResolvedLightConfig = LightConfig & {
|
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":"AA4DA;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAA2B,EAAE,KAAa;IAC5E,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,UAAU,KAAK,GAAG,CAAC;IAEjC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,mBAAmB,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,sCAAsC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1E,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,8CAA8C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpG,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,qBAAqB,CAAC,CAAC;IAC/C,CAAC;IACD,yEAAyE;IACzE,8EAA8E;IAC9E,4CAA4C;IAC5C,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACjG,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,wCAAwC,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACjF,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,yCAAyC,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,CAAC;QAClE,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,8FAA8F,CAAC,CAAC;IACxH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/dyson/lamp.d.ts
CHANGED
|
@@ -5,6 +5,23 @@ export interface LampState {
|
|
|
5
5
|
brightness: number;
|
|
6
6
|
/** Colour temperature in Kelvin, 2700-6500. */
|
|
7
7
|
kelvin: number;
|
|
8
|
+
/**
|
|
9
|
+
* Whether the lamp is tracking daylight.
|
|
10
|
+
*
|
|
11
|
+
* Asked for on connecting and reported by the lamp on every change. Carried
|
|
12
|
+
* across reconnects rather than reset, so that a lamp which does not answer
|
|
13
|
+
* starts from the last value seen rather than from a guess.
|
|
14
|
+
*/
|
|
15
|
+
daylight: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the lamp is trimming its own brightness to the room — its "Auto".
|
|
18
|
+
*
|
|
19
|
+
* Unlike daylight mode this is a plain characteristic: readable, writable and
|
|
20
|
+
* notified, so it needs none of the asking-and-inferring that one does.
|
|
21
|
+
*/
|
|
22
|
+
autoBrightness: boolean;
|
|
23
|
+
/** Whether the lamp lights on movement and goes out when the room is still. */
|
|
24
|
+
movement: boolean;
|
|
8
25
|
}
|
|
9
26
|
export interface LampOptions {
|
|
10
27
|
/** BLE MAC, e.g. `AA:BB:CC:DD:EE:FF`. */
|
|
@@ -46,6 +63,9 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
46
63
|
/** Serialises all GATT access. */
|
|
47
64
|
private readonly operations;
|
|
48
65
|
private readonly writes;
|
|
66
|
+
private readonly pacer;
|
|
67
|
+
/** Whether the lamp has stated the daylight mode, rather than it being inferred. */
|
|
68
|
+
private daylightReported;
|
|
49
69
|
private readonly reconciles;
|
|
50
70
|
private readonly settling;
|
|
51
71
|
/** Whether the running scan is one we started and must clean up. */
|
|
@@ -67,7 +87,6 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
67
87
|
private rssiMin;
|
|
68
88
|
private rssiMax;
|
|
69
89
|
private rssiReportedAt;
|
|
70
|
-
private manualModeSetAt;
|
|
71
90
|
private state;
|
|
72
91
|
/** What the user last asked for. Reconciliation aims at this, not at guesses. */
|
|
73
92
|
private desired;
|
|
@@ -82,6 +101,28 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
82
101
|
setPower(on: boolean): Promise<void>;
|
|
83
102
|
/** @param percent HomeKit brightness, 0-100 %. */
|
|
84
103
|
setBrightness(percent: number): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Turn daylight tracking on or off.
|
|
106
|
+
*
|
|
107
|
+
* Goes out on the attribute channel, which is the one part of this lamp that
|
|
108
|
+
* acknowledges a write. Not reconciled all the same: the lamp announces the
|
|
109
|
+
* mode itself whenever it changes, from here, from the app, from the button
|
|
110
|
+
* on its base, or because setting a value by hand ended the tracking, so the
|
|
111
|
+
* report is a better answer than anything read back would be.
|
|
112
|
+
*/
|
|
113
|
+
/** Turn the lamp's own brightness trimming on or off. */
|
|
114
|
+
setAutoBrightness(on: boolean): Promise<void>;
|
|
115
|
+
/** Turn movement-triggered lighting on or off. */
|
|
116
|
+
setMovement(on: boolean): Promise<void>;
|
|
117
|
+
/**
|
|
118
|
+
* Write one of the lamp's one-byte mode flags.
|
|
119
|
+
*
|
|
120
|
+
* Set optimistically like every other command here, but unusually well
|
|
121
|
+
* covered afterwards: these characteristics notify, so the lamp corrects us
|
|
122
|
+
* within a moment if the write did not land.
|
|
123
|
+
*/
|
|
124
|
+
private setFlag;
|
|
125
|
+
setDaylight(on: boolean): Promise<void>;
|
|
85
126
|
setColorTemperature(kelvin: number): Promise<void>;
|
|
86
127
|
private writeUint16;
|
|
87
128
|
/**
|
|
@@ -143,7 +184,10 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
143
184
|
* match on characteristic UUID, which is unique regardless of its parent.
|
|
144
185
|
*/
|
|
145
186
|
private discoverCharacteristics;
|
|
146
|
-
/**
|
|
187
|
+
/**
|
|
188
|
+
* Write using whichever acknowledgement mode the characteristic supports,
|
|
189
|
+
* never closer than {@link MIN_WRITE_GAP_MS} behind the previous one.
|
|
190
|
+
*/
|
|
147
191
|
private write;
|
|
148
192
|
/**
|
|
149
193
|
* LTK re-authentication: prove we hold the key without contacting the cloud.
|
|
@@ -157,12 +201,16 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
157
201
|
private sendMessage;
|
|
158
202
|
private waitForMessage;
|
|
159
203
|
/**
|
|
160
|
-
*
|
|
204
|
+
* Ask the lamp whether it is tracking daylight.
|
|
205
|
+
*
|
|
206
|
+
* The characteristic has no `read` flag, but the attribute channel carries a
|
|
207
|
+
* request of its own, so the mode does not have to be guessed at. The answer
|
|
208
|
+
* arrives as a notification and is handled with the change reports.
|
|
161
209
|
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
210
|
+
* Best-effort: a lamp that does not answer leaves the inference in
|
|
211
|
+
* {@link publishFromLamp} to work it out from the tracking instead.
|
|
164
212
|
*/
|
|
165
|
-
private
|
|
213
|
+
private readDaylight;
|
|
166
214
|
private refreshState;
|
|
167
215
|
/** Read what the lamp currently reports. Values it will not give up are absent. */
|
|
168
216
|
private readState;
|
|
@@ -221,6 +269,18 @@ export declare class DysonMorphLamp extends EventEmitter {
|
|
|
221
269
|
* A value the user just set must stay where they put it; the steps the lamp
|
|
222
270
|
* takes on its way there are not news, they are the command happening.
|
|
223
271
|
*/
|
|
272
|
+
/**
|
|
273
|
+
* Take what the lamp reports, and read daylight mode out of it where it can.
|
|
274
|
+
*
|
|
275
|
+
* A fallback for a lamp that does not answer the question asked on connecting,
|
|
276
|
+
* which would otherwise leave the mode unknown until something changed it.
|
|
277
|
+
* Colour temperature moving when nobody asked for it is the tell: with
|
|
278
|
+
* daylight mode off, nothing but a write moves it.
|
|
279
|
+
*
|
|
280
|
+
* Only ever concludes the mode is on. Stillness proves nothing — the lamp
|
|
281
|
+
* drifts a few Kelvin a minute and less than that on a plateau — and a report
|
|
282
|
+
* from the lamp always wins over an inference once one arrives.
|
|
283
|
+
*/
|
|
224
284
|
private publishFromLamp;
|
|
225
285
|
private patchState;
|
|
226
286
|
}
|