@camera.ui/sdk 0.0.3 → 0.0.5

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.
Files changed (65) hide show
  1. package/README.md +2 -2
  2. package/dist/camera/events.js +2 -0
  3. package/dist/camera/index.js +3 -1
  4. package/dist/external.js +7 -0
  5. package/dist/index.d.ts +7132 -4248
  6. package/dist/index.js +3 -11
  7. package/dist/internal/contract-validators.js +21 -0
  8. package/dist/internal/index.d.ts +915 -0
  9. package/dist/internal/index.js +9 -0
  10. package/dist/internal/sensor-triggers.js +2 -0
  11. package/dist/internal/shared-utils.js +86 -0
  12. package/dist/internal/streaming-internal.js +1 -0
  13. package/dist/manager/index.js +1 -1
  14. package/dist/observable/index.js +419 -0
  15. package/dist/plugin/api.js +21 -0
  16. package/dist/plugin/contract.js +101 -114
  17. package/dist/plugin/helper.js +277 -0
  18. package/dist/plugin/index.js +4 -1
  19. package/dist/plugin/interfaces.js +51 -1
  20. package/dist/plugin/notifier.js +23 -0
  21. package/dist/plugin/oauth.js +1 -0
  22. package/dist/sensor/audio.js +103 -81
  23. package/dist/sensor/base.js +350 -318
  24. package/dist/sensor/battery.js +73 -59
  25. package/dist/sensor/classifier.js +117 -0
  26. package/dist/sensor/clip.js +30 -0
  27. package/dist/sensor/contact.js +37 -18
  28. package/dist/sensor/detection.js +4 -0
  29. package/dist/sensor/doorbell.js +52 -38
  30. package/dist/sensor/face.js +71 -86
  31. package/dist/sensor/garage.js +121 -0
  32. package/dist/sensor/humidity.js +52 -0
  33. package/dist/sensor/index.js +17 -11
  34. package/dist/sensor/leak.js +52 -0
  35. package/dist/sensor/licensePlate.js +70 -79
  36. package/dist/sensor/light.js +82 -38
  37. package/dist/sensor/lock.js +99 -0
  38. package/dist/sensor/motion.js +85 -70
  39. package/dist/sensor/object.js +73 -94
  40. package/dist/sensor/occupancy.js +52 -0
  41. package/dist/sensor/ptz.js +114 -100
  42. package/dist/sensor/securitySystem.js +98 -0
  43. package/dist/sensor/siren.js +75 -43
  44. package/dist/sensor/smoke.js +52 -0
  45. package/dist/sensor/spec.js +1 -0
  46. package/dist/sensor/switch.js +72 -0
  47. package/dist/sensor/temperature.js +52 -0
  48. package/dist/storage/index.js +1 -2
  49. package/dist/types.js +1 -0
  50. package/package.json +36 -23
  51. package/CHANGELOG.md +0 -8
  52. package/CONTRIBUTING.md +0 -1
  53. package/LICENSE.md +0 -22
  54. package/dist/sensor/guards.js +0 -133
  55. package/dist/sensor/types.js +0 -46
  56. package/dist/service/base.js +0 -96
  57. package/dist/service/index.js +0 -3
  58. package/tsconfig.node.json +0 -30
  59. /package/dist/camera/{types.js → enums.js} +0 -0
  60. /package/dist/{manager/types.js → camera/frames.js} +0 -0
  61. /package/dist/{plugin/types.js → internal/camera-config-internal.js} +0 -0
  62. /package/dist/{service/services.js → internal/camera-enums.js} +0 -0
  63. /package/dist/{service/types.js → internal/camera-wire.js} +0 -0
  64. /package/dist/{storage/schema.js → internal/manager-rpc.js} +0 -0
  65. /package/dist/{storage/storages.js → internal/sensor-rpc.js} +0 -0
@@ -0,0 +1,52 @@
1
+ import { Sensor, SensorType, SensorCategory } from './base.js';
2
+ /**
3
+ * Properties for occupancy sensors
4
+ *
5
+ * @internal
6
+ */
7
+ export var OccupancyProperty;
8
+ (function (OccupancyProperty) {
9
+ /** Whether occupancy is detected (true = occupied) */
10
+ OccupancyProperty["Detected"] = "detected";
11
+ })(OccupancyProperty || (OccupancyProperty = {}));
12
+ /** Occupancy sensor for detecting presence in a room or area */
13
+ export class OccupancySensor extends Sensor {
14
+ type = SensorType.Occupancy;
15
+ category = SensorCategory.Sensor;
16
+ constructor(name = 'Occupancy Sensor') {
17
+ super(name);
18
+ this._writeState({ [OccupancyProperty.Detected]: false });
19
+ }
20
+ get detected() {
21
+ return this.props.detected;
22
+ }
23
+ /**
24
+ * Report occupancy state.
25
+ *
26
+ * @param value - True when the area is currently occupied.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * occupancy.setDetected(true);
31
+ * ```
32
+ */
33
+ setDetected(value) {
34
+ this._writeState({ [OccupancyProperty.Detected]: value });
35
+ }
36
+ /**
37
+ * Read-only sensor: external writes are ignored. State is reported via `setDetected`.
38
+ *
39
+ * Called by the cross-process plugin host when a generic property write is received.
40
+ * Occupancy sensors have no externally writable properties, so the parameters are
41
+ * unused (underscore-prefixed) and the call is a no-op.
42
+ *
43
+ * @param _property - Unused — occupancy sensors expose no writable properties.
44
+ *
45
+ * @param _value - Unused — occupancy sensors expose no writable properties.
46
+ *
47
+ * @internal
48
+ */
49
+ updateValue(_property, _value) {
50
+ // No-op — occupancy state is reported by the plugin, not set externally.
51
+ }
52
+ }
@@ -1,159 +1,173 @@
1
- import { Sensor } from './base.js';
2
- import { SensorCategory, SensorType } from './types.js';
3
- /**
4
- * PTZ Capability enum
5
- * Describes what PTZ features this sensor supports
6
- */
1
+ import { Sensor, SensorType, SensorCategory } from './base.js';
2
+ /** Optional capabilities for PTZ controls. Add to `capabilities` to enable features. */
7
3
  export var PTZCapability;
8
4
  (function (PTZCapability) {
9
- /** Supports horizontal panning */
10
5
  PTZCapability["Pan"] = "pan";
11
- /** Supports vertical tilting */
12
6
  PTZCapability["Tilt"] = "tilt";
13
- /** Supports zoom in/out */
14
7
  PTZCapability["Zoom"] = "zoom";
15
- /** Supports preset positions */
8
+ /** Camera supports named position presets */
16
9
  PTZCapability["Presets"] = "presets";
17
- /** Supports home position */
10
+ /** Camera supports a home position */
18
11
  PTZCapability["Home"] = "home";
19
12
  })(PTZCapability || (PTZCapability = {}));
20
13
  /**
21
- * PTZ control property keys
14
+ * Properties for PTZ controls
15
+ *
16
+ * @internal
22
17
  */
23
18
  export var PTZProperty;
24
19
  (function (PTZProperty) {
20
+ /** Current pan/tilt/zoom position */
25
21
  PTZProperty["Position"] = "position";
22
+ /** Whether the camera is currently moving */
26
23
  PTZProperty["Moving"] = "moving";
24
+ /** List of available preset names */
27
25
  PTZProperty["Presets"] = "presets";
26
+ /** Current movement velocity (continuous move) */
28
27
  PTZProperty["Velocity"] = "velocity";
28
+ /** Target preset to move to */
29
29
  PTZProperty["TargetPreset"] = "targetPreset";
30
30
  })(PTZProperty || (PTZProperty = {}));
31
31
  /**
32
- * PTZ Control
33
- *
34
- * Bidirectional control for camera pan/tilt/zoom.
35
- *
36
- * @example
37
- * ```typescript
38
- * // Move to absolute position
39
- * ptz.position = { pan: 45, tilt: -10, zoom: 0.5 };
40
- *
41
- * // Continuous move
42
- * ptz.continuousMove({ panSpeed: 1, tiltSpeed: 0, zoomSpeed: 0 });
43
- *
44
- * // Stop all movement
45
- * ptz.stop();
46
- *
47
- * // Go to preset
48
- * ptz.goToPreset('Entrance');
32
+ * Pan-tilt-zoom camera control. Override `setPosition()` / `setVelocity()` /
33
+ * `setTargetPreset()` to drive hardware, then call the corresponding `super.X()`
34
+ * method after success to sync the SDK state. For hardware-pushed state updates
35
+ * (e.g. PTZ position change events), call the `super` methods from your event
36
+ * handler — that bypasses any plugin override and only syncs state.
49
37
  *
50
- * // Go to home position
51
- * ptz.goHome();
52
- * ```
38
+ * Set `capabilities` to advertise supported axes and features. Use `setPresets()`
39
+ * to publish the discovered preset list and `setMoving()` to publish movement state.
53
40
  */
54
41
  export class PTZControl extends Sensor {
55
42
  type = SensorType.PTZ;
56
43
  category = SensorCategory.Control;
57
- name;
58
- /**
59
- * Create a new PTZ control sensor.
60
- *
61
- * @param name - Human-readable name for this sensor
62
- */
63
44
  constructor(name = 'PTZ') {
64
- super();
65
- this.name = name;
66
- // Initialize defaults
67
- this.props.position = { pan: 0, tilt: 0, zoom: 0 };
68
- this.props.moving = false;
69
- this.props.presets = [];
45
+ super(name);
46
+ this._writeState({
47
+ [PTZProperty.Position]: { pan: 0, tilt: 0, zoom: 0 },
48
+ [PTZProperty.Moving]: false,
49
+ [PTZProperty.Presets]: [],
50
+ });
70
51
  }
71
- /** Current PTZ position */
72
52
  get position() {
73
- return this.rawProps.position;
74
- }
75
- /** Set PTZ position (absolute move) */
76
- set position(value) {
77
- this.props.position = value;
53
+ return this.props.position;
78
54
  }
79
- /** Whether PTZ is currently moving */
80
55
  get moving() {
81
- return this.rawProps.moving;
56
+ return this.props.moving;
82
57
  }
83
- /** Set moving state */
84
- set moving(value) {
85
- this.props.moving = value;
86
- }
87
- /** Available presets */
88
58
  get presets() {
89
- return this.rawProps.presets;
90
- }
91
- /** Set available presets */
92
- set presets(value) {
93
- this.props.presets = value;
59
+ return this.props.presets;
94
60
  }
95
- /** Current velocity (for continuous move) */
96
61
  get velocity() {
97
- return this.rawProps.velocity;
98
- }
99
- /** Set velocity for continuous move */
100
- set velocity(value) {
101
- this.props.velocity = value;
62
+ return this.props.velocity;
102
63
  }
103
- /** Target preset to go to */
104
64
  get targetPreset() {
105
- return this.rawProps.targetPreset;
65
+ return this.props.targetPreset;
106
66
  }
107
- /** Set target preset */
108
- set targetPreset(value) {
109
- this.props.targetPreset = value;
110
- }
111
- /** Go to home position (pan: 0, tilt: 0, zoom: 0) */
112
- goHome() {
113
- this.props.position = { pan: 0, tilt: 0, zoom: 0 };
67
+ /**
68
+ * Move to an absolute pan/tilt/zoom position. Override to drive hardware and
69
+ * call `await super.setPosition(value)` after success to sync the SDK state.
70
+ *
71
+ * @param value - Absolute pan/tilt/zoom target position.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * await ptz.setPosition({ pan: 0.25, tilt: -0.1, zoom: 0.5 });
76
+ * ```
77
+ */
78
+ async setPosition(value) {
79
+ this._writeState({ [PTZProperty.Position]: value });
114
80
  }
115
81
  /**
116
- * Pan to specific angle
82
+ * Continuous-move command. Override to drive hardware and call
83
+ * `await super.setVelocity(value)` after success to sync the SDK state.
84
+ *
85
+ * @param value - Per-axis speeds in `[-1, 1]`, or `undefined` to stop.
117
86
  *
118
- * @param angle - Pan angle in degrees
87
+ * @example
88
+ * ```ts
89
+ * await ptz.setVelocity({ panSpeed: 0.5, tiltSpeed: 0, zoomSpeed: 0 });
90
+ * await ptz.setVelocity(undefined); // stop
91
+ * ```
119
92
  */
120
- pan(angle) {
121
- this.props.position = { ...this.position, pan: angle };
93
+ async setVelocity(value) {
94
+ this._writeState({ [PTZProperty.Velocity]: value });
122
95
  }
123
96
  /**
124
- * Tilt to specific angle
97
+ * Preset-move command. Override to drive hardware and call
98
+ * `await super.setTargetPreset(value)` after success to sync the SDK state.
99
+ *
100
+ * @param value - Preset name to move to, or `undefined` to clear.
125
101
  *
126
- * @param angle - Tilt angle in degrees
102
+ * @example
103
+ * ```ts
104
+ * await ptz.setTargetPreset('Driveway');
105
+ * ```
127
106
  */
128
- tilt(angle) {
129
- this.props.position = { ...this.position, tilt: angle };
107
+ async setTargetPreset(value) {
108
+ this._writeState({ [PTZProperty.TargetPreset]: value });
130
109
  }
131
110
  /**
132
- * Zoom to specific level (0-1)
111
+ * Publish the discovered preset list (typically called once at startup).
133
112
  *
134
- * @param level - Zoom level between 0 and 1
113
+ * @param value - List of preset names supported by the camera.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * ptz.setPresets(['Home', 'Driveway', 'Backyard']);
118
+ * ```
135
119
  */
136
- zoom(level) {
137
- this.props.position = { ...this.position, zoom: Math.max(0, Math.min(1, level)) };
120
+ setPresets(value) {
121
+ this._writeState({ [PTZProperty.Presets]: value });
138
122
  }
139
123
  /**
140
- * Start continuous movement
124
+ * Publish movement state (e.g. when continuous-move starts/stops).
125
+ *
126
+ * @param value - True while the camera is moving.
141
127
  *
142
- * @param velocity - Movement speed for each axis (-1 to 1)
128
+ * @example
129
+ * ```ts
130
+ * ptz.setMoving(true);
131
+ * ```
143
132
  */
144
- continuousMove(velocity) {
145
- this.props.velocity = velocity;
133
+ setMoving(value) {
134
+ this._writeState({ [PTZProperty.Moving]: value });
146
135
  }
147
- /** Stop all movement */
148
- stop() {
149
- this.props.velocity = { panSpeed: 0, tiltSpeed: 0, zoomSpeed: 0 };
136
+ /**
137
+ * Move the camera to the home position (pan=0, tilt=0, zoom=0).
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * await ptz.goHome();
142
+ * ```
143
+ */
144
+ async goHome() {
145
+ await this.setPosition({ pan: 0, tilt: 0, zoom: 0 });
150
146
  }
151
147
  /**
152
- * Go to a saved preset
148
+ * Cross-process consumer entry point. Dispatches writable properties
149
+ * to semantic methods so plugin overrides (hardware actions) are honored.
150
+ * `moving` and `presets` are observed/discovered state and not externally writable;
151
+ * only `Position`, `Velocity`, and `TargetPreset` may be set.
152
+ *
153
+ * @param property - Property name to write.
154
+ *
155
+ * @param value - New value for the property.
153
156
  *
154
- * @param preset - Preset name
157
+ * @internal
155
158
  */
156
- goToPreset(preset) {
157
- this.props.targetPreset = preset;
159
+ async updateValue(property, value) {
160
+ switch (property) {
161
+ case PTZProperty.Position:
162
+ await this.setPosition(value);
163
+ return;
164
+ case PTZProperty.Velocity:
165
+ await this.setVelocity(value);
166
+ return;
167
+ case PTZProperty.TargetPreset:
168
+ await this.setTargetPreset(value);
169
+ return;
170
+ }
171
+ // Unknown / non-writable property (incl. moving, presets) — ignored.
158
172
  }
159
173
  }
@@ -0,0 +1,98 @@
1
+ import { Sensor, SensorType, SensorCategory } from './base.js';
2
+ /** Security system arm/disarm states (HomeKit-compatible values) */
3
+ export var SecuritySystemState;
4
+ (function (SecuritySystemState) {
5
+ SecuritySystemState[SecuritySystemState["StayArm"] = 0] = "StayArm";
6
+ SecuritySystemState[SecuritySystemState["AwayArm"] = 1] = "AwayArm";
7
+ SecuritySystemState[SecuritySystemState["NightArm"] = 2] = "NightArm";
8
+ SecuritySystemState[SecuritySystemState["Disarmed"] = 3] = "Disarmed";
9
+ SecuritySystemState[SecuritySystemState["AlarmTriggered"] = 4] = "AlarmTriggered";
10
+ })(SecuritySystemState || (SecuritySystemState = {}));
11
+ /**
12
+ * Properties for security system controls
13
+ *
14
+ * @internal
15
+ */
16
+ export var SecuritySystemProperty;
17
+ (function (SecuritySystemProperty) {
18
+ /** The actual current state of the security system */
19
+ SecuritySystemProperty["CurrentState"] = "currentState";
20
+ /** The desired target state (set by user, transitions to currentState) */
21
+ SecuritySystemProperty["TargetState"] = "targetState";
22
+ })(SecuritySystemProperty || (SecuritySystemProperty = {}));
23
+ /**
24
+ * Security system control. Override `setTargetState()` to drive hardware and call
25
+ * `await super.setTargetState(value)` once the hardware confirms — the base
26
+ * implementation updates both `targetState` and `currentState`.
27
+ */
28
+ export class SecuritySystem extends Sensor {
29
+ type = SensorType.SecuritySystem;
30
+ category = SensorCategory.Control;
31
+ constructor(name = 'Security System') {
32
+ super(name);
33
+ this._writeState({
34
+ [SecuritySystemProperty.CurrentState]: SecuritySystemState.Disarmed,
35
+ [SecuritySystemProperty.TargetState]: SecuritySystemState.Disarmed,
36
+ });
37
+ }
38
+ get currentState() {
39
+ return this.props.currentState;
40
+ }
41
+ get targetState() {
42
+ return this.props.targetState;
43
+ }
44
+ /**
45
+ * Set the target state. Override to drive hardware and call
46
+ * `await super.setTargetState(value)` after success — the base implementation
47
+ * syncs both `targetState` and `currentState` to the new value.
48
+ *
49
+ * @param value - Desired armed/disarmed state from {@link SecuritySystemState}.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * import { SecuritySystemState } from '@camera.ui/sdk';
54
+ * await alarm.setTargetState(SecuritySystemState.AwayArm);
55
+ * ```
56
+ */
57
+ async setTargetState(value) {
58
+ this._writeState({
59
+ [SecuritySystemProperty.TargetState]: value,
60
+ [SecuritySystemProperty.CurrentState]: value,
61
+ });
62
+ }
63
+ /**
64
+ * Publish the actual security system state. Use this to drive transitions
65
+ * that diverge from the user-requested target — most notably the
66
+ * `AlarmTriggered` state when an intruder is detected, or arming-delay
67
+ * intermediate states. Read-only from cross-process consumers
68
+ * (`updateValue` ignores it).
69
+ *
70
+ * @param value - Current security system state from {@link SecuritySystemState}.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * import { SecuritySystemState } from '@camera.ui/sdk';
75
+ * alarm.setCurrentState(SecuritySystemState.AlarmTriggered);
76
+ * ```
77
+ */
78
+ setCurrentState(value) {
79
+ this._writeState({ [SecuritySystemProperty.CurrentState]: value });
80
+ }
81
+ /**
82
+ * Cross-process consumer entry point. Dispatches writable properties
83
+ * to semantic methods so plugin overrides (hardware actions) are honored.
84
+ * `currentState` is observed-only and not externally writable; only `targetState` may be set.
85
+ *
86
+ * @param property - Property name to write.
87
+ *
88
+ * @param value - New value for the property.
89
+ *
90
+ * @internal
91
+ */
92
+ async updateValue(property, value) {
93
+ if (property === SecuritySystemProperty.TargetState) {
94
+ await this.setTargetState(value);
95
+ }
96
+ // Unknown / non-writable property (incl. currentState) — ignored.
97
+ }
98
+ }
@@ -1,73 +1,105 @@
1
- import { Sensor } from './base.js';
2
- import { SensorCategory, SensorType } from './types.js';
3
- /**
4
- * Siren Capability enum
5
- * Describes what Siren features this sensor supports
6
- */
1
+ import { Sensor, SensorType, SensorCategory } from './base.js';
2
+ /** Optional capabilities for siren controls */
7
3
  export var SirenCapability;
8
4
  (function (SirenCapability) {
9
- /** Supports volume control */
5
+ /** Siren supports volume adjustment (0–100) */
10
6
  SirenCapability["Volume"] = "volume";
11
- /** Supports different siren modes */
12
- SirenCapability["Modes"] = "modes";
13
7
  })(SirenCapability || (SirenCapability = {}));
14
8
  /**
15
- * Siren control property keys
9
+ * Properties for siren controls
10
+ *
11
+ * @internal
16
12
  */
17
13
  export var SirenProperty;
18
14
  (function (SirenProperty) {
15
+ /** Whether the siren is currently active */
19
16
  SirenProperty["Active"] = "active";
17
+ /** Volume level (0–100) */
20
18
  SirenProperty["Volume"] = "volume";
21
19
  })(SirenProperty || (SirenProperty = {}));
22
20
  /**
23
- * Siren Control
24
- *
25
- * Bidirectional control for camera siren/alarm.
26
- * Properties can be set directly: `siren.active = true`
21
+ * Siren control sensor. Override `setActive()`/`setInactive()` to drive your
22
+ * hardware, then `await super.setActive()` / `await super.setInactive()` to sync
23
+ * the SDK state. For hardware-pushed updates, call the `super` methods from your
24
+ * event handler that bypasses any plugin override and only syncs state.
27
25
  */
28
26
  export class SirenControl extends Sensor {
29
27
  type = SensorType.Siren;
30
28
  category = SensorCategory.Control;
31
- name;
32
29
  constructor(name = 'Siren') {
33
- super();
34
- this.name = name;
35
- // Initialize defaults
36
- this.props.active = false;
37
- this.props.volume = 100;
30
+ super(name);
31
+ this._writeState({
32
+ [SirenProperty.Active]: false,
33
+ [SirenProperty.Volume]: 100,
34
+ });
38
35
  }
39
- /** Whether siren is active */
40
36
  get active() {
41
- return this.rawProps.active;
42
- }
43
- /** Activate/deactivate siren */
44
- set active(value) {
45
- this.props.active = value;
37
+ return this.props.active;
46
38
  }
47
- /** Volume level (0-100) */
48
39
  get volume() {
49
- return this.rawProps.volume;
40
+ return this.props.volume;
50
41
  }
51
- /** Set volume level (0-100) */
52
- set volume(value) {
53
- this.props.volume = Math.max(0, Math.min(100, value));
42
+ /**
43
+ * Activate the siren. Override to drive hardware and call `await super.setActive()`
44
+ * after success to sync the SDK state.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * await siren.setActive();
49
+ * ```
50
+ */
51
+ async setActive() {
52
+ this._writeState({ [SirenProperty.Active]: true });
54
53
  }
55
- /** Activate siren */
56
- activate() {
57
- this.props.active = true;
54
+ /**
55
+ * Deactivate the siren. Override to drive hardware and call `await super.setInactive()`
56
+ * after success to sync the SDK state.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * await siren.setInactive();
61
+ * ```
62
+ */
63
+ async setInactive() {
64
+ this._writeState({ [SirenProperty.Active]: false });
58
65
  }
59
- /** Deactivate siren */
60
- deactivate() {
61
- this.props.active = false;
66
+ /**
67
+ * Set volume. Override to drive hardware and call `await super.setVolume(value)`
68
+ * after success. The default implementation clamps the value to [0, 100].
69
+ *
70
+ * @param value - Volume level in the range 0–100.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * await siren.setVolume(80);
75
+ * ```
76
+ */
77
+ async setVolume(value) {
78
+ this._writeState({ [SirenProperty.Volume]: Math.max(0, Math.min(100, value)) });
62
79
  }
63
80
  /**
64
- * Sound siren for a duration
81
+ * Cross-process consumer entry point. Dispatches writable properties
82
+ * to semantic methods so plugin overrides (hardware actions) are honored.
83
+ * Unknown properties are ignored — only `Active` and `Volume` are externally writable.
84
+ *
85
+ * @param property - Property name to write.
86
+ *
87
+ * @param value - New value for the property.
65
88
  *
66
- * @param durationMs - Duration to sound siren in milliseconds
89
+ * @internal
67
90
  */
68
- async soundFor(durationMs) {
69
- this.activate();
70
- await new Promise((resolve) => setTimeout(resolve, durationMs));
71
- this.deactivate();
91
+ async updateValue(property, value) {
92
+ switch (property) {
93
+ case SirenProperty.Active:
94
+ if (value)
95
+ await this.setActive();
96
+ else
97
+ await this.setInactive();
98
+ return;
99
+ case SirenProperty.Volume:
100
+ await this.setVolume(value);
101
+ return;
102
+ }
103
+ // Unknown / non-writable property — ignored.
72
104
  }
73
105
  }
@@ -0,0 +1,52 @@
1
+ import { Sensor, SensorType, SensorCategory } from './base.js';
2
+ /**
3
+ * Properties for smoke sensors
4
+ *
5
+ * @internal
6
+ */
7
+ export var SmokeProperty;
8
+ (function (SmokeProperty) {
9
+ /** Whether smoke is detected */
10
+ SmokeProperty["Detected"] = "detected";
11
+ })(SmokeProperty || (SmokeProperty = {}));
12
+ /** Smoke detector sensor */
13
+ export class SmokeSensor extends Sensor {
14
+ type = SensorType.Smoke;
15
+ category = SensorCategory.Sensor;
16
+ constructor(name = 'Smoke Sensor') {
17
+ super(name);
18
+ this._writeState({ [SmokeProperty.Detected]: false });
19
+ }
20
+ get detected() {
21
+ return this.props.detected;
22
+ }
23
+ /**
24
+ * Report smoke detection state.
25
+ *
26
+ * @param value - True when smoke is currently detected.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * smoke.setDetected(true);
31
+ * ```
32
+ */
33
+ setDetected(value) {
34
+ this._writeState({ [SmokeProperty.Detected]: value });
35
+ }
36
+ /**
37
+ * Read-only sensor: external writes are ignored. State is reported via `setDetected`.
38
+ *
39
+ * Called by the cross-process plugin host when a generic property write is received.
40
+ * Smoke sensors have no externally writable properties, so the parameters are
41
+ * unused (underscore-prefixed) and the call is a no-op.
42
+ *
43
+ * @param _property - Unused — smoke sensors expose no writable properties.
44
+ *
45
+ * @param _value - Unused — smoke sensors expose no writable properties.
46
+ *
47
+ * @internal
48
+ */
49
+ updateValue(_property, _value) {
50
+ // No-op — smoke state is reported by the plugin, not set externally.
51
+ }
52
+ }
@@ -0,0 +1 @@
1
+ export {};