@camera.ui/sdk 0.0.2 → 0.0.4
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/LICENSE.md +1 -1
- package/README.md +3 -3
- package/dist/camera/events.js +2 -0
- package/dist/camera/index.js +3 -1
- package/dist/external.js +7 -0
- package/dist/index.d.ts +7132 -4248
- package/dist/index.js +3 -11
- package/dist/internal/contract-validators.js +21 -0
- package/dist/internal/index.d.ts +915 -0
- package/dist/internal/index.js +9 -0
- package/dist/internal/sensor-triggers.js +2 -0
- package/dist/internal/shared-utils.js +86 -0
- package/dist/internal/streaming-internal.js +1 -0
- package/dist/manager/index.js +1 -1
- package/dist/observable/index.js +419 -0
- package/dist/plugin/api.js +21 -0
- package/dist/plugin/contract.js +101 -114
- package/dist/plugin/helper.js +277 -0
- package/dist/plugin/index.js +4 -1
- package/dist/plugin/interfaces.js +51 -1
- package/dist/plugin/notifier.js +23 -0
- package/dist/plugin/oauth.js +1 -0
- package/dist/sensor/audio.js +103 -81
- package/dist/sensor/base.js +350 -318
- package/dist/sensor/battery.js +73 -59
- package/dist/sensor/classifier.js +117 -0
- package/dist/sensor/clip.js +30 -0
- package/dist/sensor/contact.js +37 -18
- package/dist/sensor/detection.js +4 -0
- package/dist/sensor/doorbell.js +52 -38
- package/dist/sensor/face.js +71 -86
- package/dist/sensor/garage.js +121 -0
- package/dist/sensor/humidity.js +52 -0
- package/dist/sensor/index.js +17 -11
- package/dist/sensor/leak.js +52 -0
- package/dist/sensor/licensePlate.js +70 -79
- package/dist/sensor/light.js +82 -38
- package/dist/sensor/lock.js +99 -0
- package/dist/sensor/motion.js +85 -70
- package/dist/sensor/object.js +73 -94
- package/dist/sensor/occupancy.js +52 -0
- package/dist/sensor/ptz.js +114 -100
- package/dist/sensor/securitySystem.js +98 -0
- package/dist/sensor/siren.js +75 -43
- package/dist/sensor/smoke.js +52 -0
- package/dist/sensor/spec.js +1 -0
- package/dist/sensor/switch.js +72 -0
- package/dist/sensor/temperature.js +52 -0
- package/dist/storage/index.js +1 -2
- package/dist/types.js +1 -0
- package/docs/.vitepress/config.ts +77 -0
- package/docs/.vitepress/theme/index.ts +5 -0
- package/docs/.vitepress/theme/style.css +117 -0
- package/docs/index.md +16 -0
- package/docs/logo.png +0 -0
- package/docs/public/apple-touch-icon.png +0 -0
- package/docs/public/favicon-16.ico +0 -0
- package/docs/public/favicon.ico +0 -0
- package/docs/public/logo.svg +1 -0
- package/examples/README.md +7 -0
- package/examples/getting-started.md +535 -0
- package/package.json +36 -23
- package/scripts/build-example-docs.mjs +62 -0
- package/tsconfig.node.json +3 -2
- package/typedoc.json +42 -0
- package/dist/sensor/guards.js +0 -133
- package/dist/sensor/types.js +0 -46
- package/dist/service/base.js +0 -96
- package/dist/service/index.js +0 -3
- /package/dist/camera/{types.js → enums.js} +0 -0
- /package/dist/{manager/types.js → camera/frames.js} +0 -0
- /package/dist/{plugin/types.js → internal/camera-config-internal.js} +0 -0
- /package/dist/{service/services.js → internal/camera-enums.js} +0 -0
- /package/dist/{service/types.js → internal/camera-wire.js} +0 -0
- /package/dist/{storage/schema.js → internal/manager-rpc.js} +0 -0
- /package/dist/{storage/storages.js → internal/sensor-rpc.js} +0 -0
package/dist/sensor/battery.js
CHANGED
|
@@ -1,101 +1,115 @@
|
|
|
1
|
-
import { Sensor } from './base.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Battery Capability enum
|
|
5
|
-
* Describes what Battery features this sensor supports
|
|
6
|
-
* Note: "level" property is always available (standard)
|
|
7
|
-
*/
|
|
1
|
+
import { Sensor, SensorType, SensorCategory } from './base.js';
|
|
2
|
+
/** Optional capabilities for battery info sensors */
|
|
8
3
|
export var BatteryCapability;
|
|
9
4
|
(function (BatteryCapability) {
|
|
10
|
-
/**
|
|
5
|
+
/** Sensor reports low-battery alerts */
|
|
11
6
|
BatteryCapability["LowBattery"] = "lowBattery";
|
|
12
|
-
/**
|
|
7
|
+
/** Sensor reports charging state */
|
|
13
8
|
BatteryCapability["Charging"] = "charging";
|
|
14
9
|
})(BatteryCapability || (BatteryCapability = {}));
|
|
15
10
|
/**
|
|
16
|
-
*
|
|
11
|
+
* Properties for battery info sensors
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
17
14
|
*/
|
|
18
15
|
export var BatteryProperty;
|
|
19
16
|
(function (BatteryProperty) {
|
|
17
|
+
/** Battery level percentage (0–100) */
|
|
20
18
|
BatteryProperty["Level"] = "level";
|
|
19
|
+
/** Current charging state */
|
|
21
20
|
BatteryProperty["Charging"] = "charging";
|
|
21
|
+
/** Whether battery is critically low */
|
|
22
22
|
BatteryProperty["Low"] = "low";
|
|
23
23
|
})(BatteryProperty || (BatteryProperty = {}));
|
|
24
|
+
/** Battery charging state */
|
|
25
|
+
export var ChargingState;
|
|
26
|
+
(function (ChargingState) {
|
|
27
|
+
ChargingState["NotChargeable"] = "NOT_CHARGEABLE";
|
|
28
|
+
ChargingState["NotCharging"] = "NOT_CHARGING";
|
|
29
|
+
ChargingState["Charging"] = "CHARGING";
|
|
30
|
+
ChargingState["Full"] = "FULL";
|
|
31
|
+
})(ChargingState || (ChargingState = {}));
|
|
24
32
|
/**
|
|
25
|
-
* Battery
|
|
33
|
+
* Battery info sensor. Reports battery level, charging state, and low-battery alerts.
|
|
26
34
|
*
|
|
27
|
-
*
|
|
35
|
+
* Plugin authors call `setLevel(value)`, `setCharging(state)`, and `setLow(value)`
|
|
36
|
+
* to push updates from the device.
|
|
28
37
|
*/
|
|
38
|
+
// prettier-ignore
|
|
29
39
|
export class BatteryInfo extends Sensor {
|
|
30
40
|
type = SensorType.Battery;
|
|
31
41
|
category = SensorCategory.Info;
|
|
32
|
-
name;
|
|
33
|
-
/** Threshold for low battery warning (default: 20%) */
|
|
34
|
-
lowBatteryThreshold = 20;
|
|
35
42
|
constructor(name = 'Battery') {
|
|
36
|
-
super();
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
super(name);
|
|
44
|
+
this._writeState({
|
|
45
|
+
[BatteryProperty.Level]: 100,
|
|
46
|
+
[BatteryProperty.Charging]: ChargingState.NotCharging,
|
|
47
|
+
[BatteryProperty.Low]: false,
|
|
48
|
+
});
|
|
42
49
|
}
|
|
43
|
-
// ========== Properties (Getter/Setter Pairs) ==========
|
|
44
|
-
/** Battery level (0-100) */
|
|
45
50
|
get level() {
|
|
46
|
-
return this.
|
|
47
|
-
}
|
|
48
|
-
/** Set battery level (0-100) */
|
|
49
|
-
set level(value) {
|
|
50
|
-
const clampedValue = Math.max(0, Math.min(100, value));
|
|
51
|
-
this.props.level = clampedValue;
|
|
52
|
-
// Auto-update low battery state
|
|
53
|
-
this.props.low = clampedValue <= this.lowBatteryThreshold;
|
|
51
|
+
return this.props.level;
|
|
54
52
|
}
|
|
55
|
-
/** Charging state */
|
|
56
53
|
get charging() {
|
|
57
|
-
return this.
|
|
54
|
+
return this.props.charging;
|
|
58
55
|
}
|
|
59
|
-
/** Set charging state */
|
|
60
|
-
set charging(value) {
|
|
61
|
-
this.props.charging = value;
|
|
62
|
-
}
|
|
63
|
-
/** Whether battery is low */
|
|
64
56
|
get low() {
|
|
65
|
-
return this.
|
|
57
|
+
return this.props.low;
|
|
66
58
|
}
|
|
67
|
-
/**
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Report a new battery level (percentage). Clamped to [0, 100].
|
|
61
|
+
*
|
|
62
|
+
* @param value - Battery level percentage in the range 0–100.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* battery.setLevel(87);
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
setLevel(value) {
|
|
70
|
+
this._writeState({ [BatteryProperty.Level]: Math.max(0, Math.min(100, value)) });
|
|
70
71
|
}
|
|
71
|
-
// ========== Convenience Methods ==========
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
73
|
+
* Report the current charging state.
|
|
74
74
|
*
|
|
75
|
-
* @param
|
|
75
|
+
* @param value - Current charging state from the {@link ChargingState} enum.
|
|
76
76
|
*
|
|
77
|
-
* @
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { ChargingState } from '@camera.ui/sdk';
|
|
80
|
+
* battery.setCharging(ChargingState.Charging);
|
|
81
|
+
* ```
|
|
78
82
|
*/
|
|
79
|
-
|
|
80
|
-
this.
|
|
81
|
-
if (charging !== undefined) {
|
|
82
|
-
this.props.charging = charging;
|
|
83
|
-
}
|
|
83
|
+
setCharging(value) {
|
|
84
|
+
this._writeState({ [BatteryProperty.Charging]: value });
|
|
84
85
|
}
|
|
85
86
|
/**
|
|
86
|
-
*
|
|
87
|
+
* Report whether the battery is critically low.
|
|
88
|
+
*
|
|
89
|
+
* @param value - True when the battery has crossed the low-battery threshold.
|
|
87
90
|
*
|
|
88
|
-
* @
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* battery.setLow(true);
|
|
94
|
+
* ```
|
|
89
95
|
*/
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
setLow(value) {
|
|
97
|
+
this._writeState({ [BatteryProperty.Low]: value });
|
|
92
98
|
}
|
|
93
99
|
/**
|
|
94
|
-
*
|
|
100
|
+
* Read-only sensor: external writes are ignored. State is reported via `setLevel`/`setCharging`/`setLow`.
|
|
101
|
+
*
|
|
102
|
+
* Called by the cross-process plugin host when a generic property write is received.
|
|
103
|
+
* Battery sensors have no externally writable properties, so the parameters are
|
|
104
|
+
* unused (underscore-prefixed) and the call is a no-op.
|
|
105
|
+
*
|
|
106
|
+
* @param _property - Unused — battery sensors expose no writable properties.
|
|
107
|
+
*
|
|
108
|
+
* @param _value - Unused — battery sensors expose no writable properties.
|
|
95
109
|
*
|
|
96
|
-
* @
|
|
110
|
+
* @internal
|
|
97
111
|
*/
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
updateValue(_property, _value) {
|
|
113
|
+
// No-op — battery state is reported by the plugin, not set externally.
|
|
100
114
|
}
|
|
101
115
|
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Sensor, SensorType, SensorCategory } from './base.js';
|
|
2
|
+
/**
|
|
3
|
+
* Property names of a classifier sensor.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export var ClassifierProperty;
|
|
8
|
+
(function (ClassifierProperty) {
|
|
9
|
+
/** Whether any classification result is active. */
|
|
10
|
+
ClassifierProperty["Detected"] = "detected";
|
|
11
|
+
/** List of classification results with labels and confidence. */
|
|
12
|
+
ClassifierProperty["Detections"] = "detections";
|
|
13
|
+
/** Unique labels of the current detections (auto-derived when reporting detections). */
|
|
14
|
+
ClassifierProperty["Labels"] = "labels";
|
|
15
|
+
})(ClassifierProperty || (ClassifierProperty = {}));
|
|
16
|
+
/**
|
|
17
|
+
* General-purpose image classifier sensor.
|
|
18
|
+
*
|
|
19
|
+
* Plugin authors call `reportDetections(list)` to push classification results.
|
|
20
|
+
* `detected` and `labels` are auto-derived from the detection list.
|
|
21
|
+
*/
|
|
22
|
+
export class ClassifierSensor extends Sensor {
|
|
23
|
+
type = SensorType.Classifier;
|
|
24
|
+
category = SensorCategory.Sensor;
|
|
25
|
+
_requiresFrames = false;
|
|
26
|
+
constructor(name = 'Classifier') {
|
|
27
|
+
super(name);
|
|
28
|
+
this._writeState({
|
|
29
|
+
[ClassifierProperty.Detected]: false,
|
|
30
|
+
[ClassifierProperty.Detections]: [],
|
|
31
|
+
[ClassifierProperty.Labels]: [],
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/** Whether any classification result is active. */
|
|
35
|
+
get detected() {
|
|
36
|
+
return this.props.detected;
|
|
37
|
+
}
|
|
38
|
+
/** Current detection list. */
|
|
39
|
+
get detections() {
|
|
40
|
+
return this.props.detections;
|
|
41
|
+
}
|
|
42
|
+
/** Unique labels of the current detections. */
|
|
43
|
+
get labels() {
|
|
44
|
+
return this.props.labels;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Report classification results. Auto-derives `detected` and `labels` from the list.
|
|
48
|
+
*
|
|
49
|
+
* - `reportDetections(true)` — generic classification trigger. The SDK
|
|
50
|
+
* synthesizes a single full-frame detection with empty attribute/subAttribute.
|
|
51
|
+
* - `reportDetections(true, [...])` — explicit classifier detections.
|
|
52
|
+
* - `reportDetections(false)` — clear.
|
|
53
|
+
*
|
|
54
|
+
* @param detected - Whether any classification result is active.
|
|
55
|
+
*
|
|
56
|
+
* @param detections - Optional explicit classifier detections to publish.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* import type { ClassifierDetection } from '@camera.ui/sdk';
|
|
61
|
+
* sensor.reportDetections(true, [
|
|
62
|
+
* {
|
|
63
|
+
* label: 'animal',
|
|
64
|
+
* confidence: 0.88,
|
|
65
|
+
* box: { x: 0.1, y: 0.2, width: 0.3, height: 0.4 },
|
|
66
|
+
* attribute: 'bird',
|
|
67
|
+
* subAttribute: 'woodpecker',
|
|
68
|
+
* } satisfies ClassifierDetection,
|
|
69
|
+
* ]);
|
|
70
|
+
* sensor.reportDetections(false);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
reportDetections(detected, detections) {
|
|
74
|
+
const list = this._normalizeReportedDetections(detected, detections, 'motion', { attribute: '', subAttribute: '' });
|
|
75
|
+
const labels = Array.from(new Set(list.map((d) => d.label)));
|
|
76
|
+
this._writeState({
|
|
77
|
+
[ClassifierProperty.Detected]: detected,
|
|
78
|
+
[ClassifierProperty.Detections]: list,
|
|
79
|
+
[ClassifierProperty.Labels]: labels,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Explicitly clear classifier state (detected = false, detections = [], labels = []).
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* sensor.clearDetections();
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
clearDetections() {
|
|
91
|
+
this.reportDetections(false);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Read-only sensor: external writes are ignored. State is reported via `reportDetections`.
|
|
95
|
+
*
|
|
96
|
+
* Called by the cross-process plugin host when a generic property write is received.
|
|
97
|
+
* Classifier sensors have no externally writable properties, so the parameters are
|
|
98
|
+
* unused (underscore-prefixed) and the call is a no-op.
|
|
99
|
+
*
|
|
100
|
+
* @param _property - Unused — classifier sensors expose no writable properties.
|
|
101
|
+
*
|
|
102
|
+
* @param _value - Unused — classifier sensors expose no writable properties.
|
|
103
|
+
*
|
|
104
|
+
* @internal
|
|
105
|
+
*/
|
|
106
|
+
updateValue(_property, _value) {
|
|
107
|
+
// No-op — classifier state is reported by the plugin, not set externally.
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Classifier detector that receives video frames from the backend pipeline.
|
|
112
|
+
* Extend this class and implement {@link detectClassifications} to run image
|
|
113
|
+
* classification models against trigger regions.
|
|
114
|
+
*/
|
|
115
|
+
export class ClassifierDetectorSensor extends ClassifierSensor {
|
|
116
|
+
_requiresFrames = true;
|
|
117
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Sensor, SensorType, SensorCategory } from './base.js';
|
|
2
|
+
/**
|
|
3
|
+
* CLIP detector sensor that receives video frames and generates semantic
|
|
4
|
+
* embeddings. Extend this class and implement {@link detectEmbeddings} to
|
|
5
|
+
* produce CLIP embeddings for downstream semantic search.
|
|
6
|
+
*/
|
|
7
|
+
export class ClipDetectorSensor extends Sensor {
|
|
8
|
+
type = SensorType.Clip;
|
|
9
|
+
category = SensorCategory.Sensor;
|
|
10
|
+
_requiresFrames = true;
|
|
11
|
+
constructor(name = 'CLIP Sensor') {
|
|
12
|
+
super(name);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Frame-only sensor: no externally writable properties.
|
|
16
|
+
*
|
|
17
|
+
* Called by the cross-process plugin host when a generic property write is received.
|
|
18
|
+
* CLIP detectors have no writable properties, so the parameters are unused
|
|
19
|
+
* (underscore-prefixed) and the call is a no-op.
|
|
20
|
+
*
|
|
21
|
+
* @param _property - Unused — CLIP detectors expose no writable properties.
|
|
22
|
+
*
|
|
23
|
+
* @param _value - Unused — CLIP detectors expose no writable properties.
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
updateValue(_property, _value) {
|
|
28
|
+
// No-op — clip detector has no state.
|
|
29
|
+
}
|
|
30
|
+
}
|
package/dist/sensor/contact.js
CHANGED
|
@@ -1,33 +1,52 @@
|
|
|
1
|
-
import { Sensor } from './base.js';
|
|
2
|
-
import { SensorCategory, SensorType } from './types.js';
|
|
1
|
+
import { Sensor, SensorType, SensorCategory } from './base.js';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
3
|
+
* Properties for contact sensors
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
5
6
|
*/
|
|
6
7
|
export var ContactProperty;
|
|
7
8
|
(function (ContactProperty) {
|
|
9
|
+
/** Whether the contact is open (true = open, false = closed) */
|
|
8
10
|
ContactProperty["Detected"] = "detected";
|
|
9
11
|
})(ContactProperty || (ContactProperty = {}));
|
|
10
|
-
/**
|
|
11
|
-
* Contact Sensor
|
|
12
|
-
*
|
|
13
|
-
* Detects contact state (open/closed) for doors, windows, etc.
|
|
14
|
-
*/
|
|
12
|
+
/** Contact sensor for door/window open-close state */
|
|
15
13
|
export class ContactSensor extends Sensor {
|
|
16
14
|
type = SensorType.Contact;
|
|
17
15
|
category = SensorCategory.Sensor;
|
|
18
|
-
name;
|
|
19
16
|
constructor(name = 'Contact Sensor') {
|
|
20
|
-
super();
|
|
21
|
-
this.
|
|
22
|
-
// Initialize defaults
|
|
23
|
-
this.props.detected = false;
|
|
17
|
+
super(name);
|
|
18
|
+
this._writeState({ [ContactProperty.Detected]: false });
|
|
24
19
|
}
|
|
25
|
-
/** Whether contact is detected (closed) */
|
|
26
20
|
get detected() {
|
|
27
|
-
return this.
|
|
21
|
+
return this.props.detected;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Report contact state (true = open, false = closed).
|
|
25
|
+
*
|
|
26
|
+
* @param value - True when the contact is open, false when closed.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* contact.setDetected(true);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
setDetected(value) {
|
|
34
|
+
this._writeState({ [ContactProperty.Detected]: value });
|
|
28
35
|
}
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
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
|
+
* Contact 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 — contact sensors expose no writable properties.
|
|
44
|
+
*
|
|
45
|
+
* @param _value - Unused — contact sensors expose no writable properties.
|
|
46
|
+
*
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
updateValue(_property, _value) {
|
|
50
|
+
// No-op — contact state is reported by the plugin, not set externally.
|
|
32
51
|
}
|
|
33
52
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Built-in detection label types recognized across the system. */
|
|
2
|
+
export const DETECTION_LABELS = ['motion', 'person', 'vehicle', 'animal', 'package', 'audio'];
|
|
3
|
+
/** Detection attribute types used to mark sub-detections (face, license plate, ...). */
|
|
4
|
+
export const DETECTION_ATTRIBUTES = ['face', 'license_plate'];
|
package/dist/sensor/doorbell.js
CHANGED
|
@@ -1,63 +1,77 @@
|
|
|
1
|
-
import { Sensor } from './base.js';
|
|
2
|
-
import { SensorCategory, SensorType } from './types.js';
|
|
1
|
+
import { Sensor, SensorType, SensorCategory } from './base.js';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
3
|
+
* Properties for doorbell triggers
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
5
6
|
*/
|
|
6
7
|
export var DoorbellProperty;
|
|
7
8
|
(function (DoorbellProperty) {
|
|
9
|
+
/** Whether the doorbell is currently ringing */
|
|
8
10
|
DoorbellProperty["Ring"] = "ring";
|
|
9
11
|
})(DoorbellProperty || (DoorbellProperty = {}));
|
|
12
|
+
/** Auto-reset duration after `trigger()` is called (ms). */
|
|
13
|
+
export const RING_AUTO_RESET_MS = 2000;
|
|
10
14
|
/**
|
|
11
|
-
* Doorbell
|
|
15
|
+
* Doorbell trigger sensor.
|
|
12
16
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
17
|
+
* Plugin authors call `trigger()` to fire a doorbell event. The `ring` property
|
|
18
|
+
* is set to true and automatically reset to false after a short delay
|
|
19
|
+
* ({@link RING_AUTO_RESET_MS}). Calling `trigger()` again while still ringing
|
|
20
|
+
* resets the timer (extends the ring phase).
|
|
15
21
|
*/
|
|
16
22
|
export class DoorbellTrigger extends Sensor {
|
|
17
23
|
type = SensorType.Doorbell;
|
|
18
24
|
category = SensorCategory.Trigger;
|
|
19
|
-
|
|
20
|
-
_resetTimeout;
|
|
25
|
+
_ringResetTimer;
|
|
21
26
|
constructor(name = 'Doorbell') {
|
|
22
|
-
super();
|
|
23
|
-
this.
|
|
24
|
-
// Initialize defaults
|
|
25
|
-
this.props.ring = false;
|
|
27
|
+
super(name);
|
|
28
|
+
this._writeState({ [DoorbellProperty.Ring]: false });
|
|
26
29
|
}
|
|
27
|
-
// ========== Properties (Getter/Setter Pairs) ==========
|
|
28
|
-
/** Whether doorbell is currently ringing */
|
|
29
30
|
get ring() {
|
|
30
|
-
return this.
|
|
31
|
+
return this.props.ring;
|
|
31
32
|
}
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Trigger a doorbell ring. Sets `ring = true` and auto-resets after a
|
|
35
|
+
* short delay. Re-triggering while still ringing extends the ring phase.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* doorbell.trigger();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
trigger() {
|
|
43
|
+
if (this._ringResetTimer) {
|
|
44
|
+
clearTimeout(this._ringResetTimer);
|
|
45
|
+
}
|
|
46
|
+
this._writeState({ [DoorbellProperty.Ring]: true });
|
|
47
|
+
this._ringResetTimer = setTimeout(() => {
|
|
48
|
+
this._ringResetTimer = undefined;
|
|
49
|
+
this._writeState({ [DoorbellProperty.Ring]: false });
|
|
50
|
+
}, RING_AUTO_RESET_MS);
|
|
35
51
|
}
|
|
36
|
-
// ========== Convenience Methods ==========
|
|
37
52
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
53
|
+
* Cross-process consumer entry point. Writing `ring=true` (any truthy value)
|
|
54
|
+
* dispatches to `trigger()` so a UI test button or external automation can
|
|
55
|
+
* fire the doorbell using the same flow as a real hardware ring (auto-reset
|
|
56
|
+
* included). Writing `ring=false` is ignored — the auto-reset timer owns
|
|
57
|
+
* the off transition.
|
|
58
|
+
*
|
|
59
|
+
* @param property - Property name to write.
|
|
60
|
+
*
|
|
61
|
+
* @param value - New value for the property.
|
|
40
62
|
*
|
|
41
|
-
* @
|
|
63
|
+
* @internal
|
|
42
64
|
*/
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
clearTimeout(this._resetTimeout);
|
|
65
|
+
updateValue(property, value) {
|
|
66
|
+
if (property === DoorbellProperty.Ring && value) {
|
|
67
|
+
this.trigger();
|
|
47
68
|
}
|
|
48
|
-
this.props.ring = true;
|
|
49
|
-
// Auto-reset after duration
|
|
50
|
-
this._resetTimeout = setTimeout(() => {
|
|
51
|
-
this.props.ring = false;
|
|
52
|
-
this._resetTimeout = undefined;
|
|
53
|
-
}, resetAfterMs);
|
|
54
69
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this._resetTimeout = undefined;
|
|
70
|
+
_cleanup() {
|
|
71
|
+
if (this._ringResetTimer) {
|
|
72
|
+
clearTimeout(this._ringResetTimer);
|
|
73
|
+
this._ringResetTimer = undefined;
|
|
60
74
|
}
|
|
61
|
-
|
|
75
|
+
super._cleanup();
|
|
62
76
|
}
|
|
63
77
|
}
|