@akospasztor/homebridge-create-ceiling-fan 1.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 +5 -0
- package/LICENSE +176 -0
- package/README.md +151 -0
- package/config.schema.json +55 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/mutex.d.ts +61 -0
- package/dist/mutex.js +96 -0
- package/dist/mutex.js.map +1 -0
- package/dist/platform.d.ts +48 -0
- package/dist/platform.js +108 -0
- package/dist/platform.js.map +1 -0
- package/dist/platformAccessory.d.ts +309 -0
- package/dist/platformAccessory.js +542 -0
- package/dist/platformAccessory.js.map +1 -0
- package/dist/settings.d.ts +8 -0
- package/dist/settings.js +9 -0
- package/dist/settings.js.map +1 -0
- package/docs/fan-speed-slider.gif +0 -0
- package/docs/homebridge-create-logo.png +0 -0
- package/package.json +60 -0
package/dist/platform.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { CreateCeilingFanAccessory } from './platformAccessory.js';
|
|
2
|
+
import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js';
|
|
3
|
+
/**
|
|
4
|
+
* CreateCeilingFanPlatform: the platform implementation for CREATE ceiling fans.
|
|
5
|
+
*
|
|
6
|
+
* This class contains the platform implementation and follows the Homebridge
|
|
7
|
+
* plugin development recommendations.
|
|
8
|
+
*
|
|
9
|
+
* @see https://developers.homebridge.io/#/
|
|
10
|
+
* @see https://github.com/homebridge/homebridge-plugin-template/blob/latest/README.md
|
|
11
|
+
*/
|
|
12
|
+
export class CreateCeilingFanPlatform {
|
|
13
|
+
log;
|
|
14
|
+
config;
|
|
15
|
+
api;
|
|
16
|
+
/** The HomeKit Accessory Protocol (HAP) service. */
|
|
17
|
+
Service;
|
|
18
|
+
/** The HomeKit Accessory Protocol (HAP) characteristic. */
|
|
19
|
+
Characteristic;
|
|
20
|
+
/** Used for tracking the restored cached accessories. */
|
|
21
|
+
accessories = new Map();
|
|
22
|
+
/** Used for tracking the cached UUIDs. */
|
|
23
|
+
discoveredCacheUUIDs = [];
|
|
24
|
+
/**
|
|
25
|
+
* The CreateCeilingFanPlatform constructor.
|
|
26
|
+
*
|
|
27
|
+
* Note: This constructor is called by Homebridge.
|
|
28
|
+
*
|
|
29
|
+
* @param log The logging object.
|
|
30
|
+
* @param config The platform configuration object.
|
|
31
|
+
* @param api The API object.
|
|
32
|
+
*/
|
|
33
|
+
constructor(log, config, api) {
|
|
34
|
+
this.log = log;
|
|
35
|
+
this.config = config;
|
|
36
|
+
this.api = api;
|
|
37
|
+
this.Service = api.hap.Service;
|
|
38
|
+
this.Characteristic = api.hap.Characteristic;
|
|
39
|
+
// When this event is fired, it means Homebridge has restored all cached
|
|
40
|
+
// accessories from the disk. Dynamic Platform plugins should only register
|
|
41
|
+
// new accessories after this event was fired, in order to ensure they
|
|
42
|
+
// weren't added to Homebridge already. This event can also be used to
|
|
43
|
+
// start discovery of new accessories.
|
|
44
|
+
this.api.on('didFinishLaunching', () => {
|
|
45
|
+
this.discoverDevices();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* This function is invoked when Homebridge restores cached accessories from
|
|
50
|
+
* the disk at startup. It should be used to set up event handlers for
|
|
51
|
+
* characteristics and update respective values.
|
|
52
|
+
*
|
|
53
|
+
* @param accessory The accessory restored from the disk at startup.
|
|
54
|
+
*/
|
|
55
|
+
configureAccessory(accessory) {
|
|
56
|
+
this.log.info('Loading accessory from cache:', accessory.displayName);
|
|
57
|
+
// Add the restored accessory to the accessories cache to track if it has
|
|
58
|
+
// already been registered
|
|
59
|
+
this.accessories.set(accessory.UUID, accessory);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Register discovered accessories.
|
|
63
|
+
*
|
|
64
|
+
* Accessories must only be registered once, previously created accessories
|
|
65
|
+
* must not be registered again to prevent "duplicate UUID" errors.
|
|
66
|
+
*/
|
|
67
|
+
discoverDevices() {
|
|
68
|
+
// Loop over the devices and register each one if it has not already been registered
|
|
69
|
+
for (const device of this.config.devices) {
|
|
70
|
+
// Generate a unique id for the accessory
|
|
71
|
+
// Note: this should be generated from something globally unique, but
|
|
72
|
+
// constant, for example, the device serial number or MAC address
|
|
73
|
+
const uuid = this.api.hap.uuid.generate(device.id);
|
|
74
|
+
// See if an accessory with the same uuid has already been registered and restored
|
|
75
|
+
// from the cached devices we stored in the `configureAccessory` method above
|
|
76
|
+
const existingAccessory = this.accessories.get(uuid);
|
|
77
|
+
if (existingAccessory) {
|
|
78
|
+
this.log.info('Restoring existing accessory from cache: %s (device id: %s)', existingAccessory.displayName, existingAccessory.context.device.id);
|
|
79
|
+
// Update the `accessory.context` in case the plugin configuration (in the config.json) has changed
|
|
80
|
+
existingAccessory.context.device = device;
|
|
81
|
+
this.api.updatePlatformAccessories([existingAccessory]);
|
|
82
|
+
// Create the accessory handler for the restored accessory
|
|
83
|
+
new CreateCeilingFanAccessory(this, existingAccessory);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.log.info('Adding new accessory: %s (device id: %s)', device.name, device.id);
|
|
87
|
+
// Create a new accessory
|
|
88
|
+
const accessory = new this.api.platformAccessory(device.name, uuid);
|
|
89
|
+
// Store a copy of the device object in the `accessory.context`
|
|
90
|
+
accessory.context.device = device;
|
|
91
|
+
// Create the accessory handler for the newly created accessory
|
|
92
|
+
new CreateCeilingFanAccessory(this, accessory);
|
|
93
|
+
// Link the accessory to the platform
|
|
94
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
95
|
+
}
|
|
96
|
+
// Push into discoveredCacheUUIDs
|
|
97
|
+
this.discoveredCacheUUIDs.push(uuid);
|
|
98
|
+
}
|
|
99
|
+
// Remove existing cached accessories from Homebridge if they are no longer present
|
|
100
|
+
for (const [uuid, accessory] of this.accessories) {
|
|
101
|
+
if (!this.discoveredCacheUUIDs.includes(uuid)) {
|
|
102
|
+
this.log.info('Removing existing accessory from cache: %s (device id: %s)', accessory.displayName, accessory.context.device.id);
|
|
103
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# 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,309 @@
|
|
|
1
|
+
import type { CharacteristicValue, PlatformAccessory } from 'homebridge';
|
|
2
|
+
import type { CreateCeilingFanPlatform } from './platform.js';
|
|
3
|
+
/**
|
|
4
|
+
* CreateCeilingFanAccessory: the accessory implementation for CREATE ceiling fans.
|
|
5
|
+
*
|
|
6
|
+
* This class contains the accessory implementation and follows the Homebridge
|
|
7
|
+
* plugin development recommendations.
|
|
8
|
+
*
|
|
9
|
+
* #### Exposed services and characteristics
|
|
10
|
+
*
|
|
11
|
+
* | Service | Characteristics |
|
|
12
|
+
* | ------------| ------------------------------------------------ |
|
|
13
|
+
* | `Fanv2` | `Active`, `Rotation Direction`, `Rotation Speed` |
|
|
14
|
+
* | `Lightbulb` | `On` |
|
|
15
|
+
*
|
|
16
|
+
* Note: the `Lightbulb` service is only exposed if the accessory has been
|
|
17
|
+
* configured with the light option enabled.
|
|
18
|
+
*
|
|
19
|
+
* #### Fan rotation speed representation
|
|
20
|
+
*
|
|
21
|
+
* CREATE fans have speed settings ranging from `1` (lowest) to `6` (highest).
|
|
22
|
+
* The HomeKit UI slider for the fan rotation speed provides a value from `1`
|
|
23
|
+
* to `100` and `0` means the fan is turned off. The slider steps can be
|
|
24
|
+
* configured to a desired value via the `Min Step` Characteristic. This works
|
|
25
|
+
* well e.g. for Dyson devices where the speed settings ranges from `1` to `10`.
|
|
26
|
+
* In this case the `Min Step` Characteristic can be configured to `10`,
|
|
27
|
+
* resulting in a nice user experience where the `0` - `100` UI slider is
|
|
28
|
+
* divided into 10 steps. However, this does not work well for CREATE fans with
|
|
29
|
+
* 6 speed steps. In order to provide smooth user experience, the following
|
|
30
|
+
* representation is implemented:
|
|
31
|
+
*
|
|
32
|
+
* - The UI slider is configured with the default `Min Step` Characteristic of
|
|
33
|
+
* `1`. This provides smooth and fluid user input and slider operation.
|
|
34
|
+
* - The following UI slider inputs represent the different speed settings of
|
|
35
|
+
* the fan:
|
|
36
|
+
* | Device fan speed | Corresponding UI slider value | User input range on the slider |
|
|
37
|
+
* | :--------------: | :---------------------------: | :----------------------------: |
|
|
38
|
+
* | 1 | 10 | 1 - 19 |
|
|
39
|
+
* | 2 | 30 | 20 - 39 |
|
|
40
|
+
* | 3 | 50 | 40 - 59 |
|
|
41
|
+
* | 4 | 70 | 60 - 79 |
|
|
42
|
+
* | 5 | 90 | 80 - 94 |
|
|
43
|
+
* | 6 | 100 | 95 - 100 |
|
|
44
|
+
*
|
|
45
|
+
* - When the user operates the slider, a debouncing timer with the value of
|
|
46
|
+
* {@link fanSetSpeedDebouncePeriod} member is set. When the timer fires, the
|
|
47
|
+
* current state of the slider value is converted to the nearest value that
|
|
48
|
+
* corresponds to the device fan speed. The purpose of the debounce timer is
|
|
49
|
+
* to provide great user experience. Without the debounce timer, every moment
|
|
50
|
+
* the user slides the finger would result in generating lots of events -
|
|
51
|
+
* making the slider jump around immediately, without waiting for the user to
|
|
52
|
+
* finish adjusting the speed.
|
|
53
|
+
*
|
|
54
|
+
* ```text
|
|
55
|
+
* UI slider │ Fan speed
|
|
56
|
+
* input value │ value
|
|
57
|
+
* ─────────────┼──────────────
|
|
58
|
+
* ┌──────┐ │
|
|
59
|
+
* │ 100 ─┼─────┼─► Fan speed 6
|
|
60
|
+
* │ │ ▲ │
|
|
61
|
+
* │ 95 ├─┘ │
|
|
62
|
+
* │ 94 ├─┐ │
|
|
63
|
+
* │ │ ▼ │
|
|
64
|
+
* │ 90 ─┼─────┼─► Fan speed 5
|
|
65
|
+
* │ │ ▲ │
|
|
66
|
+
* │ 80 ├─┘ │
|
|
67
|
+
* │ 79 ├─┐ │
|
|
68
|
+
* │ │ ▼ │
|
|
69
|
+
* │ 70 ─┼─────┼─► Fan speed 4
|
|
70
|
+
* │ │ ▲ │
|
|
71
|
+
* │ 60 ├─┘ │
|
|
72
|
+
* │ 59 ├─┐ │
|
|
73
|
+
* │ │ ▼ │
|
|
74
|
+
* │ 50 ─┼─────┼─► Fan speed 3
|
|
75
|
+
* │ │ ▲ │
|
|
76
|
+
* │ 40 ├─┘ │
|
|
77
|
+
* │ 39 ├─┐ │
|
|
78
|
+
* │ │ ▼ │
|
|
79
|
+
* │ 30 ─┼─────┼─► Fan speed 2
|
|
80
|
+
* │ │ ▲ │
|
|
81
|
+
* │ 20 ├─┘ │
|
|
82
|
+
* │ 19 ├─┐ │
|
|
83
|
+
* │ │ ▼ │
|
|
84
|
+
* │ 10 ─┼─────┼─► Fan speed 1
|
|
85
|
+
* │ │ ▲ │
|
|
86
|
+
* │ 1 ├─┘ │
|
|
87
|
+
* │ 0 ─┼─────┼─► Fan off
|
|
88
|
+
* └──────┘ │
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* #### Fan rotation direction representation
|
|
92
|
+
*
|
|
93
|
+
* The rotation of the device as seen from standing below the fan follows the
|
|
94
|
+
* HomeKit rotation representation.
|
|
95
|
+
*
|
|
96
|
+
* | Device direction raw value | HomeKit representation | Fan operation |
|
|
97
|
+
* | -------------------------- | ---------------------- | --------------------------------------- |
|
|
98
|
+
* | `forward` (default) | Counter-clockwise | Fan blows downwards (i.e. summer mode) |
|
|
99
|
+
* | `reverse` | Clockwise | Fan blows upwards (i.e. winter mode) |
|
|
100
|
+
*
|
|
101
|
+
* #### Device communication
|
|
102
|
+
*
|
|
103
|
+
* The fan is a Tuya-compatible device and its firmware is mildly put: not the best.
|
|
104
|
+
* Among other issues, devices with these firmware are known to stop responding
|
|
105
|
+
* to commands, randomly drop connection, etc (see e.g.
|
|
106
|
+
* https://github.com/jasonacox/tinytuya/discussions/443 and
|
|
107
|
+
* https://github.com/moifort/homebridge-create-fan/issues/18).
|
|
108
|
+
*
|
|
109
|
+
* To provide reliable operation via HomeKit, this plugin implements the device
|
|
110
|
+
* communication the following way:
|
|
111
|
+
*
|
|
112
|
+
* - The device accepts one connection at a time. Therefore, a mutex with a
|
|
113
|
+
* waiting queue is used for ensuring that only one command is sent to the
|
|
114
|
+
* device at a time. For detailed description refer to: {@link Mutex}.
|
|
115
|
+
* - The device state is cached. Whenever the device state is requested by
|
|
116
|
+
* HomeKit (e.g. the user opens up the Home app), the implementation
|
|
117
|
+
* immediately returns the requested value from the cache.
|
|
118
|
+
* - The status of the device is periodically (defined by
|
|
119
|
+
* {@link getDeviceStatusPeriod}) queried from the device. After obtaining the
|
|
120
|
+
* device status, the device state cache as well as the HomeKit
|
|
121
|
+
* Characteristics are automatically updated.
|
|
122
|
+
* - If the device fails to respond to the get status request, the polling
|
|
123
|
+
* period is reduced significantly (defined by
|
|
124
|
+
* {@link getDeviceStatusFastRetryPeriod}), so that the attempt is retried
|
|
125
|
+
* quickly.
|
|
126
|
+
* - The communication with the device happens in a synchronous way, supported
|
|
127
|
+
* by the mutex queue and timeout mechanism. This seems to provide the most
|
|
128
|
+
* reliable communication with the device.
|
|
129
|
+
*
|
|
130
|
+
* Communication failure tends to happen when attempting to control the device
|
|
131
|
+
* via HomeKit right after using the device's physical remote. The device used
|
|
132
|
+
* for development & testing (CREATE Wind Calm model purchased in 2025) seemed
|
|
133
|
+
* to always recover from a failed communication latest after a few retry
|
|
134
|
+
* attempts.
|
|
135
|
+
*
|
|
136
|
+
* @see https://developers.homebridge.io/#/
|
|
137
|
+
* @see [Fanv2 service type](https://developers.homebridge.io/#/service/Fanv2)
|
|
138
|
+
* @see [Lightbulb service type](https://developers.homebridge.io/#/service/Lightbulb)
|
|
139
|
+
*/
|
|
140
|
+
export declare class CreateCeilingFanAccessory {
|
|
141
|
+
private readonly platform;
|
|
142
|
+
private readonly accessory;
|
|
143
|
+
private fanService;
|
|
144
|
+
private lightService;
|
|
145
|
+
private getDeviceStatusTimer;
|
|
146
|
+
private fanSetSpeedDebounceTimer;
|
|
147
|
+
private deviceCommunicator;
|
|
148
|
+
private mutex;
|
|
149
|
+
private isGetStatusInProgress;
|
|
150
|
+
private readonly fanSetSpeedDebouncePeriod;
|
|
151
|
+
private readonly getDeviceStatusFastRetryPeriod;
|
|
152
|
+
private readonly getDeviceStatusPeriod;
|
|
153
|
+
private readonly getDeviceStatusConnectTimeout;
|
|
154
|
+
private readonly getDeviceStatusReadTimeout;
|
|
155
|
+
private readonly fanRotationSpeedNormalized;
|
|
156
|
+
private state;
|
|
157
|
+
/**
|
|
158
|
+
* Constructor for the CreateCeilingFanAccessory object.
|
|
159
|
+
*
|
|
160
|
+
* @param platform The plugin platform object.
|
|
161
|
+
* @param accessory The homebridge platform accessory object.
|
|
162
|
+
*/
|
|
163
|
+
constructor(platform: CreateCeilingFanPlatform, accessory: PlatformAccessory);
|
|
164
|
+
/**
|
|
165
|
+
* Handle the get requests from HomeKit to get the current value of the Fanv2 Active characteristic
|
|
166
|
+
*
|
|
167
|
+
* @return The Fanv2 Active characteristic value from the device state cache.
|
|
168
|
+
*/
|
|
169
|
+
handleFanActiveStateGet(): Promise<CharacteristicValue>;
|
|
170
|
+
/**
|
|
171
|
+
* Handle the set requests from HomeKit to set the device with the Fanv2 Active characteristic value
|
|
172
|
+
*
|
|
173
|
+
* @param value The Fanv2 Active characteristic value to be set.
|
|
174
|
+
*/
|
|
175
|
+
handleFanActiveStateSet(value: CharacteristicValue): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Handle the get requests from HomeKit to get the current value of the Fanv2 Rotation Speed characteristic
|
|
178
|
+
*
|
|
179
|
+
* @return The Fanv2 Rotation Speed characteristic value from the device state cache.
|
|
180
|
+
*/
|
|
181
|
+
handleFanRotationSpeedGet(): Promise<CharacteristicValue>;
|
|
182
|
+
/**
|
|
183
|
+
* Handle the set requests from HomeKit to set the device with the Fanv2 Rotation Speed characteristic value
|
|
184
|
+
*
|
|
185
|
+
* @param value The Fanv2 Rotation Speed characteristic value to be set.
|
|
186
|
+
*/
|
|
187
|
+
handleFanRotationSpeedSet(value: CharacteristicValue): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* Handle the get requests from HomeKit to get the current value of the Fanv2 Rotation Direction characteristic
|
|
190
|
+
*
|
|
191
|
+
* @return The Fanv2 Rotation Direction characteristic value from the device state cache.
|
|
192
|
+
*/
|
|
193
|
+
handleFanRotationDirectionGet(): Promise<CharacteristicValue>;
|
|
194
|
+
/**
|
|
195
|
+
* Handle the set requests from HomeKit to set the device with the Fanv2 Rotation Direction characteristic value
|
|
196
|
+
*
|
|
197
|
+
* @param value The Fanv2 Rotation Direction characteristic value to be set.
|
|
198
|
+
*/
|
|
199
|
+
handleFanRotationDirectionSet(value: CharacteristicValue): Promise<void>;
|
|
200
|
+
/**
|
|
201
|
+
* Handle the get requests from HomeKit to get the current value of the Lightbulb On characteristic
|
|
202
|
+
*
|
|
203
|
+
* @return The Lightbulb On characteristic value from the device state cache.
|
|
204
|
+
*/
|
|
205
|
+
handleLightOnGet(): Promise<CharacteristicValue>;
|
|
206
|
+
/**
|
|
207
|
+
* Handle the set requests from HomeKit to set the device with the Lightbulb On characteristic value
|
|
208
|
+
*
|
|
209
|
+
* @param value The Lightbulb On characteristic value to be set.
|
|
210
|
+
*/
|
|
211
|
+
handleLightOnSet(value: CharacteristicValue): Promise<void>;
|
|
212
|
+
/**
|
|
213
|
+
* Get device status.
|
|
214
|
+
*
|
|
215
|
+
* This method reads the status of the device periodically and updates the
|
|
216
|
+
* accessory state after completing the operation. The actual communication
|
|
217
|
+
* is carried out with a timeout mechanism, so that an unresponsive device
|
|
218
|
+
* will not make the plugin and HomeKit unresponsive. If the communication
|
|
219
|
+
* fails, the periodic timer will be set with a shorter timeout so that the
|
|
220
|
+
* next retry attempt happens fast. After the communication with the device
|
|
221
|
+
* is recovered, the period will be reset to the original period value.
|
|
222
|
+
*
|
|
223
|
+
* The function can be called in two ways:
|
|
224
|
+
*
|
|
225
|
+
* 1. Calling it with `await`: the method starts the reading operation and
|
|
226
|
+
* waits (i.e. blocks) until the reading has been completed (or timed out).
|
|
227
|
+
* 2. Simply calling it (without `await`): the method starts the reading
|
|
228
|
+
* operation and returns right afterwards, not waiting for the reading
|
|
229
|
+
* to be completed. This is used when handling accessory GET requests
|
|
230
|
+
* from HomeKit. Get requests should return as fast as possible, because
|
|
231
|
+
* long delays will result in HomeKit being unresponsive and a bad user
|
|
232
|
+
* experience in general.
|
|
233
|
+
*
|
|
234
|
+
* If the function is called again while there is already an ongoing read
|
|
235
|
+
* operation, the reading will simply be skipped - the accessory status will
|
|
236
|
+
* be updated anyway after executing the already ongoing reading operation.
|
|
237
|
+
* This can happen e.g. when a periodic read operation is already in place
|
|
238
|
+
* and a GET request arrives from HomeKit at the same time.
|
|
239
|
+
*/
|
|
240
|
+
private getDeviceStatus;
|
|
241
|
+
/**
|
|
242
|
+
* Set device value.
|
|
243
|
+
*
|
|
244
|
+
* This method sends a command to the device to set the device into the
|
|
245
|
+
* required state. Only one parameter can be set at a time.
|
|
246
|
+
*
|
|
247
|
+
* @param dps The data point index of the device to be set.
|
|
248
|
+
* @param value The value to be set.
|
|
249
|
+
*/
|
|
250
|
+
private setDeviceValue;
|
|
251
|
+
/**
|
|
252
|
+
* Wait for a promise to be resolved within a given timeout.
|
|
253
|
+
*
|
|
254
|
+
* @param promise The promise to be resolved within a given timeout.
|
|
255
|
+
* @param ms The timeout in [ms] within the promise should be resolved.
|
|
256
|
+
* @return The resolved promise if it gets resolved within the timeout, otherwise reject the promise.
|
|
257
|
+
*/
|
|
258
|
+
private waitForPromiseWithTimeout;
|
|
259
|
+
/**
|
|
260
|
+
* Throw a HomeKit No Response status if the accessory state is invalid.
|
|
261
|
+
*/
|
|
262
|
+
private throwErrorIfDeviceUnresponsive;
|
|
263
|
+
/**
|
|
264
|
+
* Update the accessory state with the values received from the device.
|
|
265
|
+
*
|
|
266
|
+
* @param status The raw data points object received from the device.
|
|
267
|
+
*/
|
|
268
|
+
private updateDeviceState;
|
|
269
|
+
/**
|
|
270
|
+
* Update all accessory service characteristics based on the accessory state.
|
|
271
|
+
*/
|
|
272
|
+
private updateAccessoryState;
|
|
273
|
+
/**
|
|
274
|
+
* Convert the fan active state of the accessory to Fanv2 Active characteristic value.
|
|
275
|
+
*
|
|
276
|
+
* @return The Fanv2 Active characteristic value.
|
|
277
|
+
*/
|
|
278
|
+
private fanActiveValueToCharacteristicValue;
|
|
279
|
+
/**
|
|
280
|
+
* Convert the fan rotation speed of the accessory to Fanv2 Rotation Speed characteristic value.
|
|
281
|
+
*
|
|
282
|
+
* @return The Fanv2 Rotation Speed characteristic value.
|
|
283
|
+
*/
|
|
284
|
+
private fanRotationSpeedValueToCharacteristicValue;
|
|
285
|
+
/**
|
|
286
|
+
* Convert the fan rotation direction of the accessory to Fanv2 Rotation Direction characteristic value.
|
|
287
|
+
*
|
|
288
|
+
* @return The Fanv2 Rotation Direction characteristic value.
|
|
289
|
+
*/
|
|
290
|
+
private fanRotationDirectionValueToCharacteristicValue;
|
|
291
|
+
/**
|
|
292
|
+
* Convert the light on state of the accessory to Lightbulb On characteristic value.
|
|
293
|
+
*
|
|
294
|
+
* @return The Lightbulb On characteristic value.
|
|
295
|
+
*/
|
|
296
|
+
private lightOnValueToCharacteristicValue;
|
|
297
|
+
/**
|
|
298
|
+
* Adjust the rotation speed input value.
|
|
299
|
+
*
|
|
300
|
+
* This method is used for converting the input state of the slider value to
|
|
301
|
+
* the nearest value that corresponds to the device fan speed.
|
|
302
|
+
*
|
|
303
|
+
* See the {@link CreateCeilingFanAccessory} class description for more details.
|
|
304
|
+
*
|
|
305
|
+
* @param value The input value of the rotation speed.
|
|
306
|
+
* @return The adjusted value of the rotation speed.
|
|
307
|
+
*/
|
|
308
|
+
private adjustInputRotationSpeed;
|
|
309
|
+
}
|