homebridge-eliot-smart-control 0.5.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 +125 -0
- package/LICENSE +21 -0
- package/README.md +172 -0
- package/config.schema.json +100 -0
- package/dist/accessory.d.ts +26 -0
- package/dist/accessory.js +282 -0
- package/dist/accessory.js.map +1 -0
- package/dist/config.d.ts +54 -0
- package/dist/config.js +24 -0
- package/dist/config.js.map +1 -0
- package/dist/eliot/desk.d.ts +177 -0
- package/dist/eliot/desk.js +562 -0
- package/dist/eliot/desk.js.map +1 -0
- package/dist/eliot/discover.d.ts +32 -0
- package/dist/eliot/discover.js +97 -0
- package/dist/eliot/discover.js.map +1 -0
- package/dist/eliot/link.d.ts +51 -0
- package/dist/eliot/link.js +244 -0
- package/dist/eliot/link.js.map +1 -0
- package/dist/eliot/move.d.ts +104 -0
- package/dist/eliot/move.js +122 -0
- package/dist/eliot/move.js.map +1 -0
- package/dist/eliot/protocol.d.ts +157 -0
- package/dist/eliot/protocol.js +212 -0
- package/dist/eliot/protocol.js.map +1 -0
- package/dist/eliot/queue.d.ts +24 -0
- package/dist/eliot/queue.js +51 -0
- package/dist/eliot/queue.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +19 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +12 -0
- package/dist/platform.js +73 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +4 -0
- package/dist/settings.js +5 -0
- package/dist/settings.js.map +1 -0
- package/docs/PROTOCOL.md +330 -0
- package/homebridge-ui/public/index.html +168 -0
- package/homebridge-ui/server.js +41 -0
- package/package.json +63 -0
- package/tools/conflict-test.js +67 -0
- package/tools/desk-test.js +75 -0
- package/tools/eco-test.js +68 -0
- package/tools/eliot-probe.js +442 -0
- package/tools/find-desks.js +30 -0
- package/tools/goto-stop-test.js +127 -0
- package/tools/interrupt-test.js +120 -0
- package/tools/link-smoke.js +98 -0
- package/tools/lock-speed-test.js +117 -0
- package/tools/memory-test.js +84 -0
- package/tools/move-test.js +148 -0
- package/tools/velocity-test.js +65 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
+
adheres to [semantic versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.5.0] — 2026-09-18
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **The desk's child lock as a switch.** It shows the real state: unlike every
|
|
14
|
+
other setting the app can change, this one the control box reads back.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **The desk is now given a height and left to drive there itself.** Its
|
|
19
|
+
control box has a *go to height* command and a *stop* command; neither
|
|
20
|
+
appears in the published write-ups of this protocol, and both were found in
|
|
21
|
+
the Eliot Android app and verified on hardware. Moves land exactly on target
|
|
22
|
+
instead of within about 1%, on the control box's own ramp, and stopping part
|
|
23
|
+
way coasts 13 mm rather than 18.
|
|
24
|
+
- Step commands remain as a fallback for a control box that does not know
|
|
25
|
+
*go to height*: if the desk has not moved shortly after being told where to
|
|
26
|
+
go, the old loop takes over. Untested against such a box, since none was to
|
|
27
|
+
hand.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- `docs/PROTOCOL.md` records the twelve commands the published write-ups are
|
|
32
|
+
missing, and what the app's *Automatischer Reset* actually does — it is not
|
|
33
|
+
a command at all, but a drive to the physical bottom so the control box can
|
|
34
|
+
find its zero. It also records the two commands that do nothing on this
|
|
35
|
+
control box, measured rather than assumed, which is why no switches were
|
|
36
|
+
built for them.
|
|
37
|
+
|
|
38
|
+
## [0.3.1] — 2026-09-18
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- **Memory switches did nothing after a restart.** Homebridge restores an
|
|
43
|
+
accessory's services from its cache but not their handlers, and the switches
|
|
44
|
+
were adopted without being wired up again — present in the Home app,
|
|
45
|
+
unresponsive, and silent about it. They worked only in the session that
|
|
46
|
+
created them.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- The accessory accepts an injected transport, so its behaviour can be tested
|
|
51
|
+
without a desk in the room. The fix above was untestable before.
|
|
52
|
+
|
|
53
|
+
## [0.3.0] — 2026-09-18
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- **Find your desk** in the plugin's settings page. The dongle advertises as
|
|
58
|
+
`Schreibtisch` with no manufacturer name, a random-static address and often
|
|
59
|
+
nothing printed on the sticker, so a scan list gives nothing to go on.
|
|
60
|
+
Candidates are confirmed by the serial service rather than by name, and the
|
|
61
|
+
page reports the two states that otherwise look like failure: a dongle
|
|
62
|
+
already connected to something else, and a signal weak enough to predict
|
|
63
|
+
dropouts.
|
|
64
|
+
- `tools/find-desks.js`, the same discovery from the command line.
|
|
65
|
+
|
|
66
|
+
## [0.2.1] — 2026-09-18
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- **A memory move can be stopped after all.** The previous release documented
|
|
71
|
+
the opposite. There is no stop command, but any step command cancels a move
|
|
72
|
+
the control box is driving — verified on hardware. `HoldPosition` works
|
|
73
|
+
during a preset, and a second move now cancels the first rather than racing
|
|
74
|
+
it.
|
|
75
|
+
|
|
76
|
+
## [0.2.0] — 2026-09-18
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- **The desk's memory positions as momentary switches.** The control box drives
|
|
81
|
+
to them itself on its own ramp, easing into the target within about 2 mm,
|
|
82
|
+
which is better than this plugin manages with step commands. Only memories
|
|
83
|
+
the desk actually has appear.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- Services set `ConfiguredName` as well as `Name`; without it the Home app
|
|
88
|
+
shows every switch under the accessory's own name.
|
|
89
|
+
|
|
90
|
+
## [0.1.1] — 2026-09-18
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
|
|
94
|
+
- **Measurement noise read as somebody using the handset.** The control box's
|
|
95
|
+
reported height wanders a few millimetres between reports, and the threshold
|
|
96
|
+
sat inside that noise, so the target was reset constantly. Movement is now
|
|
97
|
+
judged against the height the desk was last settled at, which also catches a
|
|
98
|
+
slow handset move that consecutive readings would miss entirely.
|
|
99
|
+
|
|
100
|
+
## [0.1.0] — 2026-09-18
|
|
101
|
+
|
|
102
|
+
First release.
|
|
103
|
+
|
|
104
|
+
### Added
|
|
105
|
+
|
|
106
|
+
- Control an Eliot sit-stand desk from the Home app over Bluetooth, as a window
|
|
107
|
+
covering. 0% is the lowest height the desk is configured to allow, 100% the
|
|
108
|
+
highest, both read from the desk rather than configured here.
|
|
109
|
+
- Position, direction of travel and a stop control; the Home app follows the
|
|
110
|
+
handset as well as the other way round.
|
|
111
|
+
- An unreachable desk reports a communication failure rather than the height it
|
|
112
|
+
had an hour ago.
|
|
113
|
+
- `docs/PROTOCOL.md`: the protocol, reverse-engineered for this desk and
|
|
114
|
+
verified against hardware, including the measured travel speed and stopping
|
|
115
|
+
distance.
|
|
116
|
+
|
|
117
|
+
[Unreleased]: https://github.com/rummeyer/homebridge-eliot-smart-control/compare/v0.5.0...HEAD
|
|
118
|
+
[0.5.0]: https://github.com/rummeyer/homebridge-eliot-smart-control/compare/v0.4.0...v0.5.0
|
|
119
|
+
[0.4.0]: https://github.com/rummeyer/homebridge-eliot-smart-control/compare/v0.3.1...v0.4.0
|
|
120
|
+
[0.3.1]: https://github.com/rummeyer/homebridge-eliot-smart-control/compare/v0.3.0...v0.3.1
|
|
121
|
+
[0.3.0]: https://github.com/rummeyer/homebridge-eliot-smart-control/compare/v0.2.1...v0.3.0
|
|
122
|
+
[0.2.1]: https://github.com/rummeyer/homebridge-eliot-smart-control/compare/v0.2.0...v0.2.1
|
|
123
|
+
[0.2.0]: https://github.com/rummeyer/homebridge-eliot-smart-control/compare/v0.1.1...v0.2.0
|
|
124
|
+
[0.1.1]: https://github.com/rummeyer/homebridge-eliot-smart-control/compare/v0.1.0...v0.1.1
|
|
125
|
+
[0.1.0]: https://github.com/rummeyer/homebridge-eliot-smart-control/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Oliver Rummeyer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
<h1 align="center">homebridge-eliot-smart-control</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
Your <b>Eliot sit-stand desk</b> in the Apple Home app — over Bluetooth, with no account and no cloud.
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/homebridge-eliot-smart-control"><img src="https://img.shields.io/npm/v/homebridge-eliot-smart-control?label=npm" alt="npm"></a>
|
|
9
|
+
<a href="https://github.com/rummeyer/homebridge-eliot-smart-control/actions/workflows/build.yml"><img src="https://github.com/rummeyer/homebridge-eliot-smart-control/actions/workflows/build.yml/badge.svg" alt="CI"></a>
|
|
10
|
+
<a href="https://github.com/rummeyer/homebridge-eliot-smart-control/blob/main/LICENSE"><img src="https://img.shields.io/badge/licence-MIT-blue" alt="Licence"></a>
|
|
11
|
+
<img src="https://img.shields.io/badge/homebridge-%E2%89%A5%202.0.0-purple" alt="Homebridge 2.0.0+">
|
|
12
|
+
<img src="https://img.shields.io/badge/node-22%20%7C%2024%20%7C%2026-green" alt="Node 22, 24 or 26">
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## What it looks like in the Home app
|
|
18
|
+
|
|
19
|
+
**The desk itself**, as a slider from 0 to 100%.
|
|
20
|
+
|
|
21
|
+
0% is the lowest height your desk is set to allow and 100% the highest. Those
|
|
22
|
+
come from the desk, not from this plugin, so if you change the limits on the
|
|
23
|
+
handset the ends of the slider follow.
|
|
24
|
+
|
|
25
|
+
*"Hey Siri, set the desk to 100%."* Or put it in an automation: up for the
|
|
26
|
+
morning meeting, down at the end of the day.
|
|
27
|
+
|
|
28
|
+
**Your memory positions**, as buttons — the same ones as on the handset.
|
|
29
|
+
Press one and the desk goes there; the button springs back, the way a scene
|
|
30
|
+
does. Only positions you have actually stored appear.
|
|
31
|
+
|
|
32
|
+
**The child lock**, as a switch. It shows the desk's real state, so if someone
|
|
33
|
+
locks it at the handset the Home app knows.
|
|
34
|
+
|
|
35
|
+
Everything follows the desk, not just the other way round. Use the handset and
|
|
36
|
+
the Home app keeps up. A desk out of range says *No Response* rather than
|
|
37
|
+
showing you the height it had an hour ago.
|
|
38
|
+
|
|
39
|
+
## What you need
|
|
40
|
+
|
|
41
|
+
| | |
|
|
42
|
+
|---|---|
|
|
43
|
+
| **Desk** | An Eliot with the Smart Dongle, or the Procontroller |
|
|
44
|
+
| **Homebridge** | 2.0.0 or newer, **on Linux** |
|
|
45
|
+
| **Node.js** | 22.18, 24 or 26 |
|
|
46
|
+
| **Range** | Homebridge has to stay within Bluetooth range of the desk |
|
|
47
|
+
|
|
48
|
+
**Linux only.** The plugin talks to BlueZ over D-Bus, and macOS and Windows
|
|
49
|
+
have no equivalent. A Raspberry Pi running Homebridge is the usual home for it.
|
|
50
|
+
In a container, mount the host's `/var/run/dbus/system_bus_socket`.
|
|
51
|
+
|
|
52
|
+
**One connection at a time.** The dongle accepts a single Bluetooth connection.
|
|
53
|
+
While Homebridge has it, the Eliot app on your phone cannot connect — and while
|
|
54
|
+
the app has it, this plugin cannot.
|
|
55
|
+
|
|
56
|
+
## Setting it up
|
|
57
|
+
|
|
58
|
+
**1. Install it.** In the Homebridge UI, go to **Plugins**, search for
|
|
59
|
+
`homebridge-eliot-smart-control` and choose **Install**.
|
|
60
|
+
|
|
61
|
+
**2. Give it a child bridge.** In the plugin's **⋮** menu, choose **Bridge
|
|
62
|
+
Settings** and turn the child bridge on. Bluetooth links drop and reconnect;
|
|
63
|
+
in a child bridge that churn stays in its own process instead of unsettling
|
|
64
|
+
your other accessories.
|
|
65
|
+
|
|
66
|
+
**3. Find your desk.** Open the plugin's **Settings** and press **Scan for
|
|
67
|
+
desks**.
|
|
68
|
+
|
|
69
|
+
This is the part worth having help with. The dongle does not announce itself:
|
|
70
|
+
it appears as **`Schreibtisch`**, with no manufacturer name, and many units
|
|
71
|
+
have nothing printed on them — in a scan list it sits among forty anonymous
|
|
72
|
+
phones with nothing to tell them apart. The page looks for the Bluetooth
|
|
73
|
+
service the desk actually speaks, so a result marked *confirmed* is the right
|
|
74
|
+
device and not a good guess.
|
|
75
|
+
|
|
76
|
+
Press **Use this** next to yours, name it, and save.
|
|
77
|
+
|
|
78
|
+
*Nothing found?* Something else probably has it. Close the Eliot app and turn
|
|
79
|
+
Bluetooth off on any phone that has been paired with the desk, then unplug the
|
|
80
|
+
dongle for five seconds.
|
|
81
|
+
|
|
82
|
+
**4. Add it to the Home app.** The child bridge has its own QR code under
|
|
83
|
+
**Bridge Settings**. Scan it the same way you paired Homebridge itself.
|
|
84
|
+
|
|
85
|
+
## Settings
|
|
86
|
+
|
|
87
|
+
| | | |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| **Name** | required | What the desk is called in the Home app |
|
|
90
|
+
| **Dongle address** | required | Filled in for you by the scan |
|
|
91
|
+
| **Idle refresh** | 30 s | How often to ask a standing desk for its height. It reports by itself while moving, so this only catches the handset being used. 0 turns it off |
|
|
92
|
+
| **Memory switches** | on | Offer your stored positions as buttons |
|
|
93
|
+
| **Memory names** | — | What to call them. Defaults to *Memory 1*…*Memory 4* |
|
|
94
|
+
| **Child lock switch** | on | Offer the desk's child lock |
|
|
95
|
+
|
|
96
|
+
Or by hand, in `config.json`:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"platform": "EliotSmartControl",
|
|
101
|
+
"desks": [
|
|
102
|
+
{
|
|
103
|
+
"name": "Schreibtisch",
|
|
104
|
+
"mac": "E5:11:22:33:44:55",
|
|
105
|
+
"memoryNames": ["Sitzen", "Stehen", "Besprechung"]
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Things worth knowing
|
|
112
|
+
|
|
113
|
+
**Positions land exactly.** The desk is handed a height and drives there on its
|
|
114
|
+
own ramp, easing in and stopping within a couple of millimetres — the same
|
|
115
|
+
mechanism as the memory buttons on the handset.
|
|
116
|
+
|
|
117
|
+
**Stopping works, and coasts about 13 mm.** There is no instant brake on a desk.
|
|
118
|
+
|
|
119
|
+
**Using the handset during a move is safe.** The control box gives the handset
|
|
120
|
+
priority and stops; it never drives against you. A brief press pauses the move
|
|
121
|
+
and it carries on, holding the button ends it, and the Home app settles on
|
|
122
|
+
wherever the desk actually is rather than trying again.
|
|
123
|
+
|
|
124
|
+
**An unset memory gets no button.** If you store a new position on the handset,
|
|
125
|
+
its button appears the next time the plugin connects.
|
|
126
|
+
|
|
127
|
+
**The desk's own safety features are untouched.** Anti-collision and the soft
|
|
128
|
+
limits live in the control box. The plugin adds limits of its own on top: it
|
|
129
|
+
gives up if the desk stops making progress, if a move takes longer than the
|
|
130
|
+
distance can account for, or if the desk stops saying where it is.
|
|
131
|
+
|
|
132
|
+
## When something is wrong
|
|
133
|
+
|
|
134
|
+
**The scan finds nothing.** Close the Eliot app and turn Bluetooth off on any
|
|
135
|
+
phone that has been paired with the desk — closing the app does not always
|
|
136
|
+
release the connection, and the dongle will not advertise while something holds
|
|
137
|
+
it. Then unplug it for five seconds; it advertises immediately on power-up.
|
|
138
|
+
|
|
139
|
+
**It connects, then drops.** Check the signal. The settings page shows it beside
|
|
140
|
+
each result and warns when it is weak; anything near -90 dBm comes and goes.
|
|
141
|
+
Move Homebridge closer, or put a second one near the desk.
|
|
142
|
+
|
|
143
|
+
**A dongle that stays silent while plugged in and powered is broken.** Obvious
|
|
144
|
+
written down, indistinguishable from a range problem in practice, and worth
|
|
145
|
+
ruling out early by trying another one. It cost a day here.
|
|
146
|
+
|
|
147
|
+
**"No D-Bus system bus"** means BlueZ is not reachable: you are not on Linux, or
|
|
148
|
+
you are in a container without `/var/run/dbus/system_bus_socket` mounted.
|
|
149
|
+
|
|
150
|
+
**Everything looks right but nothing moves.** Check the dongle is in the port
|
|
151
|
+
marked **F** on the control box, not **HS** — that one is for the handset.
|
|
152
|
+
|
|
153
|
+
## How it works
|
|
154
|
+
|
|
155
|
+
The Smart Dongle is a Lierda `LSD4BT-E95ALSP001` presenting a transparent
|
|
156
|
+
Bluetooth-to-serial bridge; behind it the control box speaks the Jiecang
|
|
157
|
+
handset protocol. None of that was written down anywhere for this desk, so
|
|
158
|
+
[`docs/PROTOCOL.md`](docs/PROTOCOL.md) writes it down now: the framing, the
|
|
159
|
+
command set, the measured travel speed and stopping distance, what the app's
|
|
160
|
+
*Automatischer Reset* really does, and which parts are verified against
|
|
161
|
+
hardware rather than assumed. Including the commands that turned out to do
|
|
162
|
+
nothing, which is worth knowing too.
|
|
163
|
+
|
|
164
|
+
Credit where it is due: the serial protocol was reverse-engineered for other
|
|
165
|
+
desks by [phord/Jarvis](https://github.com/phord/Jarvis) and
|
|
166
|
+
[Rocka84/jiecang_desk_controller](https://github.com/Rocka84/jiecang_desk_controller).
|
|
167
|
+
Working out that an Eliot speaks it, what the Bluetooth side looks like, and
|
|
168
|
+
the several commands those write-ups are missing is what this project added.
|
|
169
|
+
|
|
170
|
+
## Licence
|
|
171
|
+
|
|
172
|
+
MIT
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pluginAlias": "EliotSmartControl",
|
|
3
|
+
"pluginType": "platform",
|
|
4
|
+
"singular": true,
|
|
5
|
+
"headerDisplay": "Control an Eliot sit-stand desk with the Smart Dongle from the Home app, over Bluetooth. Requires Linux — the plugin talks to BlueZ.",
|
|
6
|
+
"footerDisplay": "The dongle advertises as **Schreibtisch** and has no vendor name, so it can be hard to spot. Run `node tools/eliot-probe.js scan` on the Homebridge host to find its address.\n\nThe desk appears as a window covering: 0% is the lowest height it is set to allow, 100% the highest. Those come from the desk's own limits, so changing them on the handset changes what 0% and 100% mean.",
|
|
7
|
+
"schema": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"name": {
|
|
11
|
+
"title": "Name",
|
|
12
|
+
"type": "string",
|
|
13
|
+
"default": "Eliot Smart Control",
|
|
14
|
+
"description": "Only the log prefix. Each desk is named separately below."
|
|
15
|
+
},
|
|
16
|
+
"desks": {
|
|
17
|
+
"title": "Desks",
|
|
18
|
+
"type": "array",
|
|
19
|
+
"items": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"properties": {
|
|
22
|
+
"name": {
|
|
23
|
+
"title": "Name",
|
|
24
|
+
"type": "string",
|
|
25
|
+
"required": true,
|
|
26
|
+
"default": "Schreibtisch",
|
|
27
|
+
"placeholder": "Schreibtisch",
|
|
28
|
+
"description": "What the desk is called in the Home app."
|
|
29
|
+
},
|
|
30
|
+
"mac": {
|
|
31
|
+
"title": "Dongle address",
|
|
32
|
+
"type": "string",
|
|
33
|
+
"required": true,
|
|
34
|
+
"placeholder": "E5:11:22:33:44:55",
|
|
35
|
+
"pattern": "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$",
|
|
36
|
+
"description": "Bluetooth address of the Smart Dongle."
|
|
37
|
+
},
|
|
38
|
+
"idlePollSeconds": {
|
|
39
|
+
"title": "Idle refresh (seconds)",
|
|
40
|
+
"type": "integer",
|
|
41
|
+
"default": 30,
|
|
42
|
+
"minimum": 0,
|
|
43
|
+
"description": "How often to ask a standing desk for its height. The desk reports by itself while moving, so this only catches the handset being used. 0 turns it off."
|
|
44
|
+
},
|
|
45
|
+
"memorySwitches": {
|
|
46
|
+
"title": "Memory-Schalter",
|
|
47
|
+
"type": "boolean",
|
|
48
|
+
"default": true,
|
|
49
|
+
"description": "Die Speicherplätze des Tisches als Schalter anbieten. Sie springen nach dem Drücken zurück, wie eine Szene. Nur belegte Plätze erscheinen."
|
|
50
|
+
},
|
|
51
|
+
"memoryNames": {
|
|
52
|
+
"title": "Namen der Memory-Schalter",
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"title": "Name"
|
|
57
|
+
},
|
|
58
|
+
"description": "Optionale Namen für Memory 1 bis 4, in dieser Reihenfolge. Leer lassen für \"Memory 1\", \"Memory 2\" und so weiter."
|
|
59
|
+
},
|
|
60
|
+
"childLockSwitch": {
|
|
61
|
+
"title": "Kindersicherung als Schalter",
|
|
62
|
+
"type": "boolean",
|
|
63
|
+
"default": true,
|
|
64
|
+
"description": "Die Kindersicherung des Tisches in der Home-App anbieten. Sie ist die einzige Einstellung, die die Controlbox zurückmeldet, also die einzige, die ehrlich angezeigt werden kann."
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"layout": [
|
|
72
|
+
{
|
|
73
|
+
"key": "name"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"key": "desks",
|
|
77
|
+
"type": "array",
|
|
78
|
+
"orderable": false,
|
|
79
|
+
"buttonText": "Add desk",
|
|
80
|
+
"items": [
|
|
81
|
+
"desks[].name",
|
|
82
|
+
"desks[].mac",
|
|
83
|
+
"desks[].idlePollSeconds",
|
|
84
|
+
"desks[].childLockSwitch",
|
|
85
|
+
"desks[].memorySwitches",
|
|
86
|
+
{
|
|
87
|
+
"key": "desks[].memoryNames",
|
|
88
|
+
"type": "array",
|
|
89
|
+
"orderable": false,
|
|
90
|
+
"buttonText": "Namen hinzufügen",
|
|
91
|
+
"items": [
|
|
92
|
+
"desks[].memoryNames[]"
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"customUi": true,
|
|
99
|
+
"customUiPath": "./homebridge-ui"
|
|
100
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One desk as a HomeKit window covering.
|
|
3
|
+
*
|
|
4
|
+
* A covering rather than a light, because a desk is a positional actuator that
|
|
5
|
+
* takes time to get there: `PositionState` says which way it is going and
|
|
6
|
+
* `HoldPosition` stops it, neither of which a dimmer can express. It also
|
|
7
|
+
* keeps the desk out of "turn off all the lights", which would otherwise drive
|
|
8
|
+
* it to its lowest setting at bedtime.
|
|
9
|
+
*/
|
|
10
|
+
import type { PlatformAccessory } from 'homebridge';
|
|
11
|
+
import type { DeskConfig } from './config.ts';
|
|
12
|
+
import type { Transport } from './eliot/desk.ts';
|
|
13
|
+
import type { EliotPlatform } from './platform.ts';
|
|
14
|
+
export declare class EliotAccessory {
|
|
15
|
+
#private;
|
|
16
|
+
/**
|
|
17
|
+
* @param transport Stand-in for the Bluetooth link. Only tests pass one;
|
|
18
|
+
* in normal use the accessory builds its own. Without this seam there is
|
|
19
|
+
* no way to exercise the accessory without a desk in the room, and the
|
|
20
|
+
* handler wiring is exactly the part that needs exercising.
|
|
21
|
+
*/
|
|
22
|
+
constructor(platform: EliotPlatform, accessory: PlatformAccessory, config: DeskConfig, transport?: Transport);
|
|
23
|
+
get name(): string;
|
|
24
|
+
start(): Promise<void>;
|
|
25
|
+
stop(): Promise<void>;
|
|
26
|
+
}
|