homebridge-powerview-3 3.0.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 ADDED
@@ -0,0 +1,39 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ ## [3.0.0] - 2026-05-17
6
+
7
+ ### Added
8
+
9
+ - Homebridge **2.x** support (ESM plugin, Node.js 22/24)
10
+ - TypeScript source, `config.schema.json` for Homebridge UI settings
11
+ - `AccessoryInformation` service on each shade (manufacturer, hub firmware model)
12
+
13
+ ### Changed
14
+
15
+ - **Breaking:** npm package renamed to `homebridge-powerview-3`
16
+ - **Breaking:** plugin identifier for accessory cache is now `homebridge-powerview-3` (was `homebridge-powerview`)
17
+ - Replaced deprecated `request` with native `fetch`
18
+ - Replaced `getServiceByUUIDAndSubType` with `getServiceById` (Homebridge 2 API)
19
+ - Removed use of removed `accessory.reachable` property
20
+ - Modern `api.registerPlatform(PLATFORM_NAME, PowerViewPlatform)` registration
21
+ - Hub HTTP client uses Promises/async throughout
22
+
23
+ ### Fixed
24
+
25
+ - `putShade` queue merge incorrectly deleted bottom position (`delete position[...]` → `delete positions[...]`)
26
+ - `jogShade` callback referenced undefined `position` variable
27
+ - `removeService` called when top Window Covering service did not exist
28
+
29
+ ### Migration from homebridge-powerview-2
30
+
31
+ 1. Uninstall `homebridge-powerview-2`, install `homebridge-powerview-3`.
32
+ 2. Keep `"platform": "PowerView"` in `config.json`; add `"name": "PowerView"` if using the config UI schema.
33
+ 3. Restart Homebridge. Remove duplicate shade accessories from the Home app if the cache identifier change left orphans.
34
+
35
+ Requires Homebridge **^1.8.0 || ^2.0.0** and Node **^22.12.0 || ^24.0.0**.
36
+
37
+ ## [1.0.9] and earlier
38
+
39
+ See [homebridge-powerview-2](https://github.com/owenselles/homebridge-powerview-2) history.
package/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # homebridge-powerview-3
2
+
3
+ [![npm](https://img.shields.io/npm/v/homebridge-powerview-3.svg)](https://www.npmjs.com/package/homebridge-powerview-3)
4
+ [![npm](https://img.shields.io/npm/dt/homebridge-powerview-3.svg)](https://www.npmjs.com/package/homebridge-powerview-3)
5
+
6
+ Homebridge plugin for [Hunter Douglas PowerView](https://www.hunterdouglas.com/operating-systems/motorized/powerview-motorization) window shades. Compatible with **Homebridge 1.8+** and **Homebridge 2.x** (Node.js 22 or 24).
7
+
8
+ Supports Generation 1 and 2 PowerView hubs.
9
+
10
+ ## Requirements
11
+
12
+ - [Homebridge](https://github.com/homebridge/homebridge) **1.8.0** or **2.0.0**
13
+ - Node.js **22** or **24**
14
+
15
+ ## Supported shades
16
+
17
+ - Roller shades
18
+ - Horizontal vane shades (e.g. Silhouette, Pirouette) — position plus tilt in Details
19
+ - Vertical vane shades (e.g. Luminette) — position plus tilt in Details
20
+ - Top-down/bottom-up shades (e.g. Duette) — two Window Covering services per shade
21
+
22
+ Shades work in HomeKit scenes and automations.
23
+
24
+ ## Installation
25
+
26
+ 1. Install and set up [Homebridge](https://github.com/homebridge/homebridge).
27
+ 2. Install the plugin (Homebridge UI **Plugins** tab, or CLI):
28
+
29
+ ```bash
30
+ npm install -g homebridge-powerview-3
31
+ ```
32
+
33
+ 3. Add the **PowerView** platform via the plugin **Settings** button in the Homebridge UI, or add a platform block to `config.json`:
34
+
35
+ ```json
36
+ "platforms": [
37
+ {
38
+ "platform": "PowerView",
39
+ "name": "PowerView"
40
+ }
41
+ ]
42
+ ```
43
+
44
+ The hub is contacted at `powerview-hub.local` by default.
45
+
46
+ ## Configuration
47
+
48
+ | Option | Description | Default |
49
+ |--------|-------------|---------|
50
+ | `name` | Platform name in Homebridge | `PowerView` |
51
+ | `host` | Hub hostname or IP | `powerview-hub.local` |
52
+ | `refreshShades` | Request fresh positions from the hub on every HomeKit read | `false` |
53
+ | `pollShadesForUpdate` | Poll the hub every 30 seconds for position updates | `false` |
54
+ | `forceRollerShades` | Shade IDs to treat as roller | `[]` |
55
+ | `forceTopBottomShades` | Shade IDs to treat as top/bottom | `[]` |
56
+ | `forceHorizontalShades` | Shade IDs to treat as horizontal vane | `[]` |
57
+ | `forceVerticalShades` | Shade IDs to treat as vertical vane | `[]` |
58
+
59
+ Example with host and polling:
60
+
61
+ ```json
62
+ {
63
+ "platform": "PowerView",
64
+ "name": "PowerView",
65
+ "host": "192.168.1.50",
66
+ "pollShadesForUpdate": true
67
+ }
68
+ ```
69
+
70
+ ### Unknown shade types
71
+
72
+ If the hub reports an unknown shade type, the log may show:
73
+
74
+ ```
75
+ Shade 12345 has unknown type 66, assuming roller
76
+ ```
77
+
78
+ Please [open an issue](https://github.com/squircle12/homebridge-powerview-3/issues) with the shade model. You can override detection with the `force*` arrays above.
79
+
80
+ ## Migrating from homebridge-powerview-2
81
+
82
+ 1. Stop Homebridge.
83
+ 2. Uninstall the old plugin: `npm uninstall -g homebridge-powerview-2`
84
+ 3. Install `homebridge-powerview-3`.
85
+ 4. Update your config: keep `"platform": "PowerView"` and add `"name": "PowerView"` if missing.
86
+ 5. Remove any old **PowerView** platform entry that pointed at the v2 package, then add the platform again for v3.
87
+ 6. Restart Homebridge.
88
+
89
+ The plugin identifier changed from `homebridge-powerview` to `homebridge-powerview-3`. Cached accessories from the old package may appear as duplicates in the Home app. Remove ghost accessories from Home if needed.
90
+
91
+ ## Shade examples
92
+
93
+ Tap an accessory to open/close; long-press for a custom position.
94
+
95
+ ### Horizontal and vertical vanes
96
+
97
+ Use **Details** after a long-press to adjust tilt. For scenes: use **Closed** when setting vane tilt; use **0°** tilt when setting position.
98
+
99
+ ### Top-down/bottom-up
100
+
101
+ Two controls are created per shade (bottom and top), which can be used independently or in scenes.
102
+
103
+ ## Development
104
+
105
+ ```bash
106
+ npm install
107
+ npm run build
108
+ npm run lint
109
+ ```
110
+
111
+ ## License
112
+
113
+ ISC
@@ -0,0 +1,57 @@
1
+ {
2
+ "pluginAlias": "PowerView",
3
+ "pluginType": "platform",
4
+ "singular": true,
5
+ "strictValidation": false,
6
+ "schema": {
7
+ "type": "object",
8
+ "required": ["name"],
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "name": {
12
+ "title": "Name",
13
+ "type": "string",
14
+ "default": "PowerView"
15
+ },
16
+ "host": {
17
+ "title": "Hub host",
18
+ "type": "string",
19
+ "description": "Hostname or IP of the PowerView hub.",
20
+ "placeholder": "powerview-hub.local"
21
+ },
22
+ "refreshShades": {
23
+ "title": "Refresh on read",
24
+ "type": "boolean",
25
+ "default": false,
26
+ "description": "Request fresh shade positions from the hub on every HomeKit read."
27
+ },
28
+ "pollShadesForUpdate": {
29
+ "title": "Poll every 30 seconds",
30
+ "type": "boolean",
31
+ "default": false,
32
+ "description": "Periodically poll the hub for shade position updates."
33
+ },
34
+ "forceRollerShades": {
35
+ "title": "Force roller shade IDs",
36
+ "type": "array",
37
+ "items": { "type": "integer" },
38
+ "description": "Treat these shade IDs as roller shades regardless of hub type."
39
+ },
40
+ "forceTopBottomShades": {
41
+ "title": "Force top/bottom shade IDs",
42
+ "type": "array",
43
+ "items": { "type": "integer" }
44
+ },
45
+ "forceHorizontalShades": {
46
+ "title": "Force horizontal vane shade IDs",
47
+ "type": "array",
48
+ "items": { "type": "integer" }
49
+ },
50
+ "forceVerticalShades": {
51
+ "title": "Force vertical vane shade IDs",
52
+ "type": "array",
53
+ "items": { "type": "integer" }
54
+ }
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,6 @@
1
+ import type { API } from 'homebridge';
2
+ /**
3
+ * Registers the PowerView platform with Homebridge.
4
+ */
5
+ declare const _default: (api: API) => void;
6
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import { PowerViewPlatform } from './platform.js';
2
+ import { PLATFORM_NAME } from './settings.js';
3
+ /**
4
+ * Registers the PowerView platform with Homebridge.
5
+ */
6
+ export default (api) => {
7
+ api.registerPlatform(PLATFORM_NAME, PowerViewPlatform);
8
+ };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,eAAe,CAAC,GAAQ,EAAE,EAAE;IAC1B,GAAG,CAAC,gBAAgB,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;AACzD,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { API, Characteristic, DynamicPlatformPlugin, Logging, PlatformAccessory, Service } from 'homebridge';
2
+ import { HubPosition, type PowerViewShade } from './powerviewHub.js';
3
+ import { type CharacteristicCallback } from './platformAccessory.js';
4
+ import { ShadeKind, type PowerViewPlatformConfig, type ShadeContext } from './settings.js';
5
+ export declare class PowerViewPlatform implements DynamicPlatformPlugin {
6
+ readonly log: Logging;
7
+ readonly api: API;
8
+ readonly Service: typeof Service;
9
+ readonly Characteristic: typeof Characteristic;
10
+ readonly accessories: Record<number, PlatformAccessory<ShadeContext>>;
11
+ private readonly handlers;
12
+ hubVersion?: string;
13
+ private hubName?;
14
+ private readonly hub;
15
+ private readonly refreshShades;
16
+ private readonly pollShadesForUpdate;
17
+ private readonly forceRollerShades;
18
+ private readonly forceTopBottomShades;
19
+ private readonly forceHorizontalShades;
20
+ private readonly forceVerticalShades;
21
+ constructor(log: Logging, config: PowerViewPlatformConfig, api: API);
22
+ private onLaunch;
23
+ shadeType(shade: PowerViewShade): ShadeKind;
24
+ configureAccessory(accessory: PlatformAccessory): void;
25
+ private registerHandler;
26
+ private addShadeAccessory;
27
+ private updateShadeAccessory;
28
+ private removeShadeAccessory;
29
+ updateShades(): Promise<void>;
30
+ private pollShades;
31
+ updateHubInfo(): Promise<void>;
32
+ private updateShade;
33
+ getPosition(shadeId: number, position: HubPosition, callback: CharacteristicCallback): Promise<void>;
34
+ private updatePosition;
35
+ setPosition(shadeId: number, position: HubPosition, value: number, callback: (error: Error | null) => void): Promise<void>;
36
+ jogShade(shadeId: number): Promise<Partial<Record<HubPosition, number>> | null>;
37
+ }
@@ -0,0 +1,246 @@
1
+ import { HubPosition, PowerViewHub, } from './powerviewHub.js';
2
+ import { PowerViewPlatformAccessory, } from './platformAccessory.js';
3
+ import { PLUGIN_NAME, PLATFORM_NAME, SHADE_POLL_INTERVAL_MS, SHADE_TYPE_IDS, ShadeKind, SUBTYPE, } from './settings.js';
4
+ export class PowerViewPlatform {
5
+ log;
6
+ api;
7
+ Service;
8
+ Characteristic;
9
+ accessories = {};
10
+ handlers = new Map();
11
+ hubVersion;
12
+ hubName;
13
+ hub;
14
+ refreshShades;
15
+ pollShadesForUpdate;
16
+ forceRollerShades;
17
+ forceTopBottomShades;
18
+ forceHorizontalShades;
19
+ forceVerticalShades;
20
+ constructor(log, config, api) {
21
+ this.log = log;
22
+ this.api = api;
23
+ this.Service = api.hap.Service;
24
+ this.Characteristic = api.hap.Characteristic;
25
+ this.log.info('PowerView init');
26
+ const host = config.host ?? 'powerview-hub.local';
27
+ this.hub = new PowerViewHub(log, host);
28
+ this.refreshShades = config.refreshShades === true;
29
+ this.pollShadesForUpdate = config.pollShadesForUpdate === true;
30
+ this.forceRollerShades = config.forceRollerShades ?? [];
31
+ this.forceTopBottomShades = config.forceTopBottomShades ?? [];
32
+ this.forceHorizontalShades = config.forceHorizontalShades ?? [];
33
+ this.forceVerticalShades = config.forceVerticalShades ?? [];
34
+ this.api.on('didFinishLaunching', () => {
35
+ void this.onLaunch();
36
+ });
37
+ }
38
+ async onLaunch() {
39
+ try {
40
+ await this.updateHubInfo();
41
+ if (this.pollShadesForUpdate) {
42
+ this.pollShades();
43
+ }
44
+ else {
45
+ await this.updateShades();
46
+ }
47
+ }
48
+ catch (err) {
49
+ const message = err instanceof Error ? err.message : String(err);
50
+ this.log.error('Failed to start PowerView platform:', message);
51
+ }
52
+ }
53
+ shadeType(shade) {
54
+ if (this.forceRollerShades.includes(shade.id)) {
55
+ return ShadeKind.ROLLER;
56
+ }
57
+ if (this.forceTopBottomShades.includes(shade.id)) {
58
+ return ShadeKind.TOP_BOTTOM;
59
+ }
60
+ if (this.forceHorizontalShades.includes(shade.id)) {
61
+ return ShadeKind.HORIZONTAL;
62
+ }
63
+ if (this.forceVerticalShades.includes(shade.id)) {
64
+ return ShadeKind.VERTICAL;
65
+ }
66
+ const type = shade.type ?? 0;
67
+ if (SHADE_TYPE_IDS.ROLLER.includes(type)) {
68
+ return ShadeKind.ROLLER;
69
+ }
70
+ if (SHADE_TYPE_IDS.TOP_BOTTOM.includes(type)) {
71
+ return ShadeKind.TOP_BOTTOM;
72
+ }
73
+ if (SHADE_TYPE_IDS.HORIZONTAL.includes(type)) {
74
+ return ShadeKind.HORIZONTAL;
75
+ }
76
+ if (SHADE_TYPE_IDS.VERTICAL.includes(type)) {
77
+ return ShadeKind.VERTICAL;
78
+ }
79
+ this.log.warn(`Shade ${shade.id} has unknown type ${type}, assuming roller`);
80
+ return ShadeKind.ROLLER;
81
+ }
82
+ configureAccessory(accessory) {
83
+ const shadeAccessory = accessory;
84
+ this.log.info('Cached shade %d: %s', shadeAccessory.context.shadeId, shadeAccessory.displayName);
85
+ if (!shadeAccessory.context.shadeType) {
86
+ const topService = shadeAccessory.getServiceById(this.Service.WindowCovering.UUID, SUBTYPE.TOP);
87
+ shadeAccessory.context.shadeType = topService ? ShadeKind.TOP_BOTTOM : ShadeKind.ROLLER;
88
+ }
89
+ this.registerHandler(shadeAccessory);
90
+ }
91
+ registerHandler(accessory) {
92
+ const shadeId = accessory.context.shadeId;
93
+ this.accessories[shadeId] = accessory;
94
+ const handler = new PowerViewPlatformAccessory(this, accessory, this.log);
95
+ this.handlers.set(shadeId, handler);
96
+ }
97
+ addShadeAccessory(shade) {
98
+ const name = Buffer.from(shade.name, 'base64').toString();
99
+ this.log.info('Adding shade %d: %s', shade.id, name);
100
+ const uuid = this.api.hap.uuid.generate(shade.id.toString());
101
+ const accessory = new this.api.platformAccessory(name, uuid);
102
+ accessory.context.shadeId = shade.id;
103
+ accessory.context.shadeType = this.shadeType(shade);
104
+ this.registerHandler(accessory);
105
+ this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
106
+ return accessory;
107
+ }
108
+ updateShadeAccessory(shade) {
109
+ const accessory = this.accessories[shade.id];
110
+ this.log.info('Updating shade %d: %s', shade.id, accessory.displayName);
111
+ const newType = this.shadeType(shade);
112
+ const handler = this.handlers.get(shade.id);
113
+ if (newType !== accessory.context.shadeType && handler) {
114
+ this.log.info('Shade changed type %d -> %d', accessory.context.shadeType, newType);
115
+ handler.shadeType = newType;
116
+ handler.configure();
117
+ this.api.updatePlatformAccessories([accessory]);
118
+ }
119
+ return accessory;
120
+ }
121
+ removeShadeAccessory(accessory) {
122
+ this.log.info('Removing shade %d: %s', accessory.context.shadeId, accessory.displayName);
123
+ this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
124
+ delete this.accessories[accessory.context.shadeId];
125
+ this.handlers.delete(accessory.context.shadeId);
126
+ }
127
+ async updateShades() {
128
+ const shadeData = await this.hub.getShades();
129
+ const newShades = {};
130
+ for (const shade of shadeData) {
131
+ if (!this.accessories[shade.id]) {
132
+ newShades[shade.id] = this.addShadeAccessory(shade);
133
+ }
134
+ else {
135
+ newShades[shade.id] = this.updateShadeAccessory(shade);
136
+ }
137
+ const handler = this.handlers.get(shade.id);
138
+ handler?.updateShadeValues(shade);
139
+ }
140
+ for (const shadeId of Object.keys(this.accessories)) {
141
+ const id = parseInt(shadeId, 10);
142
+ if (!newShades[id]) {
143
+ this.removeShadeAccessory(this.accessories[id]);
144
+ }
145
+ }
146
+ }
147
+ pollShades() {
148
+ void this.updateShades().finally(() => {
149
+ setTimeout(() => this.pollShades(), SHADE_POLL_INTERVAL_MS);
150
+ });
151
+ }
152
+ async updateHubInfo() {
153
+ const userData = await this.hub.getUserData();
154
+ this.hubName = Buffer.from(userData.hubName, 'base64').toString();
155
+ if (userData.firmware?.mainProcessor) {
156
+ this.hubVersion = userData.firmware.mainProcessor.name;
157
+ }
158
+ this.log.info('Hub: %s', this.hubName);
159
+ for (const handler of this.handlers.values()) {
160
+ handler.updateAccessoryInformation();
161
+ }
162
+ }
163
+ async updateShade(shadeId, refresh = false) {
164
+ const shade = await this.hub.getShade(shadeId, refresh);
165
+ const handler = this.handlers.get(shadeId);
166
+ const positions = handler?.updateShadeValues(shade) ?? null;
167
+ return { positions, timedOut: refresh ? shade.timedOut : undefined };
168
+ }
169
+ async getPosition(shadeId, position, callback) {
170
+ this.log.info('getPosition %d/%d', shadeId, position);
171
+ try {
172
+ const value = await this.updatePosition(shadeId, position, this.refreshShades);
173
+ if (!this.refreshShades && value == null) {
174
+ this.log.info('refresh %d/%d', shadeId, position);
175
+ const refreshed = await this.updatePosition(shadeId, position, true);
176
+ callback(null, refreshed ?? 0);
177
+ }
178
+ else {
179
+ callback(null, value ?? 0);
180
+ }
181
+ }
182
+ catch (err) {
183
+ callback(err instanceof Error ? err : new Error(String(err)));
184
+ }
185
+ }
186
+ async updatePosition(shadeId, position, refresh) {
187
+ const { positions, timedOut } = await this.updateShade(shadeId, refresh);
188
+ if (refresh && timedOut) {
189
+ this.log.warn('Timeout for %d/%d', shadeId, position);
190
+ throw new Error('Timed out');
191
+ }
192
+ if (!positions) {
193
+ this.log.warn('Hub did not return positions for %d/%d', shadeId, position);
194
+ return null;
195
+ }
196
+ const value = positions[position];
197
+ if (typeof value === 'number' && Number.isFinite(value)) {
198
+ this.log.info('updatePosition %d/%d: %d', shadeId, position, value);
199
+ return value;
200
+ }
201
+ this.log.warn('Invalid position value received for %d/%d', shadeId, position);
202
+ return 0;
203
+ }
204
+ async setPosition(shadeId, position, value, callback) {
205
+ this.log.info('setPosition %d/%d = %d', shadeId, position, value);
206
+ if (typeof value !== 'number' || Number.isNaN(value) || !Number.isFinite(value)) {
207
+ callback(new Error(`Invalid value: ${value}`));
208
+ return;
209
+ }
210
+ let hubValue;
211
+ switch (position) {
212
+ case HubPosition.BOTTOM:
213
+ case HubPosition.TOP:
214
+ hubValue = Math.round(65535 * value / 100);
215
+ break;
216
+ case HubPosition.VANES: {
217
+ const accessory = this.accessories[shadeId];
218
+ if (accessory.context.shadeType === ShadeKind.VERTICAL) {
219
+ hubValue = Math.abs(Math.round(65535 * (value - 90) / 180));
220
+ }
221
+ else {
222
+ hubValue = Math.round(32767 * value / 90);
223
+ }
224
+ break;
225
+ }
226
+ default:
227
+ callback(new Error(`Unknown position: ${position}`));
228
+ return;
229
+ }
230
+ try {
231
+ const shade = await this.hub.putShade(shadeId, position, hubValue, value);
232
+ const handler = this.handlers.get(shadeId);
233
+ handler?.updateShadeValues(shade, true);
234
+ callback(null);
235
+ }
236
+ catch (err) {
237
+ callback(err instanceof Error ? err : new Error(String(err)));
238
+ }
239
+ }
240
+ async jogShade(shadeId) {
241
+ const shade = await this.hub.jogShade(shadeId);
242
+ const handler = this.handlers.get(shadeId);
243
+ return handler?.updateShadeValues(shade) ?? null;
244
+ }
245
+ }
246
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AASA,OAAO,EACL,WAAW,EACX,YAAY,GAEb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,0BAA0B,GAE3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,WAAW,EACX,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,SAAS,EACT,OAAO,GAGR,MAAM,eAAe,CAAC;AAEvB,MAAM,OAAO,iBAAiB;IAmBV;IAEA;IApBF,OAAO,CAAiB;IACxB,cAAc,CAAwB;IAEtC,WAAW,GAAoD,EAAE,CAAC;IACjE,QAAQ,GAA4C,IAAI,GAAG,EAAE,CAAC;IAExE,UAAU,CAAU;IACnB,OAAO,CAAU;IAER,GAAG,CAAe;IAClB,aAAa,CAAU;IACvB,mBAAmB,CAAU;IAC7B,iBAAiB,CAAW;IAC5B,oBAAoB,CAAW;IAC/B,qBAAqB,CAAW;IAChC,mBAAmB,CAAW;IAE/C,YACkB,GAAY,EAC5B,MAA+B,EACf,GAAQ;QAFR,QAAG,GAAH,GAAG,CAAS;QAEZ,QAAG,GAAH,GAAG,CAAK;QAExB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC;QAE7C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAEhC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,qBAAqB,CAAC;QAClD,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAEvC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,KAAK,IAAI,CAAC;QACnD,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,KAAK,IAAI,CAAC;QAE/D,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC;QACxD,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,oBAAoB,IAAI,EAAE,CAAC;QAC9D,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,IAAI,EAAE,CAAC;QAChE,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC;QAE5D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YACrC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,QAAQ;QACpB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qCAAqC,EAAE,OAAO,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,SAAS,CAAC,KAAqB;QAC7B,IAAI,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAC9C,OAAO,SAAS,CAAC,MAAM,CAAC;QAC1B,CAAC;QACD,IAAI,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACjD,OAAO,SAAS,CAAC,UAAU,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAClD,OAAO,SAAS,CAAC,UAAU,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAChD,OAAO,SAAS,CAAC,QAAQ,CAAC;QAC5B,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;QAC7B,IAAK,cAAc,CAAC,MAA4B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAChE,OAAO,SAAS,CAAC,MAAM,CAAC;QAC1B,CAAC;QACD,IAAK,cAAc,CAAC,UAAgC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACpE,OAAO,SAAS,CAAC,UAAU,CAAC;QAC9B,CAAC;QACD,IAAK,cAAc,CAAC,UAAgC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACpE,OAAO,SAAS,CAAC,UAAU,CAAC;QAC9B,CAAC;QACD,IAAK,cAAc,CAAC,QAA8B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClE,OAAO,SAAS,CAAC,QAAQ,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,EAAE,qBAAqB,IAAI,mBAAmB,CAAC,CAAC;QAC7E,OAAO,SAAS,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED,kBAAkB,CAAC,SAA4B;QAC7C,MAAM,cAAc,GAAG,SAA4C,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,qBAAqB,EACrB,cAAc,CAAC,OAAO,CAAC,OAAO,EAC9B,cAAc,CAAC,WAAW,CAC3B,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACtC,MAAM,UAAU,GAAG,cAAc,CAAC,cAAc,CAC9C,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAChC,OAAO,CAAC,GAAG,CACZ,CAAC;YACF,cAAc,CAAC,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;QAC1F,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;IACvC,CAAC;IAEO,eAAe,CAAC,SAA0C;QAChE,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC;QAC1C,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;QAEtC,MAAM,OAAO,GAAG,IAAI,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAEO,iBAAiB,CAAC,KAAqB;QAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC1D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAErD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAe,IAAI,EAAE,IAAI,CAAC,CAAC;QAC3E,SAAS,CAAC,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;QACrC,SAAS,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAEpD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,2BAA2B,CAAC,WAAW,EAAE,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAE9E,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,oBAAoB,CAAC,KAAqB;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;QAExE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAE5C,IAAI,OAAO,KAAK,SAAS,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC;YACvD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACnF,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC;YAC5B,OAAO,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,oBAAoB,CAAC,SAA0C;QACrE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;QACzF,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,WAAW,EAAE,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAChF,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QAC7C,MAAM,SAAS,GAAoD,EAAE,CAAC;QAEtE,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBAChC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;YACzD,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC5C,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACpD,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAEO,UAAU;QAChB,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YACpC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,sBAAsB,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;QAClE,IAAI,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC;YACrC,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAEvC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,OAAO,CAAC,0BAA0B,EAAE,CAAC;QACvC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW,CACvB,OAAe,EACf,OAAO,GAAG,KAAK;QAEf,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;QAC5D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,WAAW,CACf,OAAe,EACf,QAAqB,EACrB,QAAgC;QAEhC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEtD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;YAC/E,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBACzC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAClD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;gBACrE,QAAQ,CAAC,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAC1B,OAAe,EACf,QAAqB,EACrB,OAAgB;QAEhB,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAEzE,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wCAAwC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC3E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,2CAA2C,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC9E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,WAAW,CACf,OAAe,EACf,QAAqB,EACrB,KAAa,EACb,QAAuC;QAEvC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAElE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChF,QAAQ,CAAC,IAAI,KAAK,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC,CAAC;YAC/C,OAAO;QACT,CAAC;QAED,IAAI,QAAgB,CAAC;QACrB,QAAQ,QAAQ,EAAE,CAAC;YACnB,KAAK,WAAW,CAAC,MAAM,CAAC;YACxB,KAAK,WAAW,CAAC,GAAG;gBAClB,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;gBAC3C,MAAM;YACR,KAAK,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;gBACvB,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;gBAC5C,IAAI,SAAS,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,QAAQ,EAAE,CAAC;oBACvD,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBAC9D,CAAC;qBAAM,CAAC;oBACN,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC;gBAC5C,CAAC;gBACD,MAAM;YACR,CAAC;YACD;gBACE,QAAQ,CAAC,IAAI,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC,CAAC;gBACrD,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,EAAE,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACxC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IACnD,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ import type { CharacteristicValue, Logging, PlatformAccessory } from 'homebridge';
2
+ import { HubPosition, type PowerViewShade } from './powerviewHub.js';
3
+ import type { PowerViewPlatform } from './platform.js';
4
+ import { ShadeKind, type ShadeContext } from './settings.js';
5
+ type PositionMap = Partial<Record<HubPosition, number>> | null;
6
+ export declare class PowerViewPlatformAccessory {
7
+ private readonly platform;
8
+ readonly accessory: PlatformAccessory<ShadeContext>;
9
+ private readonly log;
10
+ constructor(platform: PowerViewPlatform, accessory: PlatformAccessory<ShadeContext>, log: Logging);
11
+ private get Service();
12
+ private get Characteristic();
13
+ get shadeId(): number;
14
+ get shadeType(): ShadeKind;
15
+ set shadeType(type: ShadeKind);
16
+ private windowCoveringService;
17
+ configure(): void;
18
+ private resetOptionalTiltCharacteristics;
19
+ updateAccessoryInformation(): void;
20
+ updateShadeValues(shade: PowerViewShade, current?: boolean): PositionMap;
21
+ }
22
+ export type CharacteristicCallback = (error: Error | null, value?: CharacteristicValue) => void;
23
+ export {};
@@ -0,0 +1,223 @@
1
+ import { HubPosition } from './powerviewHub.js';
2
+ import { ShadeKind, SUBTYPE } from './settings.js';
3
+ export class PowerViewPlatformAccessory {
4
+ platform;
5
+ accessory;
6
+ log;
7
+ constructor(platform, accessory, log) {
8
+ this.platform = platform;
9
+ this.accessory = accessory;
10
+ this.log = log;
11
+ this.configure();
12
+ this.updateAccessoryInformation();
13
+ }
14
+ get Service() {
15
+ return this.platform.Service;
16
+ }
17
+ get Characteristic() {
18
+ return this.platform.Characteristic;
19
+ }
20
+ get shadeId() {
21
+ return this.accessory.context.shadeId;
22
+ }
23
+ get shadeType() {
24
+ return this.accessory.context.shadeType;
25
+ }
26
+ set shadeType(type) {
27
+ this.accessory.context.shadeType = type;
28
+ }
29
+ windowCoveringService(subtype) {
30
+ return this.accessory.getServiceById(this.Service.WindowCovering.UUID, subtype);
31
+ }
32
+ configure() {
33
+ const shadeId = this.shadeId;
34
+ let service = this.windowCoveringService(SUBTYPE.BOTTOM);
35
+ if (!service) {
36
+ service = this.accessory.addService(this.Service.WindowCovering, this.accessory.displayName, SUBTYPE.BOTTOM);
37
+ }
38
+ service
39
+ .getCharacteristic(this.Characteristic.CurrentPosition)
40
+ .removeAllListeners('get')
41
+ .on('get', (callback) => {
42
+ void this.platform.getPosition(shadeId, HubPosition.BOTTOM, callback);
43
+ });
44
+ service
45
+ .getCharacteristic(this.Characteristic.TargetPosition)
46
+ .removeAllListeners('set')
47
+ .on('set', (value, callback) => {
48
+ void this.platform.setPosition(shadeId, HubPosition.BOTTOM, value, callback);
49
+ });
50
+ if (this.shadeType === ShadeKind.HORIZONTAL) {
51
+ service
52
+ .getCharacteristic(this.Characteristic.CurrentHorizontalTiltAngle)
53
+ .setProps({ minValue: 0 })
54
+ .removeAllListeners('get')
55
+ .on('get', (callback) => {
56
+ void this.platform.getPosition(shadeId, HubPosition.VANES, callback);
57
+ });
58
+ service
59
+ .getCharacteristic(this.Characteristic.TargetHorizontalTiltAngle)
60
+ .setProps({ minValue: 0 })
61
+ .removeAllListeners('set')
62
+ .on('set', (value, callback) => {
63
+ void this.platform.setPosition(shadeId, HubPosition.VANES, value, callback);
64
+ });
65
+ }
66
+ else {
67
+ this.resetOptionalTiltCharacteristics(service, 'horizontal');
68
+ }
69
+ if (this.shadeType === ShadeKind.VERTICAL) {
70
+ service
71
+ .getCharacteristic(this.Characteristic.CurrentVerticalTiltAngle)
72
+ .removeAllListeners('get')
73
+ .on('get', (callback) => {
74
+ void this.platform.getPosition(shadeId, HubPosition.VANES, callback);
75
+ });
76
+ service
77
+ .getCharacteristic(this.Characteristic.TargetVerticalTiltAngle)
78
+ .removeAllListeners('set')
79
+ .on('set', (value, callback) => {
80
+ void this.platform.setPosition(shadeId, HubPosition.VANES, value, callback);
81
+ });
82
+ }
83
+ else {
84
+ this.resetOptionalTiltCharacteristics(service, 'vertical');
85
+ }
86
+ let topService = this.windowCoveringService(SUBTYPE.TOP);
87
+ if (this.shadeType === ShadeKind.TOP_BOTTOM) {
88
+ if (!topService) {
89
+ topService = this.accessory.addService(this.Service.WindowCovering, this.accessory.displayName, SUBTYPE.TOP);
90
+ }
91
+ topService
92
+ .getCharacteristic(this.Characteristic.CurrentPosition)
93
+ .removeAllListeners('get')
94
+ .on('get', (callback) => {
95
+ void this.platform.getPosition(shadeId, HubPosition.TOP, callback);
96
+ });
97
+ topService
98
+ .getCharacteristic(this.Characteristic.TargetPosition)
99
+ .removeAllListeners('set')
100
+ .on('set', (value, callback) => {
101
+ void this.platform.setPosition(shadeId, HubPosition.TOP, value, callback);
102
+ });
103
+ }
104
+ else if (topService) {
105
+ this.accessory.removeService(topService);
106
+ }
107
+ this.updateAccessoryInformation();
108
+ }
109
+ resetOptionalTiltCharacteristics(service, axis) {
110
+ const targets = axis === 'horizontal'
111
+ ? [
112
+ this.Characteristic.TargetHorizontalTiltAngle,
113
+ this.Characteristic.CurrentHorizontalTiltAngle,
114
+ ]
115
+ : [
116
+ this.Characteristic.TargetVerticalTiltAngle,
117
+ this.Characteristic.CurrentVerticalTiltAngle,
118
+ ];
119
+ for (const characteristic of targets) {
120
+ if (service.testCharacteristic(characteristic)) {
121
+ const ch = service.getCharacteristic(characteristic);
122
+ service.removeCharacteristic(ch);
123
+ service.addOptionalCharacteristic(characteristic);
124
+ }
125
+ }
126
+ }
127
+ updateAccessoryInformation() {
128
+ let info = this.accessory.getService(this.Service.AccessoryInformation);
129
+ if (!info) {
130
+ info = this.accessory.addService(this.Service.AccessoryInformation);
131
+ }
132
+ info
133
+ .setCharacteristic(this.Characteristic.Manufacturer, 'Hunter Douglas')
134
+ .setCharacteristic(this.Characteristic.Model, this.platform.hubVersion ?? 'PowerView');
135
+ }
136
+ updateShadeValues(shade, current = false) {
137
+ const positions = {};
138
+ if (!shade.positions) {
139
+ return positions;
140
+ }
141
+ this.log.info('Set for', shade.id, { positions: shade.positions });
142
+ for (let i = 1; shade.positions[`posKind${i}`]; ++i) {
143
+ const position = shade.positions[`posKind${i}`];
144
+ const hubValue = shade.positions[`position${i}`];
145
+ if (position === HubPosition.BOTTOM) {
146
+ positions[HubPosition.BOTTOM] = Math.round(100 * hubValue / 65535);
147
+ const service = this.windowCoveringService(SUBTYPE.BOTTOM);
148
+ if (!service) {
149
+ continue;
150
+ }
151
+ if (current) {
152
+ this.log.info('Setting CurrentPosition to:', positions[HubPosition.BOTTOM]);
153
+ if (!Number.isNaN(positions[HubPosition.BOTTOM])) {
154
+ service.setCharacteristic(this.Characteristic.CurrentPosition, positions[HubPosition.BOTTOM]);
155
+ }
156
+ else {
157
+ this.log.warn('Invalid position value:', positions[HubPosition.BOTTOM]);
158
+ }
159
+ }
160
+ if (!Number.isNaN(positions[HubPosition.BOTTOM])) {
161
+ service.updateCharacteristic(this.Characteristic.TargetPosition, positions[HubPosition.BOTTOM]);
162
+ }
163
+ service.setCharacteristic(this.Characteristic.PositionState, this.Characteristic.PositionState.STOPPED);
164
+ if (this.shadeType === ShadeKind.HORIZONTAL && current) {
165
+ service.setCharacteristic(this.Characteristic.CurrentHorizontalTiltAngle, 0);
166
+ service.updateCharacteristic(this.Characteristic.TargetHorizontalTiltAngle, 0);
167
+ }
168
+ if (this.shadeType === ShadeKind.VERTICAL && current) {
169
+ service.setCharacteristic(this.Characteristic.CurrentVerticalTiltAngle, 0);
170
+ service.updateCharacteristic(this.Characteristic.TargetVerticalTiltAngle, 0);
171
+ }
172
+ }
173
+ if (position === HubPosition.VANES && this.shadeType === ShadeKind.HORIZONTAL) {
174
+ positions[HubPosition.VANES] = Math.round(90 * hubValue / 32767);
175
+ const service = this.windowCoveringService(SUBTYPE.BOTTOM);
176
+ if (!service) {
177
+ continue;
178
+ }
179
+ if (current) {
180
+ service.setCharacteristic(this.Characteristic.CurrentPosition, 0);
181
+ }
182
+ service.updateCharacteristic(this.Characteristic.TargetPosition, 0);
183
+ service.setCharacteristic(this.Characteristic.PositionState, this.Characteristic.PositionState.STOPPED);
184
+ if (current && !Number.isNaN(positions[HubPosition.VANES])) {
185
+ service.setCharacteristic(this.Characteristic.CurrentHorizontalTiltAngle, positions[HubPosition.VANES]);
186
+ }
187
+ if (!Number.isNaN(positions[HubPosition.VANES])) {
188
+ service.updateCharacteristic(this.Characteristic.TargetHorizontalTiltAngle, positions[HubPosition.VANES]);
189
+ }
190
+ }
191
+ if (position === HubPosition.VANES && this.shadeType === ShadeKind.VERTICAL) {
192
+ positions[HubPosition.VANES] = 90 - Math.round(180 * hubValue / 65535);
193
+ const service = this.windowCoveringService(SUBTYPE.BOTTOM);
194
+ if (!service) {
195
+ continue;
196
+ }
197
+ if (current) {
198
+ service.setCharacteristic(this.Characteristic.CurrentPosition, 0);
199
+ }
200
+ service.updateCharacteristic(this.Characteristic.TargetPosition, 0);
201
+ service.setCharacteristic(this.Characteristic.PositionState, this.Characteristic.PositionState.STOPPED);
202
+ if (current) {
203
+ service.setCharacteristic(this.Characteristic.CurrentVerticalTiltAngle, positions[HubPosition.VANES]);
204
+ }
205
+ service.updateCharacteristic(this.Characteristic.TargetVerticalTiltAngle, positions[HubPosition.VANES]);
206
+ }
207
+ if (position === HubPosition.TOP && this.shadeType === ShadeKind.TOP_BOTTOM) {
208
+ positions[HubPosition.TOP] = Math.round(100 * hubValue / 65535);
209
+ const service = this.windowCoveringService(SUBTYPE.TOP);
210
+ if (!service) {
211
+ continue;
212
+ }
213
+ if (current) {
214
+ service.setCharacteristic(this.Characteristic.CurrentPosition, positions[HubPosition.TOP]);
215
+ }
216
+ service.updateCharacteristic(this.Characteristic.TargetPosition, positions[HubPosition.TOP]);
217
+ service.setCharacteristic(this.Characteristic.PositionState, this.Characteristic.PositionState.STOPPED);
218
+ }
219
+ }
220
+ return positions;
221
+ }
222
+ }
223
+ //# sourceMappingURL=platformAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platformAccessory.js","sourceRoot":"","sources":["../src/platformAccessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { Logging } from 'homebridge';
2
+ export declare enum HubPosition {
3
+ BOTTOM = 1,
4
+ TOP = 2,
5
+ VANES = 3
6
+ }
7
+ export interface ShadePositions {
8
+ [key: string]: number;
9
+ }
10
+ export interface PowerViewShade {
11
+ id: number;
12
+ name: string;
13
+ type?: number;
14
+ positions?: ShadePositions;
15
+ timedOut?: boolean;
16
+ }
17
+ export interface HubUserData {
18
+ hubName: string;
19
+ serialNumber: string;
20
+ firmware?: {
21
+ mainProcessor?: {
22
+ name: string;
23
+ };
24
+ };
25
+ }
26
+ export declare class PowerViewHub {
27
+ private readonly log;
28
+ private readonly host;
29
+ private readonly queue;
30
+ constructor(log: Logging, host: string);
31
+ private baseUrl;
32
+ private fetchJson;
33
+ private queueRequest;
34
+ private scheduleRequest;
35
+ private processQueue;
36
+ getUserData(): Promise<HubUserData>;
37
+ getShades(): Promise<PowerViewShade[]>;
38
+ getShade(shadeId: number, refresh?: boolean): Promise<PowerViewShade>;
39
+ putShade(shadeId: number, position: HubPosition, value: number, userValue: number): Promise<PowerViewShade>;
40
+ jogShade(shadeId: number): Promise<PowerViewShade>;
41
+ }
@@ -0,0 +1,225 @@
1
+ const INITIAL_REQUEST_DELAY_MS = 100;
2
+ const REQUEST_INTERVAL_MS = 100;
3
+ export var HubPosition;
4
+ (function (HubPosition) {
5
+ HubPosition[HubPosition["BOTTOM"] = 1] = "BOTTOM";
6
+ HubPosition[HubPosition["TOP"] = 2] = "TOP";
7
+ HubPosition[HubPosition["VANES"] = 3] = "VANES";
8
+ })(HubPosition || (HubPosition = {}));
9
+ export class PowerViewHub {
10
+ log;
11
+ host;
12
+ queue = [];
13
+ constructor(log, host) {
14
+ this.log = log;
15
+ this.host = host;
16
+ }
17
+ baseUrl(path) {
18
+ return `http://${this.host}${path}`;
19
+ }
20
+ async fetchJson(url, init) {
21
+ const response = await fetch(url, init);
22
+ if (!response.ok) {
23
+ throw new Error(`HTTP Error ${response.status}`);
24
+ }
25
+ return response.json();
26
+ }
27
+ queueRequest(queued) {
28
+ if (!this.queue.length) {
29
+ this.scheduleRequest(INITIAL_REQUEST_DELAY_MS);
30
+ }
31
+ this.queue.push(queued);
32
+ }
33
+ scheduleRequest(delay) {
34
+ setTimeout(() => {
35
+ void this.processQueue();
36
+ }, delay);
37
+ }
38
+ async processQueue() {
39
+ const queued = this.queue[0];
40
+ if (!queued) {
41
+ return;
42
+ }
43
+ const url = new URL(this.baseUrl(`/api/shades/${queued.shadeId}`));
44
+ if (queued.qs) {
45
+ for (const [key, value] of Object.entries(queued.qs)) {
46
+ url.searchParams.set(key, value);
47
+ }
48
+ }
49
+ let init;
50
+ if (queued.data) {
51
+ init = {
52
+ method: 'PUT',
53
+ headers: { 'Content-Type': 'application/json' },
54
+ body: JSON.stringify({ shade: queued.data }),
55
+ };
56
+ this.log.info('Put for', queued.shadeId, queued.data);
57
+ }
58
+ try {
59
+ const json = await this.fetchJson(url.toString(), init);
60
+ for (const callback of queued.callbacks) {
61
+ callback(null, json.shade);
62
+ }
63
+ }
64
+ catch (err) {
65
+ const error = err instanceof Error ? err : new Error(String(err));
66
+ this.log.error('Error on shade request:', error.message);
67
+ for (const callback of queued.callbacks) {
68
+ callback(error);
69
+ }
70
+ }
71
+ this.queue.shift();
72
+ if (this.queue.length > 0) {
73
+ this.scheduleRequest(REQUEST_INTERVAL_MS);
74
+ }
75
+ }
76
+ async getUserData() {
77
+ const json = await this.fetchJson(this.baseUrl('/api/userdata'));
78
+ return json.userData;
79
+ }
80
+ async getShades() {
81
+ const json = await this.fetchJson(this.baseUrl('/api/shades'));
82
+ return json.shadeData;
83
+ }
84
+ async getShade(shadeId, refresh = false) {
85
+ if (refresh) {
86
+ return new Promise((resolve, reject) => {
87
+ for (const queued of this.queue) {
88
+ if (queued.shadeId === shadeId && queued.qs) {
89
+ queued.callbacks.push((err, shade) => {
90
+ if (err) {
91
+ reject(err);
92
+ }
93
+ else if (shade) {
94
+ resolve(shade);
95
+ }
96
+ else {
97
+ reject(new Error('No shade data returned'));
98
+ }
99
+ });
100
+ return;
101
+ }
102
+ }
103
+ this.queueRequest({
104
+ shadeId,
105
+ qs: { refresh: 'true' },
106
+ callbacks: [(err, shade) => {
107
+ if (err) {
108
+ reject(err);
109
+ }
110
+ else if (shade) {
111
+ resolve(shade);
112
+ }
113
+ else {
114
+ reject(new Error('No shade data returned'));
115
+ }
116
+ }],
117
+ });
118
+ });
119
+ }
120
+ const json = await this.fetchJson(this.baseUrl(`/api/shades/${shadeId}`));
121
+ return json.shade;
122
+ }
123
+ async putShade(shadeId, position, value, userValue) {
124
+ return new Promise((resolve, reject) => {
125
+ for (const queued of this.queue) {
126
+ if (queued.shadeId === shadeId && queued.data?.positions) {
127
+ const positions = {};
128
+ for (let i = 1; queued.data.positions[`posKind${i}`]; ++i) {
129
+ const kind = queued.data.positions[`posKind${i}`];
130
+ positions[kind] = queued.data.positions[`position${i}`];
131
+ }
132
+ positions[position] = value;
133
+ if (position === HubPosition.VANES && userValue) {
134
+ delete positions[HubPosition.BOTTOM];
135
+ }
136
+ else if (position === HubPosition.VANES && positions[HubPosition.BOTTOM] != null) {
137
+ delete positions[HubPosition.VANES];
138
+ }
139
+ else if (position === HubPosition.BOTTOM && userValue) {
140
+ delete positions[HubPosition.VANES];
141
+ }
142
+ else if (position === HubPosition.BOTTOM && positions[HubPosition.VANES] != null) {
143
+ delete positions[HubPosition.BOTTOM];
144
+ }
145
+ let i = 1;
146
+ queued.data.positions = {};
147
+ for (const posKind of Object.keys(positions)) {
148
+ const kind = parseInt(posKind, 10);
149
+ queued.data.positions[`posKind${i}`] = kind;
150
+ queued.data.positions[`position${i}`] = positions[kind];
151
+ ++i;
152
+ }
153
+ queued.callbacks.push((err, shade) => {
154
+ if (err) {
155
+ reject(err);
156
+ }
157
+ else if (shade) {
158
+ resolve(shade);
159
+ }
160
+ else {
161
+ reject(new Error('No shade data returned'));
162
+ }
163
+ });
164
+ return;
165
+ }
166
+ }
167
+ this.queueRequest({
168
+ shadeId,
169
+ data: {
170
+ positions: {
171
+ posKind1: position,
172
+ position1: value,
173
+ },
174
+ },
175
+ callbacks: [(err, shade) => {
176
+ if (err) {
177
+ reject(err);
178
+ }
179
+ else if (shade) {
180
+ resolve(shade);
181
+ }
182
+ else {
183
+ reject(new Error('No shade data returned'));
184
+ }
185
+ }],
186
+ });
187
+ });
188
+ }
189
+ async jogShade(shadeId) {
190
+ return new Promise((resolve, reject) => {
191
+ for (const queued of this.queue) {
192
+ if (queued.shadeId === shadeId && queued.data?.motion === 'jog') {
193
+ queued.callbacks.push((err, shade) => {
194
+ if (err) {
195
+ reject(err);
196
+ }
197
+ else if (shade) {
198
+ resolve(shade);
199
+ }
200
+ else {
201
+ reject(new Error('No shade data returned'));
202
+ }
203
+ });
204
+ return;
205
+ }
206
+ }
207
+ this.queueRequest({
208
+ shadeId,
209
+ data: { motion: 'jog' },
210
+ callbacks: [(err, shade) => {
211
+ if (err) {
212
+ reject(err);
213
+ }
214
+ else if (shade) {
215
+ resolve(shade);
216
+ }
217
+ else {
218
+ reject(new Error('No shade data returned'));
219
+ }
220
+ }],
221
+ });
222
+ });
223
+ }
224
+ }
225
+ //# sourceMappingURL=powerviewHub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"powerviewHub.js","sourceRoot":"","sources":["../src/powerviewHub.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { PlatformConfig } from 'homebridge';
2
+ /**
3
+ * Platform name users put in config.json as `"platform": "PowerView"`.
4
+ */
5
+ export declare const PLATFORM_NAME = "PowerView";
6
+ /**
7
+ * Must match package.json `name` — used when registering platform accessories.
8
+ */
9
+ export declare const PLUGIN_NAME = "homebridge-powerview-3";
10
+ export declare const SHADE_POLL_INTERVAL_MS = 30000;
11
+ export declare enum ShadeKind {
12
+ ROLLER = 1,
13
+ TOP_BOTTOM = 2,
14
+ HORIZONTAL = 3,
15
+ VERTICAL = 4
16
+ }
17
+ export declare const SHADE_TYPE_IDS: {
18
+ readonly ROLLER: readonly [1, 5, 42];
19
+ readonly TOP_BOTTOM: readonly [8];
20
+ readonly HORIZONTAL: readonly [18, 23];
21
+ readonly VERTICAL: readonly [16];
22
+ };
23
+ export declare const SUBTYPE: {
24
+ readonly BOTTOM: "bottom";
25
+ readonly TOP: "top";
26
+ };
27
+ export interface PowerViewPlatformConfig extends PlatformConfig {
28
+ host?: string;
29
+ refreshShades?: boolean;
30
+ pollShadesForUpdate?: boolean;
31
+ forceRollerShades?: number[];
32
+ forceTopBottomShades?: number[];
33
+ forceHorizontalShades?: number[];
34
+ forceVerticalShades?: number[];
35
+ }
36
+ export interface ShadeContext {
37
+ shadeId: number;
38
+ shadeType: ShadeKind;
39
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Platform name users put in config.json as `"platform": "PowerView"`.
3
+ */
4
+ export const PLATFORM_NAME = 'PowerView';
5
+ /**
6
+ * Must match package.json `name` — used when registering platform accessories.
7
+ */
8
+ export const PLUGIN_NAME = 'homebridge-powerview-3';
9
+ export const SHADE_POLL_INTERVAL_MS = 30_000;
10
+ export var ShadeKind;
11
+ (function (ShadeKind) {
12
+ ShadeKind[ShadeKind["ROLLER"] = 1] = "ROLLER";
13
+ ShadeKind[ShadeKind["TOP_BOTTOM"] = 2] = "TOP_BOTTOM";
14
+ ShadeKind[ShadeKind["HORIZONTAL"] = 3] = "HORIZONTAL";
15
+ ShadeKind[ShadeKind["VERTICAL"] = 4] = "VERTICAL";
16
+ })(ShadeKind || (ShadeKind = {}));
17
+ export const SHADE_TYPE_IDS = {
18
+ ROLLER: [1, 5, 42],
19
+ TOP_BOTTOM: [8],
20
+ HORIZONTAL: [18, 23],
21
+ VERTICAL: [16],
22
+ };
23
+ export const SUBTYPE = {
24
+ BOTTOM: 'bottom',
25
+ TOP: 'top',
26
+ };
27
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AAEzC;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAEpD,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAE7C,MAAM,CAAN,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,6CAAU,CAAA;IACV,qDAAc,CAAA;IACd,qDAAc,CAAA;IACd,iDAAY,CAAA;AACd,CAAC,EALW,SAAS,KAAT,SAAS,QAKpB;AAED,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;IAClB,UAAU,EAAE,CAAC,CAAC,CAAC;IACf,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,EAAE,CAAC;CACN,CAAC;AAEX,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,KAAK;CACF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "homebridge-powerview-3",
3
+ "displayName": "PowerView",
4
+ "type": "module",
5
+ "version": "3.0.0",
6
+ "description": "Homebridge plugin for Hunter Douglas PowerView shades (Homebridge 2 compatible)",
7
+ "license": "ISC",
8
+ "keywords": [
9
+ "homebridge-plugin"
10
+ ],
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/squircle12/homebridge-powerview-3.git"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/squircle12/homebridge-powerview-3/issues"
17
+ },
18
+ "homepage": "https://github.com/squircle12/homebridge-powerview-3#readme",
19
+ "main": "dist/index.js",
20
+ "files": [
21
+ "dist",
22
+ "config.schema.json",
23
+ "README.md",
24
+ "CHANGELOG.md"
25
+ ],
26
+ "engines": {
27
+ "node": "^22.12.0 || ^24.0.0",
28
+ "homebridge": "^1.8.0 || ^2.0.0"
29
+ },
30
+ "scripts": {
31
+ "build": "rimraf ./dist && tsc",
32
+ "lint": "eslint . --max-warnings=0",
33
+ "prepublishOnly": "npm run lint && npm run build",
34
+ "watch": "npm run build && npm link && nodemon"
35
+ },
36
+ "devDependencies": {
37
+ "@eslint/js": "^10.0.1",
38
+ "@types/node": "^22.15.0",
39
+ "eslint": "^10.3.0",
40
+ "homebridge": "^2.0.0",
41
+ "nodemon": "^3.1.14",
42
+ "rimraf": "^6.1.3",
43
+ "typescript": "^5.8.3",
44
+ "typescript-eslint": "^8.59.2"
45
+ }
46
+ }