@ecobridge.xyz/devicemanager 3.0.2
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/.gitea/workflows/default_nottags.yaml +66 -0
- package/.gitea/workflows/default_tags.yaml +124 -0
- package/.vscode/launch.json +11 -0
- package/.vscode/settings.json +26 -0
- package/changelog.md +91 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/device/device.classes.device.d.ts +205 -0
- package/dist_ts/device/device.classes.device.js +344 -0
- package/dist_ts/devicemanager.classes.devicemanager.d.ts +210 -0
- package/dist_ts/devicemanager.classes.devicemanager.js +835 -0
- package/dist_ts/discovery/discovery.classes.homeassistant.d.ts +101 -0
- package/dist_ts/discovery/discovery.classes.homeassistant.js +313 -0
- package/dist_ts/discovery/discovery.classes.mdns.d.ts +90 -0
- package/dist_ts/discovery/discovery.classes.mdns.js +291 -0
- package/dist_ts/discovery/discovery.classes.networkscanner.d.ts +64 -0
- package/dist_ts/discovery/discovery.classes.networkscanner.js +535 -0
- package/dist_ts/discovery/discovery.classes.ssdp.d.ts +112 -0
- package/dist_ts/discovery/discovery.classes.ssdp.js +255 -0
- package/dist_ts/factories/index.d.ts +190 -0
- package/dist_ts/factories/index.js +350 -0
- package/dist_ts/features/feature.abstract.d.ts +118 -0
- package/dist_ts/features/feature.abstract.js +172 -0
- package/dist_ts/features/feature.camera.d.ts +95 -0
- package/dist_ts/features/feature.camera.js +162 -0
- package/dist_ts/features/feature.climate.d.ts +174 -0
- package/dist_ts/features/feature.climate.js +328 -0
- package/dist_ts/features/feature.cover.d.ts +121 -0
- package/dist_ts/features/feature.cover.js +217 -0
- package/dist_ts/features/feature.fan.d.ts +127 -0
- package/dist_ts/features/feature.fan.js +235 -0
- package/dist_ts/features/feature.light.d.ts +156 -0
- package/dist_ts/features/feature.light.js +296 -0
- package/dist_ts/features/feature.lock.d.ts +103 -0
- package/dist_ts/features/feature.lock.js +170 -0
- package/dist_ts/features/feature.playback.d.ts +98 -0
- package/dist_ts/features/feature.playback.js +191 -0
- package/dist_ts/features/feature.power.d.ts +79 -0
- package/dist_ts/features/feature.power.js +173 -0
- package/dist_ts/features/feature.print.d.ts +78 -0
- package/dist_ts/features/feature.print.js +226 -0
- package/dist_ts/features/feature.scan.d.ts +79 -0
- package/dist_ts/features/feature.scan.js +315 -0
- package/dist_ts/features/feature.sensor.d.ts +95 -0
- package/dist_ts/features/feature.sensor.js +147 -0
- package/dist_ts/features/feature.snmp.d.ts +88 -0
- package/dist_ts/features/feature.snmp.js +175 -0
- package/dist_ts/features/feature.switch.d.ts +75 -0
- package/dist_ts/features/feature.switch.js +126 -0
- package/dist_ts/features/feature.volume.d.ts +104 -0
- package/dist_ts/features/feature.volume.js +186 -0
- package/dist_ts/features/index.d.ts +19 -0
- package/dist_ts/features/index.js +23 -0
- package/dist_ts/helpers/helpers.iprange.d.ts +35 -0
- package/dist_ts/helpers/helpers.iprange.js +151 -0
- package/dist_ts/helpers/helpers.retry.d.ts +25 -0
- package/dist_ts/helpers/helpers.retry.js +69 -0
- package/dist_ts/index.d.ts +15 -0
- package/dist_ts/index.js +40 -0
- package/dist_ts/interfaces/feature.interfaces.d.ts +255 -0
- package/dist_ts/interfaces/feature.interfaces.js +6 -0
- package/dist_ts/interfaces/homeassistant.interfaces.d.ts +550 -0
- package/dist_ts/interfaces/homeassistant.interfaces.js +111 -0
- package/dist_ts/interfaces/index.d.ts +330 -0
- package/dist_ts/interfaces/index.js +16 -0
- package/dist_ts/interfaces/smarthome.interfaces.d.ts +282 -0
- package/dist_ts/interfaces/smarthome.interfaces.js +7 -0
- package/dist_ts/paths.d.ts +1 -0
- package/dist_ts/paths.js +3 -0
- package/dist_ts/plugins.d.ts +23 -0
- package/dist_ts/plugins.js +30 -0
- package/dist_ts/protocols/index.d.ts +12 -0
- package/dist_ts/protocols/index.js +21 -0
- package/dist_ts/protocols/protocol.escl.d.ts +58 -0
- package/dist_ts/protocols/protocol.escl.js +364 -0
- package/dist_ts/protocols/protocol.homeassistant.d.ts +248 -0
- package/dist_ts/protocols/protocol.homeassistant.js +611 -0
- package/dist_ts/protocols/protocol.ipp.d.ts +45 -0
- package/dist_ts/protocols/protocol.ipp.js +284 -0
- package/dist_ts/protocols/protocol.nut.d.ts +160 -0
- package/dist_ts/protocols/protocol.nut.js +364 -0
- package/dist_ts/protocols/protocol.sane.d.ts +104 -0
- package/dist_ts/protocols/protocol.sane.js +597 -0
- package/dist_ts/protocols/protocol.snmp.d.ts +133 -0
- package/dist_ts/protocols/protocol.snmp.js +333 -0
- package/dist_ts/protocols/protocol.upnp.d.ts +207 -0
- package/dist_ts/protocols/protocol.upnp.js +442 -0
- package/dist_ts/protocols/protocol.upssnmp.d.ts +160 -0
- package/dist_ts/protocols/protocol.upssnmp.js +263 -0
- package/npmextra.json +24 -0
- package/package.json +39 -0
- package/readme.hints.md +115 -0
- package/readme.md +624 -0
- package/test/test.ts +261 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/device/device.classes.device.ts +454 -0
- package/ts/devicemanager.classes.devicemanager.ts +1219 -0
- package/ts/discovery/discovery.classes.homeassistant.ts +376 -0
- package/ts/discovery/discovery.classes.mdns.ts +347 -0
- package/ts/discovery/discovery.classes.networkscanner.ts +648 -0
- package/ts/discovery/discovery.classes.ssdp.ts +357 -0
- package/ts/factories/index.ts +696 -0
- package/ts/features/feature.abstract.ts +251 -0
- package/ts/features/feature.camera.ts +214 -0
- package/ts/features/feature.climate.ts +407 -0
- package/ts/features/feature.cover.ts +278 -0
- package/ts/features/feature.fan.ts +296 -0
- package/ts/features/feature.light.ts +369 -0
- package/ts/features/feature.lock.ts +223 -0
- package/ts/features/feature.playback.ts +246 -0
- package/ts/features/feature.power.ts +231 -0
- package/ts/features/feature.print.ts +297 -0
- package/ts/features/feature.scan.ts +370 -0
- package/ts/features/feature.sensor.ts +202 -0
- package/ts/features/feature.snmp.ts +235 -0
- package/ts/features/feature.switch.ts +170 -0
- package/ts/features/feature.volume.ts +256 -0
- package/ts/features/index.ts +25 -0
- package/ts/helpers/helpers.iprange.ts +172 -0
- package/ts/helpers/helpers.retry.ts +100 -0
- package/ts/index.ts +165 -0
- package/ts/interfaces/feature.interfaces.ts +359 -0
- package/ts/interfaces/homeassistant.interfaces.ts +666 -0
- package/ts/interfaces/index.ts +421 -0
- package/ts/interfaces/smarthome.interfaces.ts +421 -0
- package/ts/paths.ts +5 -0
- package/ts/plugins.ts +41 -0
- package/ts/protocols/index.ts +59 -0
- package/ts/protocols/protocol.escl.ts +439 -0
- package/ts/protocols/protocol.homeassistant.ts +737 -0
- package/ts/protocols/protocol.ipp.ts +329 -0
- package/ts/protocols/protocol.nut.ts +471 -0
- package/ts/protocols/protocol.sane.ts +694 -0
- package/ts/protocols/protocol.snmp.ts +439 -0
- package/ts/protocols/protocol.upnp.ts +627 -0
- package/ts/protocols/protocol.upssnmp.ts +377 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fan Feature
|
|
3
|
+
* Provides control for fans (speed, oscillation, direction)
|
|
4
|
+
*/
|
|
5
|
+
import { Feature, type TDeviceReference } from './feature.abstract.js';
|
|
6
|
+
import type { IFeatureOptions } from '../interfaces/feature.interfaces.js';
|
|
7
|
+
import type { TFanProtocol, TFanDirection, IFanCapabilities, IFanState, IFanFeatureInfo, IFanProtocolClient } from '../interfaces/smarthome.interfaces.js';
|
|
8
|
+
/**
|
|
9
|
+
* Options for creating a FanFeature
|
|
10
|
+
*/
|
|
11
|
+
export interface IFanFeatureOptions extends IFeatureOptions {
|
|
12
|
+
/** Protocol type */
|
|
13
|
+
protocol: TFanProtocol;
|
|
14
|
+
/** Entity ID (for Home Assistant) */
|
|
15
|
+
entityId: string;
|
|
16
|
+
/** Protocol client for controlling the fan */
|
|
17
|
+
protocolClient: IFanProtocolClient;
|
|
18
|
+
/** Fan capabilities */
|
|
19
|
+
capabilities?: Partial<IFanCapabilities>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Fan Feature - speed, oscillation, and direction control
|
|
23
|
+
*
|
|
24
|
+
* Protocol-agnostic: works with Home Assistant, MQTT, Bond, etc.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const fan = device.getFeature<FanFeature>('fan');
|
|
29
|
+
* if (fan) {
|
|
30
|
+
* await fan.turnOn(75); // 75% speed
|
|
31
|
+
* await fan.setOscillating(true);
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class FanFeature extends Feature {
|
|
36
|
+
readonly type: "fan";
|
|
37
|
+
readonly protocol: TFanProtocol;
|
|
38
|
+
/** Entity ID (e.g., "fan.bedroom") */
|
|
39
|
+
readonly entityId: string;
|
|
40
|
+
/** Capabilities */
|
|
41
|
+
readonly capabilities: IFanCapabilities;
|
|
42
|
+
/** Current state */
|
|
43
|
+
protected _isOn: boolean;
|
|
44
|
+
protected _percentage?: number;
|
|
45
|
+
protected _presetMode?: string;
|
|
46
|
+
protected _oscillating?: boolean;
|
|
47
|
+
protected _direction?: TFanDirection;
|
|
48
|
+
/** Protocol client for controlling the fan */
|
|
49
|
+
private protocolClient;
|
|
50
|
+
constructor(device: TDeviceReference, port: number, options: IFanFeatureOptions);
|
|
51
|
+
/**
|
|
52
|
+
* Get current on/off state (cached)
|
|
53
|
+
*/
|
|
54
|
+
get isOn(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Get current speed percentage 0-100 (cached)
|
|
57
|
+
*/
|
|
58
|
+
get percentage(): number | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Get current preset mode (cached)
|
|
61
|
+
*/
|
|
62
|
+
get presetMode(): string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Get oscillating state (cached)
|
|
65
|
+
*/
|
|
66
|
+
get oscillating(): boolean | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Get direction (cached)
|
|
69
|
+
*/
|
|
70
|
+
get direction(): TFanDirection | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Get available preset modes
|
|
73
|
+
*/
|
|
74
|
+
get presetModes(): string[] | undefined;
|
|
75
|
+
protected doConnect(): Promise<void>;
|
|
76
|
+
protected doDisconnect(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Turn on the fan
|
|
79
|
+
* @param percentage Optional speed percentage
|
|
80
|
+
*/
|
|
81
|
+
turnOn(percentage?: number): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Turn off the fan
|
|
84
|
+
*/
|
|
85
|
+
turnOff(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Toggle the fan
|
|
88
|
+
*/
|
|
89
|
+
toggle(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Set speed percentage
|
|
92
|
+
* @param percentage Speed 0-100
|
|
93
|
+
*/
|
|
94
|
+
setPercentage(percentage: number): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Set preset mode
|
|
97
|
+
* @param mode Preset mode name
|
|
98
|
+
*/
|
|
99
|
+
setPresetMode(mode: string): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Set oscillating state
|
|
102
|
+
* @param oscillating Whether to oscillate
|
|
103
|
+
*/
|
|
104
|
+
setOscillating(oscillating: boolean): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Set direction
|
|
107
|
+
* @param direction forward or reverse
|
|
108
|
+
*/
|
|
109
|
+
setDirection(direction: TFanDirection): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Get current state as object
|
|
112
|
+
*/
|
|
113
|
+
getState(): IFanState;
|
|
114
|
+
/**
|
|
115
|
+
* Refresh state from the device
|
|
116
|
+
*/
|
|
117
|
+
refreshState(): Promise<IFanState>;
|
|
118
|
+
/**
|
|
119
|
+
* Update state from external source
|
|
120
|
+
*/
|
|
121
|
+
updateState(state: IFanState): void;
|
|
122
|
+
/**
|
|
123
|
+
* Internal state update
|
|
124
|
+
*/
|
|
125
|
+
private updateStateInternal;
|
|
126
|
+
getFeatureInfo(): IFanFeatureInfo;
|
|
127
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fan Feature
|
|
3
|
+
* Provides control for fans (speed, oscillation, direction)
|
|
4
|
+
*/
|
|
5
|
+
import { Feature } from './feature.abstract.js';
|
|
6
|
+
/**
|
|
7
|
+
* Fan Feature - speed, oscillation, and direction control
|
|
8
|
+
*
|
|
9
|
+
* Protocol-agnostic: works with Home Assistant, MQTT, Bond, etc.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const fan = device.getFeature<FanFeature>('fan');
|
|
14
|
+
* if (fan) {
|
|
15
|
+
* await fan.turnOn(75); // 75% speed
|
|
16
|
+
* await fan.setOscillating(true);
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export class FanFeature extends Feature {
|
|
21
|
+
type = 'fan';
|
|
22
|
+
protocol;
|
|
23
|
+
/** Entity ID (e.g., "fan.bedroom") */
|
|
24
|
+
entityId;
|
|
25
|
+
/** Capabilities */
|
|
26
|
+
capabilities;
|
|
27
|
+
/** Current state */
|
|
28
|
+
_isOn = false;
|
|
29
|
+
_percentage;
|
|
30
|
+
_presetMode;
|
|
31
|
+
_oscillating;
|
|
32
|
+
_direction;
|
|
33
|
+
/** Protocol client for controlling the fan */
|
|
34
|
+
protocolClient;
|
|
35
|
+
constructor(device, port, options) {
|
|
36
|
+
super(device, port, options);
|
|
37
|
+
this.protocol = options.protocol;
|
|
38
|
+
this.entityId = options.entityId;
|
|
39
|
+
this.protocolClient = options.protocolClient;
|
|
40
|
+
this.capabilities = {
|
|
41
|
+
supportsSpeed: options.capabilities?.supportsSpeed ?? true,
|
|
42
|
+
supportsOscillate: options.capabilities?.supportsOscillate ?? false,
|
|
43
|
+
supportsDirection: options.capabilities?.supportsDirection ?? false,
|
|
44
|
+
supportsPresetModes: options.capabilities?.supportsPresetModes ?? false,
|
|
45
|
+
presetModes: options.capabilities?.presetModes,
|
|
46
|
+
speedCount: options.capabilities?.speedCount,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Properties
|
|
51
|
+
// ============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Get current on/off state (cached)
|
|
54
|
+
*/
|
|
55
|
+
get isOn() {
|
|
56
|
+
return this._isOn;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get current speed percentage 0-100 (cached)
|
|
60
|
+
*/
|
|
61
|
+
get percentage() {
|
|
62
|
+
return this._percentage;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get current preset mode (cached)
|
|
66
|
+
*/
|
|
67
|
+
get presetMode() {
|
|
68
|
+
return this._presetMode;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get oscillating state (cached)
|
|
72
|
+
*/
|
|
73
|
+
get oscillating() {
|
|
74
|
+
return this._oscillating;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get direction (cached)
|
|
78
|
+
*/
|
|
79
|
+
get direction() {
|
|
80
|
+
return this._direction;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get available preset modes
|
|
84
|
+
*/
|
|
85
|
+
get presetModes() {
|
|
86
|
+
return this.capabilities.presetModes;
|
|
87
|
+
}
|
|
88
|
+
// ============================================================================
|
|
89
|
+
// Connection
|
|
90
|
+
// ============================================================================
|
|
91
|
+
async doConnect() {
|
|
92
|
+
try {
|
|
93
|
+
const state = await this.protocolClient.getState(this.entityId);
|
|
94
|
+
this.updateStateInternal(state);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Ignore errors fetching initial state
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async doDisconnect() {
|
|
101
|
+
// Nothing to disconnect
|
|
102
|
+
}
|
|
103
|
+
// ============================================================================
|
|
104
|
+
// Fan Control
|
|
105
|
+
// ============================================================================
|
|
106
|
+
/**
|
|
107
|
+
* Turn on the fan
|
|
108
|
+
* @param percentage Optional speed percentage
|
|
109
|
+
*/
|
|
110
|
+
async turnOn(percentage) {
|
|
111
|
+
await this.protocolClient.turnOn(this.entityId, percentage);
|
|
112
|
+
this._isOn = true;
|
|
113
|
+
if (percentage !== undefined) {
|
|
114
|
+
this._percentage = percentage;
|
|
115
|
+
}
|
|
116
|
+
this.emit('state:changed', this.getState());
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Turn off the fan
|
|
120
|
+
*/
|
|
121
|
+
async turnOff() {
|
|
122
|
+
await this.protocolClient.turnOff(this.entityId);
|
|
123
|
+
this._isOn = false;
|
|
124
|
+
this.emit('state:changed', this.getState());
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Toggle the fan
|
|
128
|
+
*/
|
|
129
|
+
async toggle() {
|
|
130
|
+
await this.protocolClient.toggle(this.entityId);
|
|
131
|
+
this._isOn = !this._isOn;
|
|
132
|
+
this.emit('state:changed', this.getState());
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Set speed percentage
|
|
136
|
+
* @param percentage Speed 0-100
|
|
137
|
+
*/
|
|
138
|
+
async setPercentage(percentage) {
|
|
139
|
+
if (!this.capabilities.supportsSpeed) {
|
|
140
|
+
throw new Error('Fan does not support speed control');
|
|
141
|
+
}
|
|
142
|
+
const clamped = Math.max(0, Math.min(100, Math.round(percentage)));
|
|
143
|
+
await this.protocolClient.setPercentage(this.entityId, clamped);
|
|
144
|
+
this._percentage = clamped;
|
|
145
|
+
this._isOn = clamped > 0;
|
|
146
|
+
this.emit('state:changed', this.getState());
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Set preset mode
|
|
150
|
+
* @param mode Preset mode name
|
|
151
|
+
*/
|
|
152
|
+
async setPresetMode(mode) {
|
|
153
|
+
if (!this.capabilities.supportsPresetModes) {
|
|
154
|
+
throw new Error('Fan does not support preset modes');
|
|
155
|
+
}
|
|
156
|
+
await this.protocolClient.setPresetMode(this.entityId, mode);
|
|
157
|
+
this._presetMode = mode;
|
|
158
|
+
this._isOn = true;
|
|
159
|
+
this.emit('state:changed', this.getState());
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Set oscillating state
|
|
163
|
+
* @param oscillating Whether to oscillate
|
|
164
|
+
*/
|
|
165
|
+
async setOscillating(oscillating) {
|
|
166
|
+
if (!this.capabilities.supportsOscillate) {
|
|
167
|
+
throw new Error('Fan does not support oscillation');
|
|
168
|
+
}
|
|
169
|
+
await this.protocolClient.setOscillating(this.entityId, oscillating);
|
|
170
|
+
this._oscillating = oscillating;
|
|
171
|
+
this.emit('state:changed', this.getState());
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Set direction
|
|
175
|
+
* @param direction forward or reverse
|
|
176
|
+
*/
|
|
177
|
+
async setDirection(direction) {
|
|
178
|
+
if (!this.capabilities.supportsDirection) {
|
|
179
|
+
throw new Error('Fan does not support direction control');
|
|
180
|
+
}
|
|
181
|
+
await this.protocolClient.setDirection(this.entityId, direction);
|
|
182
|
+
this._direction = direction;
|
|
183
|
+
this.emit('state:changed', this.getState());
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get current state as object
|
|
187
|
+
*/
|
|
188
|
+
getState() {
|
|
189
|
+
return {
|
|
190
|
+
isOn: this._isOn,
|
|
191
|
+
percentage: this._percentage,
|
|
192
|
+
presetMode: this._presetMode,
|
|
193
|
+
oscillating: this._oscillating,
|
|
194
|
+
direction: this._direction,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Refresh state from the device
|
|
199
|
+
*/
|
|
200
|
+
async refreshState() {
|
|
201
|
+
const state = await this.protocolClient.getState(this.entityId);
|
|
202
|
+
this.updateStateInternal(state);
|
|
203
|
+
return state;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Update state from external source
|
|
207
|
+
*/
|
|
208
|
+
updateState(state) {
|
|
209
|
+
this.updateStateInternal(state);
|
|
210
|
+
this.emit('state:changed', state);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Internal state update
|
|
214
|
+
*/
|
|
215
|
+
updateStateInternal(state) {
|
|
216
|
+
this._isOn = state.isOn;
|
|
217
|
+
this._percentage = state.percentage;
|
|
218
|
+
this._presetMode = state.presetMode;
|
|
219
|
+
this._oscillating = state.oscillating;
|
|
220
|
+
this._direction = state.direction;
|
|
221
|
+
}
|
|
222
|
+
// ============================================================================
|
|
223
|
+
// Feature Info
|
|
224
|
+
// ============================================================================
|
|
225
|
+
getFeatureInfo() {
|
|
226
|
+
return {
|
|
227
|
+
...this.getBaseFeatureInfo(),
|
|
228
|
+
type: 'fan',
|
|
229
|
+
protocol: this.protocol,
|
|
230
|
+
capabilities: this.capabilities,
|
|
231
|
+
currentState: this.getState(),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS5mYW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9mZWF0dXJlcy9mZWF0dXJlLmZhbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUF5QixNQUFNLHVCQUF1QixDQUFDO0FBeUJ2RTs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxPQUFPLFVBQVcsU0FBUSxPQUFPO0lBQ3JCLElBQUksR0FBRyxLQUFjLENBQUM7SUFDdEIsUUFBUSxDQUFlO0lBRXZDLHNDQUFzQztJQUN0QixRQUFRLENBQVM7SUFFakMsbUJBQW1CO0lBQ0gsWUFBWSxDQUFtQjtJQUUvQyxvQkFBb0I7SUFDVixLQUFLLEdBQVksS0FBSyxDQUFDO0lBQ3ZCLFdBQVcsQ0FBVTtJQUNyQixXQUFXLENBQVU7SUFDckIsWUFBWSxDQUFXO0lBQ3ZCLFVBQVUsQ0FBaUI7SUFFckMsOENBQThDO0lBQ3RDLGNBQWMsQ0FBcUI7SUFFM0MsWUFDRSxNQUF3QixFQUN4QixJQUFZLEVBQ1osT0FBMkI7UUFFM0IsS0FBSyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUNqQyxJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUM7UUFFN0MsSUFBSSxDQUFDLFlBQVksR0FBRztZQUNsQixhQUFhLEVBQUUsT0FBTyxDQUFDLFlBQVksRUFBRSxhQUFhLElBQUksSUFBSTtZQUMxRCxpQkFBaUIsRUFBRSxPQUFPLENBQUMsWUFBWSxFQUFFLGlCQUFpQixJQUFJLEtBQUs7WUFDbkUsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLFlBQVksRUFBRSxpQkFBaUIsSUFBSSxLQUFLO1lBQ25FLG1CQUFtQixFQUFFLE9B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
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Light Feature
|
|
3
|
+
* Provides control for smart lights (brightness, color, effects)
|
|
4
|
+
*/
|
|
5
|
+
import { Feature, type TDeviceReference } from './feature.abstract.js';
|
|
6
|
+
import type { IFeatureOptions } from '../interfaces/feature.interfaces.js';
|
|
7
|
+
import type { TLightProtocol, ILightCapabilities, ILightState, ILightFeatureInfo, ILightProtocolClient } from '../interfaces/smarthome.interfaces.js';
|
|
8
|
+
/**
|
|
9
|
+
* Options for creating a LightFeature
|
|
10
|
+
*/
|
|
11
|
+
export interface ILightFeatureOptions extends IFeatureOptions {
|
|
12
|
+
/** Protocol type */
|
|
13
|
+
protocol: TLightProtocol;
|
|
14
|
+
/** Entity ID (for Home Assistant) */
|
|
15
|
+
entityId: string;
|
|
16
|
+
/** Protocol client for controlling the light */
|
|
17
|
+
protocolClient: ILightProtocolClient;
|
|
18
|
+
/** Light capabilities */
|
|
19
|
+
capabilities?: Partial<ILightCapabilities>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Light Feature - brightness, color, and effect control
|
|
23
|
+
*
|
|
24
|
+
* Protocol-agnostic: works with Home Assistant, Hue, MQTT, Zigbee, etc.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const light = device.getFeature<LightFeature>('light');
|
|
29
|
+
* if (light) {
|
|
30
|
+
* await light.turnOn({ brightness: 200 });
|
|
31
|
+
* await light.setColorTemp(4000); // 4000K warm white
|
|
32
|
+
* await light.setRgbColor(255, 100, 50);
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class LightFeature extends Feature {
|
|
37
|
+
readonly type: "light";
|
|
38
|
+
readonly protocol: TLightProtocol;
|
|
39
|
+
/** Entity ID (e.g., "light.living_room") */
|
|
40
|
+
readonly entityId: string;
|
|
41
|
+
/** Capabilities */
|
|
42
|
+
readonly capabilities: ILightCapabilities;
|
|
43
|
+
/** Current state */
|
|
44
|
+
protected _isOn: boolean;
|
|
45
|
+
protected _brightness?: number;
|
|
46
|
+
protected _colorTemp?: number;
|
|
47
|
+
protected _colorTempMireds?: number;
|
|
48
|
+
protected _rgbColor?: [number, number, number];
|
|
49
|
+
protected _hsColor?: [number, number];
|
|
50
|
+
protected _xyColor?: [number, number];
|
|
51
|
+
protected _effect?: string;
|
|
52
|
+
/** Protocol client for controlling the light */
|
|
53
|
+
private protocolClient;
|
|
54
|
+
constructor(device: TDeviceReference, port: number, options: ILightFeatureOptions);
|
|
55
|
+
/**
|
|
56
|
+
* Get current on/off state (cached)
|
|
57
|
+
*/
|
|
58
|
+
get isOn(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Get current brightness 0-255 (cached)
|
|
61
|
+
*/
|
|
62
|
+
get brightness(): number | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Get current color temperature in Kelvin (cached)
|
|
65
|
+
*/
|
|
66
|
+
get colorTemp(): number | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Get current color temperature in Mireds (cached)
|
|
69
|
+
*/
|
|
70
|
+
get colorTempMireds(): number | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Get current RGB color (cached)
|
|
73
|
+
*/
|
|
74
|
+
get rgbColor(): [number, number, number] | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Get current HS color [hue 0-360, saturation 0-100] (cached)
|
|
77
|
+
*/
|
|
78
|
+
get hsColor(): [number, number] | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Get current XY color (cached)
|
|
81
|
+
*/
|
|
82
|
+
get xyColor(): [number, number] | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Get current effect (cached)
|
|
85
|
+
*/
|
|
86
|
+
get effect(): string | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Get available effects
|
|
89
|
+
*/
|
|
90
|
+
get effects(): string[] | undefined;
|
|
91
|
+
protected doConnect(): Promise<void>;
|
|
92
|
+
protected doDisconnect(): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Turn on the light
|
|
95
|
+
* @param options Optional settings to apply when turning on
|
|
96
|
+
*/
|
|
97
|
+
turnOn(options?: {
|
|
98
|
+
brightness?: number;
|
|
99
|
+
colorTemp?: number;
|
|
100
|
+
rgb?: [number, number, number];
|
|
101
|
+
transition?: number;
|
|
102
|
+
}): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Turn off the light
|
|
105
|
+
* @param options Optional transition time
|
|
106
|
+
*/
|
|
107
|
+
turnOff(options?: {
|
|
108
|
+
transition?: number;
|
|
109
|
+
}): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Toggle the light
|
|
112
|
+
*/
|
|
113
|
+
toggle(): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Set brightness level
|
|
116
|
+
* @param brightness Brightness 0-255
|
|
117
|
+
* @param transition Optional transition time in seconds
|
|
118
|
+
*/
|
|
119
|
+
setBrightness(brightness: number, transition?: number): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Set color temperature in Kelvin
|
|
122
|
+
* @param kelvin Color temperature in Kelvin (e.g., 2700 warm, 6500 cool)
|
|
123
|
+
* @param transition Optional transition time in seconds
|
|
124
|
+
*/
|
|
125
|
+
setColorTemp(kelvin: number, transition?: number): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Set RGB color
|
|
128
|
+
* @param r Red 0-255
|
|
129
|
+
* @param g Green 0-255
|
|
130
|
+
* @param b Blue 0-255
|
|
131
|
+
* @param transition Optional transition time in seconds
|
|
132
|
+
*/
|
|
133
|
+
setRgbColor(r: number, g: number, b: number, transition?: number): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Set light effect
|
|
136
|
+
* @param effect Effect name from available effects
|
|
137
|
+
*/
|
|
138
|
+
setEffect(effect: string): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Get current state as object
|
|
141
|
+
*/
|
|
142
|
+
getState(): ILightState;
|
|
143
|
+
/**
|
|
144
|
+
* Refresh state from the device
|
|
145
|
+
*/
|
|
146
|
+
refreshState(): Promise<ILightState>;
|
|
147
|
+
/**
|
|
148
|
+
* Update state from external source (e.g., state change event)
|
|
149
|
+
*/
|
|
150
|
+
updateState(state: ILightState): void;
|
|
151
|
+
/**
|
|
152
|
+
* Internal state update
|
|
153
|
+
*/
|
|
154
|
+
private updateStateInternal;
|
|
155
|
+
getFeatureInfo(): ILightFeatureInfo;
|
|
156
|
+
}
|