homebridge-dyson-solarcycle-morph 0.2.1 → 0.3.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 CHANGED
@@ -5,6 +5,53 @@ 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.3.0] — 2026-09-18
9
+
10
+ ### Added
11
+
12
+ - Daylight tracking is a switch. It reports what the lamp is actually doing,
13
+ following the button on the lamp's base and the MyDyson app as well as
14
+ HomeKit, and it can be turned on and off. Setting a colour temperature ends
15
+ the tracking, which is the lamp's own behaviour, and the switch follows that
16
+ too. Turn it off per light with `daylightSwitch`.
17
+
18
+ ### Fixed
19
+
20
+ - A write arriving immediately behind another was discarded, silently. HomeKit
21
+ sets brightness and colour temperature together whenever a scene is applied,
22
+ and the second of the two was being lost: on a CF06, colour temperature
23
+ reached its target in 1 of 8 attempts written back to back, and 8 of 8 when
24
+ spaced 100 ms apart. Control writes are now paced.
25
+ - The lamp is no longer taken out of daylight mode before every brightness and
26
+ colour-temperature write. It never needed to be — values land while the lamp
27
+ is tracking — and the write that was supposed to do it was never a valid
28
+ command in the first place. Brightness changes now leave daylight tracking
29
+ running; colour-temperature changes still end it, which is the lamp's doing.
30
+
31
+ ## [0.2.2] — 2026-09-17
32
+
33
+ ### Added
34
+
35
+ - The log carries signal strength: on the line reported when the lamp connects,
36
+ once a minute as an average with its range, and on the line reported when a
37
+ connection drops. The **range** is what shows interference — a lamp that is
38
+ not moving cannot swing by 20 dB on its own — while the average only says
39
+ whether it is too far away.
40
+ - Connecting on a later attempt is reported, since repeated attempts mean
41
+ collisions where connections are established.
42
+
43
+ ### Fixed
44
+
45
+ - A lamp switched on at the device itself now reaches HomeKit. Subscribing to a
46
+ characteristic fails intermittently, which was caught and ignored, leaving
47
+ that value silent for the rest of the session. Subscriptions are retried, a
48
+ failure that sticks is warned about, and a slow poll backs them up.
49
+
50
+ ### Changed
51
+
52
+ - The README is written for someone setting the plugin up, rather than for
53
+ someone reading the source.
54
+
8
55
  ## [0.2.1] — 2026-09-17
9
56
 
10
57
  ### Changed
package/README.md CHANGED
@@ -1,259 +1,209 @@
1
- # homebridge-dyson-solarcycle-morph
1
+ <h1 align="center">homebridge-dyson-solarcycle-morph</h1>
2
2
 
3
- Homebridge plugin for the **Dyson Solarcycle Morph** and **Lightcycle Morph**
4
- task lights (model CD06).
3
+ <p align="center">
4
+ Control your <b>Dyson Solarcycle Morph</b> from the Apple Home app &mdash; over Bluetooth, with no cloud in the loop.
5
+ </p>
5
6
 
6
- These lamps have no Wi-Fi. Everything goes over Bluetooth LE, so the machine
7
- running Homebridge has to be within Bluetooth range of the lamp — there is no
8
- cloud path to fall back on.
7
+ <p align="center">
8
+ <a href="https://github.com/rummeyer/homebridge-dyson-solarcycle-morph/releases"><img src="https://img.shields.io/github/v/release/rummeyer/homebridge-dyson-solarcycle-morph?label=release" alt="Release"></a>
9
+ <a href="https://github.com/rummeyer/homebridge-dyson-solarcycle-morph/blob/main/LICENSE"><img src="https://img.shields.io/badge/licence-MIT-blue" alt="Licence"></a>
10
+ <img src="https://img.shields.io/badge/homebridge-%E2%89%A5%202.0.0-purple" alt="Homebridge 2.0.0+">
11
+ <img src="https://img.shields.io/badge/node-22%20%7C%2024%20%7C%2026-green" alt="Node 22, 24 or 26">
12
+ </p>
9
13
 
10
- Exposes a HomeKit lightbulb with on/off, brightness and colour temperature
11
- (2700–6500 K), plus the lamp's built-in motion sensor if you want it.
14
+ ---
12
15
 
13
- ## Before you start
16
+ ## What you get
14
17
 
15
- **Your lamp must already be registered in the MyDyson app, on the account you
16
- are going to log in with.** This is not optional and it is worth explaining why,
17
- because it is the one thing that can stop you dead.
18
+ Your lamp appears in the Home app as a **light**, with the controls Apple provides for one:
18
19
 
19
- The lamp ignores every command until a challenge-response handshake proves you
20
- hold its *long-term key* (LTK). That key is issued by Dyson, tied to the account
21
- the lamp is registered to, and there is no way to derive it from the device
22
- itself. Pairing here fetches it once from the Dyson cloud. If the lamp is not on
23
- your account, the endpoint returns 404 and there is nothing this plugin can do.
20
+ - **On and off**
21
+ - **Brightness**
22
+ - **Colour temperature**, across the lamp's full 2700–6500 K range
23
+ - **Motion**, from the lamp's own sensor, as a separate sensor you can automate on
24
+ - **Siri**: *"Hey Siri, turn on the desk light"*, *"Hey Siri, set the desk light to 50%"*
24
25
 
25
- The only other way to get an LTK is Dyson's "fresh pairing" handshake, which
26
- needs a physical button press on the lamp *and* a working cloud session — this
27
- plugin does not implement it. So: open the MyDyson app, make sure the lamp is
28
- there, then continue.
26
+ After setup nothing leaves your home. The lamp has no Wi-Fi at all: the plugin
27
+ talks to it over Bluetooth, and the one cloud request — fetching the lamp's key —
28
+ happens once, during pairing.
29
29
 
30
- Everything after pairing is local. The plugin never touches the network again.
30
+ ## Before you start
31
31
 
32
- ## Requirements
32
+ | | |
33
+ |---|---|
34
+ | **Lamp** | Dyson Solarcycle Morph or Lightcycle Morph, added to your MyDyson account |
35
+ | **Homebridge** | 2.0.0 or newer, on Linux |
36
+ | **Node.js** | 22.18, 24 or 26 |
37
+ | **Range** | The Homebridge host must be within Bluetooth range of the lamp |
33
38
 
34
- - A Linux host with BlueZ — a Raspberry Pi running Homebridge is the usual case.
35
- This uses [`node-ble`](https://github.com/chrvadala/node-ble), which talks to
36
- BlueZ over D-Bus, so **macOS and Windows will not work**.
37
- - Node.js 20.19+ / 22.12+ / 24+.
38
- - Homebridge 2.x.
39
+ **The lamp must already be in the MyDyson app.** This is not a formality. The
40
+ lamp ignores every command until it is handed a key that only Dyson can issue,
41
+ against the account the lamp is registered to — there is no way to read it from
42
+ the device. If the lamp is not on your account, pairing returns a 404 and there
43
+ is nothing the plugin can do about it.
39
44
 
40
- Developed and verified against a Solarcycle Morph desk light on Raspberry Pi OS
41
- Bookworm, BlueZ 5.66, Homebridge 2.4.
45
+ **Linux only.** The plugin talks to BlueZ over D-Bus, so macOS and Windows will
46
+ not work. A Raspberry Pi running Homebridge is the usual home for it.
42
47
 
43
- ## 1. Find the lamp
48
+ ## Step 1 — Install the plugin
44
49
 
45
- ```sh
46
- sudo bluetoothctl --timeout 15 scan le
47
- ```
50
+ In the Homebridge UI, go to **Plugins**, search for
51
+ `homebridge-dyson-solarcycle-morph` and choose **Install**.
48
52
 
49
- Look for a device whose name is a Dyson serial, something like
50
- `ABC-EU-XXXXXXXX`. **The lamp advertises its serial number as its Bluetooth
51
- name**, so this one command gives you both values you need:
53
+ ## Step 2 — Give it a child bridge
52
54
 
53
- ```sh
54
- bluetoothctl info AA:BB:CC:DD:EE:FF
55
- ```
55
+ In the plugin's **⋮** menu, choose **Bridge Settings** and turn the child bridge
56
+ on.
56
57
 
57
- ```
58
- Device AA:BB:CC:DD:EE:FF (random)
59
- Name: ABC-EU-XXXXXXXX ← serial number
60
- UUID: Vendor specific (2dd10010-1c37-452d-8979-d1b4a787d0a4)
61
- ```
58
+ This is worth doing. Bluetooth links drop and reconnect; in a child bridge that
59
+ churn stays in its own process instead of unsettling your other accessories.
62
60
 
63
- That `2dd10010` service UUID confirms it is a Dyson light speaking the protocol
64
- this plugin implements.
61
+ ## Step 3 — Connect your MyDyson account
65
62
 
66
- ## 2. Install
63
+ Open the plugin's **Settings**. The page walks through it:
67
64
 
68
- ```sh
69
- sudo npm install -g homebridge-dyson-solarcycle-morph
70
- ```
65
+ 1. **Enter your MyDyson email, password and country.** The country picks the
66
+ Dyson server and the language its requests use.
67
+ 2. **Request code**, then type the code Dyson emails you and press **Submit**.
68
+ The page then shows *✓ Authorised*, with when and how many devices your
69
+ account holds.
70
+ 3. **Find my lights.** This lists the lights on your account and scans for their
71
+ Bluetooth addresses. Press **Add and pair** next to yours.
72
+ 4. **Forget password** once you are done, then **Save**.
71
73
 
72
- On a Homebridge installation managed by `hb-service` (the official Raspberry Pi
73
- image and apt package), plugins live in the Homebridge storage directory rather
74
- than in npm's global prefix. Install it there instead:
74
+ Restart Homebridge when the page says so.
75
75
 
76
- ```sh
77
- cd /var/lib/homebridge
78
- sudo -u homebridge /opt/homebridge/bin/npm install homebridge-dyson-solarcycle-morph
79
- ```
76
+ ### What is stored, and where
80
77
 
81
- Installing into the wrong prefix is a quiet failure: npm reports success and
82
- Homebridge never sees the plugin.
78
+ The lamp's key and your account session go into the plugin's own storage
79
+ directory, not into `config.json`. The file you can open in the Homebridge UI —
80
+ and paste into a support thread — holds nothing sensitive.
83
81
 
84
- ## 3. Pair, in the Homebridge UI
82
+ Your password is only needed to exchange a code for a session. **Forget
83
+ password** removes it afterwards; the lamp keeps working, because its key does
84
+ not expire.
85
85
 
86
- Open the plugin's settings. The page walks through three things:
86
+ ## Step 4 — Add the lamp to the Home app
87
87
 
88
- 1. **Scan for lights.** Finds nearby Dyson lights and adds them to the
89
- configuration, filling in the address and serial number for you. You can skip
90
- this and type them by hand if you already did step 1.
91
- 2. **Authorise your MyDyson account.** Enter your email, password and country,
92
- request a code, and enter the code Dyson emails you.
93
- 3. **Check the result.** Paired lights are listed with the date they were
94
- authorised, and can be un-paired again.
88
+ The child bridge has its own QR code, under **Bridge Settings**. Scan it in the
89
+ Home app the same way you paired Homebridge itself.
95
90
 
96
- Save the configuration and restart Homebridge.
91
+ ## Everyday use
97
92
 
98
- **The key never enters `config.json`.** It is written to the plugin's own
99
- storage directory, so the file you can open in the UI — and paste into a support
100
- thread — contains nothing sensitive.
93
+ **Brightness will not always land exactly where you put it.** The lamp ramps
94
+ towards a value rather than jumping, and trims it to track daylight from its
95
+ location and the time of day. Asking for 100% and seeing 88% is the lamp working
96
+ as designed.
101
97
 
102
- ### Without the Homebridge UI
98
+ **Changes made at the lamp show up in the Home app**, usually at once and at
99
+ worst within a minute.
103
100
 
104
- `dyson-morph-pair` does the same thing from a terminal:
101
+ **When the lamp is out of reach**, the Home app shows it as *No Response* rather
102
+ than the last value it knew, and commands fail instead of being silently queued.
103
+ The plugin reconnects on its own and reads the lamp's real state when it does.
105
104
 
106
- ```sh
107
- dyson-morph-pair --serial ABC-EU-XXXXXXXX --country DE
108
- ```
105
+ **Switching off is checked.** Control commands are unacknowledged, so one can be
106
+ dropped in transit. Power is read back shortly after and resent if it did not
107
+ take — a lamp still lit after being switched off is the one failure nobody can
108
+ work around. Brightness and colour temperature are deliberately not checked,
109
+ because the lamp adjusts them itself and a correction would fight it.
109
110
 
110
- Pass `--storage` if your Homebridge storage directory is not `~/.homebridge`,
111
- and `--debug` to see every request and response.
112
-
113
- **Run it in a real terminal.** It reads from stdin interactively, so launching
114
- it from an editor, an agent or a CI shell prints the prompts but never receives
115
- your answers — every field arrives empty and Dyson rejects the login with a
116
- misleading `401 Unable to authenticate user`.
117
-
118
- ## 4. Configure
119
-
120
- Scanning writes this for you; by hand it looks like:
121
-
122
- ```json
123
- {
124
- "platform": "DysonSolarcycleMorph",
125
- "lights": [
126
- {
127
- "name": "Desk Light",
128
- "mac": "AA:BB:CC:DD:EE:FF",
129
- "serial": "ABC-EU-XXXXXXXX",
130
- "motionSensor": true
131
- }
132
- ]
133
- }
134
- ```
111
+ ## Settings
135
112
 
136
- | Field | |
137
- |---|---|
138
- | `name` | What the lamp is called in HomeKit. |
139
- | `mac` | BLE address from the scan. |
140
- | `serial` | Identifies the accessory to HomeKit and keys its stored credentials. |
141
- | `motionSensor` | Expose the lamp's motion detector as a HomeKit sensor. Default `false`. |
113
+ Everything except the lights is optional.
142
114
 
143
- Credentials are not configured here. For an unattended setup you may still set
144
- `ltk` and `accountId` explicitly, and they then take precedence over anything
145
- stored — supply both or neither.
115
+ | Setting | |
116
+ |---|---|
117
+ | **Name** | What the plugin is called in the Homebridge log |
118
+ | **Lights → Name** | What the lamp is called in the Home app |
119
+ | **Lights → BLE MAC address** | Filled in by the scan |
120
+ | **Lights → Serial number** | Filled in by the scan. Identifies the accessory, so changing it creates a new one |
121
+ | **Lights → Expose the motion sensor** | Adds the lamp's motion detector as a HomeKit sensor |
122
+ | **Bluetooth adapter** | Only needed if the host has more than one, e.g. `hci1` |
146
123
 
147
- **Running it as a child bridge is recommended.** Bluetooth links drop and
148
- reconnect; in a child bridge that churn stays isolated from your other
149
- accessories. In the Homebridge UI it is one toggle under the plugin's settings.
124
+ ## If something goes wrong
150
125
 
151
- ## Troubleshooting
126
+ **The lamp shows as *No Response*.** There is no Bluetooth link at that moment.
127
+ The plugin keeps reconnecting; if it does not recover, read on.
152
128
 
153
- **`le-connection-abort-by-local` a few times at startup.** Expected. BlueZ
154
- commonly aborts the first two or three attempts before one sticks. The plugin
155
- retries with backoff (2 s, 5 s, 15 s, 30 s, then 60 s) and normally connects
156
- within a minute. Only worry if it never succeeds.
129
+ **The log repeats `le-connection-abort-by-local` and never connects.** The lamp's
130
+ Bluetooth stack can reach a state where it advertises perfectly well — a scan
131
+ finds it, at a good signal strength — but refuses every connection.
132
+ **Disconnecting the lamp from power for ten seconds clears it**, reliably.
133
+ Nothing on the Homebridge side does. The plugin thins its attempts out to five
134
+ minutes apart, so it will pick the lamp up again by itself once you have.
157
135
 
158
- **It connects, drops after a few seconds, and reconnects, over and over.**
159
- Usually the radio link, not the software. The plugin logs the signal strength
160
- when it connects and warns below about −80 dBm; at that level BLE hits its
161
- supervision timeout and the link dies. Check it directly with:
136
+ **It connects, drops, reconnects, over and over.** Look at the signal line in the
137
+ log:
162
138
 
163
- ```sh
164
- sudo bluetoothctl info AA:BB:CC:DD:EE:FF | grep RSSI
139
+ ```
140
+ Signal from F0:… : -73 dBm average, -80 to -67
165
141
  ```
166
142
 
167
- −60 dBm is comfortable, −75 is workable, −85 will not hold. Move the lamp or the
168
- Homebridge host closer to each other, or put a Bluetooth adapter nearer the lamp.
143
+ The **average** answers one question — is the lamp too far away. Around −60 dBm
144
+ is comfortable, −75 workable, −85 will not hold.
169
145
 
170
- **It keeps failing with `le-connection-abort-by-local` and never connects.**
171
- The lamp's Bluetooth stack can reach a state where it advertises normally — a
172
- scan finds it, at a good signal strength — but refuses every connection.
173
- **Disconnecting the lamp from power for ten seconds clears it**, reliably, and
174
- nothing on the Homebridge side does. The plugin keeps retrying and thins the
175
- attempts out to five minutes apart, so it will pick the lamp up again by itself
176
- once you have done that.
146
+ The **spread** answers a different one. A lamp that is not moving cannot swing by
147
+ 20 dB on its own, so a wide spread means something else is using the band. So do
148
+ frequent `Lost connection` lines, and `Connected … on attempt 3 of 4`, which
149
+ means collisions where connections are established.
177
150
 
178
- **Everything reports `Operation Not Authorized`.** The handshake did not
179
- complete. Look for `Handshake with … complete` in the log.
151
+ On a Raspberry Pi, Wi-Fi and Bluetooth share one chip and often one antenna, so
152
+ an active Wi-Fi link is the first thing to rule out — particularly on channel 1,
153
+ which sits directly on a Bluetooth advertising channel. If the host is on
154
+ Ethernet anyway, `sudo nmcli radio wifi off` settles it. Zigbee is worth checking
155
+ next: channels 15, 20 and 25 sit in the gaps between Wi-Fi 1, 6 and 11.
180
156
 
181
157
  **`… is not paired yet`.** No key is stored for that serial. Open the plugin's
182
- settings in the Homebridge UI and authorise your account there. Check the serial
183
- matches the lamp exactly — it is what the stored key is filed under.
158
+ settings and authorise your account. Check the serial matches the lamp exactly —
159
+ it is what the key is filed under.
184
160
 
185
- **`PayloadB failed HMAC verification`.** The stored LTK is wrong or corrupted.
186
- Re-run `dyson-morph-pair`.
161
+ **`PayloadB failed HMAC verification`.** The stored key is wrong or corrupted.
162
+ Pair the lamp again.
187
163
 
188
- **404 when fetching the LTK.** The lamp is not registered to that Dyson account.
164
+ **404 when fetching the key.** The lamp is not registered to that Dyson account.
189
165
  See *Before you start*.
190
166
 
191
- **`Not authorized` from D-Bus, or nothing connects at all.** Only relevant if
192
- your distribution restricts BlueZ access — Debian Bookworm and Raspberry Pi OS
193
- already allow it for all users, so this is usually *not* your problem. If it is,
194
- create `/etc/dbus-1/system.d/node-ble.conf`, replacing `homebridge` with the
195
- user Homebridge runs as, then `sudo systemctl restart dbus`:
196
-
197
- ```xml
198
- <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
199
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
200
- <busconfig>
201
- <policy user="homebridge">
202
- <allow own="org.bluez"/>
203
- <allow send_destination="org.bluez"/>
204
- <allow send_interface="org.bluez.GattCharacteristic1"/>
205
- <allow send_interface="org.bluez.GattDescriptor1"/>
206
- <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
207
- <allow send_interface="org.freedesktop.DBus.Properties"/>
208
- </policy>
209
- </busconfig>
210
- ```
167
+ **`Not authorized` from D-Bus.** Only on distributions that restrict BlueZ
168
+ access — Debian and Raspberry Pi OS already allow it. If yours does not, create
169
+ `/etc/dbus-1/system.d/node-ble.conf` with a policy for the user Homebridge runs
170
+ as, then restart `dbus`. There is an example in
171
+ [the node-ble documentation](https://github.com/chrvadala/node-ble#provide-permissions).
211
172
 
212
- **The Home app shows the lamp as "No Response".** There is no Bluetooth link
213
- right now. Commands are not queued while that is the case: they fail, so you
214
- know they did not happen. The plugin reconnects on its own and reads the lamp's
215
- real state when it does.
173
+ ## Good to know
216
174
 
217
- **The brightness I set is not exactly what the lamp shows.** Expected. The lamp
218
- ramps towards a value rather than jumping, and trims it to track daylight from
219
- its location and the time. Only power is checked and resent, because it is the
220
- only value whose outcome is unambiguous — see
221
- [docs/PROTOCOL.md](docs/PROTOCOL.md).
175
+ **Bluetooth only.** These lamps have no Wi-Fi, so the Homebridge host has to be
176
+ within range. There is no cloud fallback when it is not.
222
177
 
223
- **Daylight mode changed at the lamp is not reflected.** The lamp lets you write
224
- that setting but not read it back, so the plugin cannot know. It re-asserts
225
- manual mode before writes to keep control predictable.
178
+ **A few failed attempts at startup are normal.** Connecting to this lamp
179
+ succeeds roughly two times in three, whatever you do, so the plugin simply tries
180
+ several times in quick succession. Only a cycle that never succeeds is worth
181
+ looking at.
226
182
 
227
- ### Inspecting the lamp yourself
183
+ **Daylight tracking appears as its own switch.** It shows what the lamp is
184
+ actually doing, following the button on the lamp's base and the MyDyson app as
185
+ well as HomeKit. Setting a colour temperature ends the tracking — that is the
186
+ lamp's own behaviour, not the plugin's — so the switch turns itself off when you
187
+ do. Turn it off per light with `daylightSwitch` if you would rather not have it.
228
188
 
229
- `tools/ble-probe.js` dumps every service, characteristic, flag and notification,
230
- with no build step and no plugin install:
189
+ **Setup without the Homebridge UI.** `dyson-morph-pair` does the same pairing
190
+ from a terminal. See [CONTRIBUTING.md](CONTRIBUTING.md).
231
191
 
232
- ```sh
233
- npm install node-ble
234
- node tools/ble-probe.js AA:BB:CC:DD:EE:FF
235
- ```
236
-
237
- Useful for checking a model this plugin has not been tried against.
192
+ ## For developers
238
193
 
239
- ## Protocol
194
+ The protocol, including where a real lamp disagreed with the published notes, is
195
+ written up in [docs/PROTOCOL.md](docs/PROTOCOL.md). Building, testing and
196
+ releasing are in [CONTRIBUTING.md](CONTRIBUTING.md).
240
197
 
241
- See [docs/PROTOCOL.md](docs/PROTOCOL.md) for the GATT layout, the message
242
- framing and the handshake, including where a real lamp disagreed with the
243
- published notes.
198
+ ## Credits
244
199
 
245
- Reverse-engineered from the MyDyson Android app by S-Termi and documented in
200
+ The BLE protocol was reverse-engineered from the MyDyson Android app by
201
+ **S-Termi** and documented in
246
202
  [cmgrayb/hass-dyson](https://github.com/cmgrayb/hass-dyson). This plugin is an
247
- independent TypeScript implementation, cross-checked against that reference with
248
- `npm test`.
249
-
250
- ## Development
251
-
252
- See [CONTRIBUTING.md](CONTRIBUTING.md) for the build, how to try a change on
253
- real hardware, and how releases are published.
203
+ independent TypeScript implementation, cross-checked against that reference.
254
204
 
255
205
  Not affiliated with or endorsed by Dyson.
256
206
 
257
- ## License
207
+ ## Licence
258
208
 
259
209
  MIT — see [LICENSE](LICENSE).
@@ -50,6 +50,12 @@
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
+ "daylightSwitch": {
55
+ "title": "Expose daylight tracking",
56
+ "type": "boolean",
57
+ "default": true,
58
+ "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
59
  }
54
60
  }
55
61
  }
@@ -99,7 +105,8 @@
99
105
  "lights[].name",
100
106
  "lights[].mac",
101
107
  "lights[].serial",
102
- "lights[].motionSensor"
108
+ "lights[].motionSensor",
109
+ "lights[].daylightSwitch"
103
110
  ]
104
111
  }
105
112
  ]
@@ -15,6 +15,7 @@ export declare class MorphAccessory {
15
15
  private readonly config;
16
16
  private readonly lightbulb;
17
17
  private readonly motion?;
18
+ private readonly daylight?;
18
19
  private readonly lamp;
19
20
  constructor(platform: MorphPlatform, accessory: PlatformAccessory, config: ResolvedLightConfig);
20
21
  start(): Promise<void>;
package/dist/accessory.js CHANGED
@@ -15,6 +15,7 @@ export class MorphAccessory {
15
15
  config;
16
16
  lightbulb;
17
17
  motion;
18
+ daylight;
18
19
  lamp;
19
20
  constructor(platform, accessory, config) {
20
21
  this.platform = platform;
@@ -57,7 +58,24 @@ export class MorphAccessory {
57
58
  this.lightbulb.updateCharacteristic(Characteristic.On, state.on);
58
59
  this.lightbulb.updateCharacteristic(Characteristic.Brightness, state.brightness);
59
60
  this.lightbulb.updateCharacteristic(Characteristic.ColorTemperature, kelvinToMired(state.kelvin));
61
+ this.daylight?.updateCharacteristic(Characteristic.On, state.daylight);
60
62
  });
63
+ if (config.daylightSwitch !== false) {
64
+ // A switch rather than a characteristic on the lightbulb: HomeKit renders
65
+ // only the characteristics it knows, so a custom one would be invisible in
66
+ // the Home app and reachable only from third-party clients.
67
+ this.daylight =
68
+ this.accessory.getService(Service.Switch) ??
69
+ this.accessory.addService(Service.Switch, `${config.name} Daylight`, 'daylight');
70
+ this.daylight.setCharacteristic(Characteristic.Name, `${config.name} Daylight`);
71
+ this.daylight
72
+ .getCharacteristic(Characteristic.On)
73
+ .onGet(() => this.live(() => this.lamp.getState().daylight))
74
+ // Reports the mode faithfully but cannot change it; see setDaylight.
75
+ // The rejection is what makes the Home app put the switch back rather
76
+ // than leave it showing a state the lamp is not in.
77
+ .onSet((value) => this.handleSet('daylight mode', () => this.lamp.setDaylight(value)));
78
+ }
61
79
  if (config.motionSensor) {
62
80
  this.motion =
63
81
  this.accessory.getService(Service.MotionSensor) ??
@@ -73,6 +91,9 @@ export class MorphAccessory {
73
91
  this.lightbulb.updateCharacteristic(Characteristic.On, state.on);
74
92
  this.lightbulb.updateCharacteristic(Characteristic.Brightness, state.brightness);
75
93
  this.lightbulb.updateCharacteristic(Characteristic.ColorTemperature, kelvinToMired(state.kelvin));
94
+ // Follows the lamp leaving daylight mode on its own, which it does as soon
95
+ // as colour temperature is set by hand.
96
+ this.daylight?.updateCharacteristic(Characteristic.On, state.daylight);
76
97
  });
77
98
  }
78
99
  async start() {
@@ -108,6 +129,7 @@ export class MorphAccessory {
108
129
  this.lightbulb.updateCharacteristic(characteristic, error);
109
130
  }
110
131
  this.motion?.updateCharacteristic(Characteristic.MotionDetected, error);
132
+ this.daylight?.updateCharacteristic(Characteristic.On, error);
111
133
  }
112
134
  /**
113
135
  * Apply a write, reporting failure to HomeKit rather than swallowing it.
@@ -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
@@ -17,6 +17,12 @@ 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;
20
26
  }
21
27
  /** A lamp whose credentials are known, from the config or the credential store. */
22
28
  export type ResolvedLightConfig = LightConfig & {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA+CA;;;;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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAqDA;;;;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"}