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 +39 -0
- package/README.md +113 -0
- package/config.schema.json +57 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +37 -0
- package/dist/platform.js +246 -0
- package/dist/platform.js.map +1 -0
- package/dist/platformAccessory.d.ts +23 -0
- package/dist/platformAccessory.js +223 -0
- package/dist/platformAccessory.js.map +1 -0
- package/dist/powerviewHub.d.ts +41 -0
- package/dist/powerviewHub.js +225 -0
- package/dist/powerviewHub.js.map +1 -0
- package/dist/settings.d.ts +39 -0
- package/dist/settings.js +27 -0
- package/dist/settings.js.map +1 -0
- package/package.json +46 -0
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
|
+
[](https://www.npmjs.com/package/homebridge-powerview-3)
|
|
4
|
+
[](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
|
+
}
|
package/dist/index.d.ts
ADDED
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
|
+
}
|
package/dist/platform.js
ADDED
|
@@ -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":"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"}
|
|
@@ -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
|
+
}
|
package/dist/settings.js
ADDED
|
@@ -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
|
+
}
|