hoffmation-base 3.6.1 → 3.7.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.
Files changed (37) hide show
  1. package/lib/action/airQualitySensorChangeAction.d.ts +16 -0
  2. package/lib/action/airQualitySensorChangeAction.js +15 -0
  3. package/lib/action/index.d.ts +1 -0
  4. package/lib/action/index.js +3 -1
  5. package/lib/devices/sharedFunctions/airQualitySensor.d.ts +27 -0
  6. package/lib/devices/sharedFunctions/airQualitySensor.js +87 -0
  7. package/lib/devices/sharedFunctions/index.d.ts +1 -0
  8. package/lib/devices/sharedFunctions/index.js +1 -0
  9. package/lib/devices/unifi/index.d.ts +1 -0
  10. package/lib/devices/unifi/index.js +1 -0
  11. package/lib/devices/unifi/own-unifi-air-quality-sensor.d.ts +81 -0
  12. package/lib/devices/unifi/own-unifi-air-quality-sensor.js +164 -0
  13. package/lib/devices/unifi/own-unifi-camera.d.ts +6 -5
  14. package/lib/devices/unifi/own-unifi-camera.js +14 -24
  15. package/lib/devices/unifi/protect-module.d.ts +11 -0
  16. package/lib/devices/unifi/protect-module.js +16 -0
  17. package/lib/devices/unifi/unifi-logger.d.ts +5 -5
  18. package/lib/devices/unifi/unifi-logger.js +9 -8
  19. package/lib/devices/unifi/unifi-protect.d.ts +38 -7
  20. package/lib/devices/unifi/unifi-protect.js +199 -66
  21. package/lib/enums/DeviceCapability.d.ts +1 -0
  22. package/lib/enums/DeviceCapability.js +1 -0
  23. package/lib/enums/commandType.d.ts +1 -0
  24. package/lib/enums/commandType.js +1 -0
  25. package/lib/enums/deviceType.d.ts +1 -0
  26. package/lib/enums/deviceType.js +1 -0
  27. package/lib/interfaces/baseDevices/iAirQualityCollector.d.ts +23 -0
  28. package/lib/interfaces/baseDevices/iAirQualityCollector.js +2 -0
  29. package/lib/interfaces/baseDevices/iAirQualitySensor.d.ts +97 -0
  30. package/lib/interfaces/baseDevices/iAirQualitySensor.js +7 -0
  31. package/lib/interfaces/baseDevices/index.d.ts +2 -0
  32. package/lib/interfaces/baseDevices/index.js +2 -0
  33. package/lib/interfaces/iPersist.d.ts +6 -1
  34. package/lib/services/dbo/postgreSqlPersist.d.ts +3 -1
  35. package/lib/services/dbo/postgreSqlPersist.js +34 -1
  36. package/lib/tsconfig.tsbuildinfo +1 -1
  37. package/package.json +4 -3
@@ -0,0 +1,16 @@
1
+ import { BaseAction } from './baseAction';
2
+ import { CommandType } from '../enums';
3
+ import { iAirQualityCollector, iAirQualityReadings } from '../interfaces';
4
+ export declare class AirQualitySensorChangeAction extends BaseAction {
5
+ /** @inheritDoc */
6
+ type: CommandType;
7
+ /**
8
+ * The new readings of the sensor
9
+ */
10
+ readonly newReadings: iAirQualityReadings;
11
+ /**
12
+ * The sensor that triggered the action
13
+ */
14
+ readonly sensor: iAirQualityCollector;
15
+ constructor(sensor: iAirQualityCollector, newReadings: iAirQualityReadings);
16
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AirQualitySensorChangeAction = void 0;
4
+ const baseAction_1 = require("./baseAction");
5
+ const enums_1 = require("../enums");
6
+ class AirQualitySensorChangeAction extends baseAction_1.BaseAction {
7
+ constructor(sensor, newReadings) {
8
+ super(enums_1.CommandSource.Automatic, `${sensor.customName} detected an air quality index of ${newReadings.aqi}`);
9
+ /** @inheritDoc */
10
+ this.type = enums_1.CommandType.AirQualitySensorChangeAction;
11
+ this.newReadings = newReadings;
12
+ this.sensor = sensor;
13
+ }
14
+ }
15
+ exports.AirQualitySensorChangeAction = AirQualitySensorChangeAction;
@@ -1,3 +1,4 @@
1
+ export { AirQualitySensorChangeAction } from './airQualitySensorChangeAction';
1
2
  export { BaseAction } from './baseAction';
2
3
  export { HumiditySensorChangeAction } from './humiditySensorChangeAction';
3
4
  export { MotionSensorAction } from './motionSensorAction';
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DingSensorAction = exports.HandleChangeAction = exports.PresenceGroupAnyMovementAction = exports.BatteryLevelChangeAction = exports.ActuatorChangeAction = exports.TemperatureSensorChangeAction = exports.ShutterPositionChangedAction = exports.PresenceGroupFirstEnterAction = exports.PresenceGroupLastLeftAction = exports.MotionSensorAction = exports.HumiditySensorChangeAction = exports.BaseAction = void 0;
3
+ exports.DingSensorAction = exports.HandleChangeAction = exports.PresenceGroupAnyMovementAction = exports.BatteryLevelChangeAction = exports.ActuatorChangeAction = exports.TemperatureSensorChangeAction = exports.ShutterPositionChangedAction = exports.PresenceGroupFirstEnterAction = exports.PresenceGroupLastLeftAction = exports.MotionSensorAction = exports.HumiditySensorChangeAction = exports.BaseAction = exports.AirQualitySensorChangeAction = void 0;
4
+ var airQualitySensorChangeAction_1 = require("./airQualitySensorChangeAction");
5
+ Object.defineProperty(exports, "AirQualitySensorChangeAction", { enumerable: true, get: function () { return airQualitySensorChangeAction_1.AirQualitySensorChangeAction; } });
4
6
  var baseAction_1 = require("./baseAction");
5
7
  Object.defineProperty(exports, "BaseAction", { enumerable: true, get: function () { return baseAction_1.BaseAction; } });
6
8
  var humiditySensorChangeAction_1 = require("./humiditySensorChangeAction");
@@ -0,0 +1,27 @@
1
+ import { iAirQualityCollector, iAirQualityReadings, iAirQualitySensor } from '../../interfaces';
2
+ import { AirQualitySensorChangeAction } from '../../action';
3
+ export declare class AirQualitySensor implements iAirQualitySensor {
4
+ private readonly _device;
5
+ /** @inheritDoc */
6
+ readonly jsonOmitKeys: string[];
7
+ /** @inheritDoc */
8
+ lastSeen: number;
9
+ private readonly _readings;
10
+ private _airQualityCallbacks;
11
+ private readonly _persistAirQualitySensorInterval;
12
+ constructor(_device: iAirQualityCollector);
13
+ /** @inheritDoc */
14
+ get readings(): iAirQualityReadings;
15
+ /** @inheritDoc */
16
+ update(readings: Partial<iAirQualityReadings>): void;
17
+ /** @inheritDoc */
18
+ reports(metric: keyof iAirQualityReadings): boolean;
19
+ /** @inheritDoc */
20
+ persist(): void;
21
+ /** @inheritDoc */
22
+ addAirQualityCallback(pCallback: (action: AirQualitySensorChangeAction) => void): void;
23
+ /** @inheritDoc */
24
+ dispose(): void;
25
+ /** @inheritDoc */
26
+ toJSON(): Partial<AirQualitySensor>;
27
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AirQualitySensor = void 0;
4
+ const interfaces_1 = require("../../interfaces");
5
+ const action_1 = require("../../action");
6
+ const utils_1 = require("../../utils");
7
+ const services_1 = require("../../services");
8
+ class AirQualitySensor {
9
+ constructor(_device) {
10
+ this._device = _device;
11
+ /** @inheritDoc */
12
+ this.jsonOmitKeys = ['_device'];
13
+ /** @inheritDoc */
14
+ this.lastSeen = 0;
15
+ this._readings = {
16
+ aqi: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
17
+ co2: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
18
+ nox: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
19
+ pm1p0: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
20
+ pm2p5: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
21
+ pm4p0: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
22
+ pm10p0: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
23
+ tvoc: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
24
+ vape: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
25
+ voc: interfaces_1.UNDEFINED_AIR_QUALITY_VALUE,
26
+ };
27
+ this._airQualityCallbacks = [];
28
+ this._persistAirQualitySensorInterval = utils_1.Utils.guardedInterval(() => {
29
+ this.persist();
30
+ }, 5 * 60 * 1000, this, false);
31
+ }
32
+ /** @inheritDoc */
33
+ get readings() {
34
+ return { ...this._readings };
35
+ }
36
+ /** @inheritDoc */
37
+ update(readings) {
38
+ this.lastSeen = utils_1.Utils.nowMS();
39
+ let changed = false;
40
+ for (const [key, value] of Object.entries(readings)) {
41
+ if (value === undefined || this._readings[key] === value) {
42
+ continue;
43
+ }
44
+ this._readings[key] = value;
45
+ changed = true;
46
+ }
47
+ if (!changed) {
48
+ // The controller repeats unchanged readings every few seconds --> don't bother the consumers with those.
49
+ return;
50
+ }
51
+ const snapshot = this.readings;
52
+ for (const cb of this._airQualityCallbacks) {
53
+ cb(new action_1.AirQualitySensorChangeAction(this._device, snapshot));
54
+ }
55
+ }
56
+ /** @inheritDoc */
57
+ reports(metric) {
58
+ return this._readings[metric] !== interfaces_1.UNDEFINED_AIR_QUALITY_VALUE;
59
+ }
60
+ /** @inheritDoc */
61
+ persist() {
62
+ var _a;
63
+ if (this.lastSeen === 0) {
64
+ // Nothing was ever reported --> persisting would only write a row of undefined values.
65
+ return;
66
+ }
67
+ (_a = services_1.Persistence.dbo) === null || _a === void 0 ? void 0 : _a.persistAirQualitySensor(this._device);
68
+ }
69
+ /** @inheritDoc */
70
+ addAirQualityCallback(pCallback) {
71
+ this._airQualityCallbacks.push(pCallback);
72
+ if (this.lastSeen > 0) {
73
+ pCallback(new action_1.AirQualitySensorChangeAction(this._device, this.readings));
74
+ }
75
+ }
76
+ /** @inheritDoc */
77
+ dispose() {
78
+ if (this._persistAirQualitySensorInterval) {
79
+ clearInterval(this._persistAirQualitySensorInterval);
80
+ }
81
+ }
82
+ /** @inheritDoc */
83
+ toJSON() {
84
+ return utils_1.Utils.jsonFilter(this, this.jsonOmitKeys);
85
+ }
86
+ }
87
+ exports.AirQualitySensor = AirQualitySensor;
@@ -1,3 +1,4 @@
1
+ export * from './airQualitySensor';
1
2
  export * from './battery';
2
3
  export * from './handleSensor';
3
4
  export * from './humiditySensor';
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./airQualitySensor"), exports);
17
18
  __exportStar(require("./battery"), exports);
18
19
  __exportStar(require("./handleSensor"), exports);
19
20
  __exportStar(require("./humiditySensor"), exports);
@@ -1,3 +1,4 @@
1
+ export * from './own-unifi-air-quality-sensor';
1
2
  export * from './own-unifi-camera';
2
3
  export * from './unifi-protect';
3
4
  export * from './unifi-access';
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./own-unifi-air-quality-sensor"), exports);
17
18
  __exportStar(require("./own-unifi-camera"), exports);
18
19
  __exportStar(require("./unifi-protect"), exports);
19
20
  __exportStar(require("./unifi-access"), exports);
@@ -0,0 +1,81 @@
1
+ import type { ProtectSensorConfig, Sensor } from 'unifi-protect';
2
+ import { iAirQualityCollector, iAirQualityReadings, iAirQualitySensor, iHumidityCollector, iHumiditySensor, iTemperatureCollector } from '../../interfaces';
3
+ import { AirQualitySensorChangeAction, HumiditySensorChangeAction, TemperatureSensorChangeAction } from '../../action';
4
+ import { TemperatureSensor } from '../sharedFunctions';
5
+ import { RoomBaseDevice } from '../RoomBaseDevice';
6
+ /**
7
+ * A UniFi Protect "UP Air Quality" sensor.
8
+ *
9
+ * The device reports temperature and humidity alongside its air quality metrics, so it acts as all three
10
+ * collectors at once and its temperature/humidity history lands in the database like any other sensor.
11
+ */
12
+ export declare class OwnUnifiAirQualitySensor extends RoomBaseDevice implements iTemperatureCollector, iHumidityCollector, iAirQualityCollector {
13
+ /**
14
+ * The name of the sensor as written in Unifi-Protect
15
+ */
16
+ readonly unifiSensorName: string;
17
+ /**
18
+ * The human readable name of this device
19
+ */
20
+ readonly name: string;
21
+ /** @inheritDoc */
22
+ temperatureSensor: TemperatureSensor;
23
+ /** @inheritDoc */
24
+ humiditySensor: iHumiditySensor;
25
+ /** @inheritDoc */
26
+ airQualitySensor: iAirQualitySensor;
27
+ protected _lastUpdate: Date;
28
+ private _sensor;
29
+ private _lastReportedTemperature;
30
+ private _lastReportedHumidity;
31
+ constructor(name: string, roomName: string, unifiSensorName: string);
32
+ /**
33
+ * The point in time this device last reported a reading.
34
+ * @returns The timestamp of the last reading
35
+ */
36
+ get lastUpdate(): Date;
37
+ /** @inheritDoc */
38
+ get airQuality(): iAirQualityReadings;
39
+ /** @inheritDoc */
40
+ get roomTemperature(): number;
41
+ /** @inheritDoc */
42
+ set roomTemperature(value: number);
43
+ /** @inheritDoc */
44
+ get humidity(): number;
45
+ /** @inheritDoc */
46
+ get iTemperature(): number;
47
+ /** @inheritDoc */
48
+ get sTemperature(): string;
49
+ /**
50
+ * Binds this device to its live Unifi-Protect projection and applies the current readings.
51
+ * @param sensor - The projection of the matching Unifi sensor
52
+ */
53
+ initialize(sensor: Sensor): void;
54
+ /**
55
+ * Applies the readings of the given sensor configuration.
56
+ * @param config - The current configuration of the Unifi sensor
57
+ */
58
+ update(config: ProtectSensorConfig): void;
59
+ /** @inheritDoc */
60
+ addAirQualityCallback(pCallback: (action: AirQualitySensorChangeAction) => void): void;
61
+ /** @inheritDoc */
62
+ addHumidityCallback(pCallback: (action: HumiditySensorChangeAction) => void): void;
63
+ /** @inheritDoc */
64
+ addTempChangeCallback(pCallback: (action: TemperatureSensorChangeAction) => void): void;
65
+ /** @inheritDoc */
66
+ onTemperaturChange(newTemperatur: number): void;
67
+ /** @inheritDoc */
68
+ dispose(): void;
69
+ /**
70
+ * Reads a single metric out of the controllers air quality readings.
71
+ *
72
+ * Kept structural on purpose: the controller reports `nox`, which the library types do not name,
73
+ * and a metric the device does not measure arrives with a `null` value. The value is rounded to one
74
+ * decimal, as the last digits of the raw reading are sensor jitter that would count as a change on
75
+ * every single update.
76
+ * @param airQuality - The air quality readings of the sensor
77
+ * @param metric - The name of the metric to read
78
+ * @returns The measured value, or undefined if the device does not report it
79
+ */
80
+ private static metricValue;
81
+ }
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OwnUnifiAirQualitySensor = void 0;
4
+ const sharedFunctions_1 = require("../sharedFunctions");
5
+ const enums_1 = require("../../enums");
6
+ const DeviceInfo_1 = require("../DeviceInfo");
7
+ const devices_1 = require("../devices");
8
+ const RoomBaseDevice_1 = require("../RoomBaseDevice");
9
+ const utils_1 = require("../../utils");
10
+ /**
11
+ * A UniFi Protect "UP Air Quality" sensor.
12
+ *
13
+ * The device reports temperature and humidity alongside its air quality metrics, so it acts as all three
14
+ * collectors at once and its temperature/humidity history lands in the database like any other sensor.
15
+ */
16
+ class OwnUnifiAirQualitySensor extends RoomBaseDevice_1.RoomBaseDevice {
17
+ constructor(name, roomName, unifiSensorName) {
18
+ const info = new DeviceInfo_1.DeviceInfo();
19
+ info.fullName = `Air Quality ${roomName} ${name}`;
20
+ info.customName = `Air Quality ${name}`;
21
+ info.room = roomName;
22
+ const allDevicesKey = `unifi-air-quality-${roomName}-${name}`;
23
+ info.allDevicesKey = allDevicesKey;
24
+ super(info, enums_1.DeviceType.UnifiAirQualitySensor);
25
+ /** @inheritDoc */
26
+ this.temperatureSensor = new sharedFunctions_1.TemperatureSensor(this);
27
+ /** @inheritDoc */
28
+ this.humiditySensor = new sharedFunctions_1.HumiditySensor(this);
29
+ /** @inheritDoc */
30
+ this.airQualitySensor = new sharedFunctions_1.AirQualitySensor(this);
31
+ this._lastUpdate = new Date(0);
32
+ // @ts-expect-error Sensor-Projektion wird später verwendet
33
+ this._sensor = null;
34
+ this._lastReportedTemperature = undefined;
35
+ this._lastReportedHumidity = undefined;
36
+ this.deviceCapabilities.push(enums_1.DeviceCapability.temperatureSensor);
37
+ this.deviceCapabilities.push(enums_1.DeviceCapability.humiditySensor);
38
+ this.deviceCapabilities.push(enums_1.DeviceCapability.airQualitySensor);
39
+ this.name = name;
40
+ this.unifiSensorName = unifiSensorName;
41
+ devices_1.Devices.alLDevices[allDevicesKey] = this;
42
+ }
43
+ /**
44
+ * The point in time this device last reported a reading.
45
+ * @returns The timestamp of the last reading
46
+ */
47
+ get lastUpdate() {
48
+ return this._lastUpdate;
49
+ }
50
+ /** @inheritDoc */
51
+ get airQuality() {
52
+ return this.airQualitySensor.readings;
53
+ }
54
+ /** @inheritDoc */
55
+ get roomTemperature() {
56
+ return this.temperatureSensor.roomTemperature;
57
+ }
58
+ /** @inheritDoc */
59
+ set roomTemperature(value) {
60
+ this.temperatureSensor.roomTemperature = value;
61
+ }
62
+ /** @inheritDoc */
63
+ get humidity() {
64
+ return this.humiditySensor.humidity;
65
+ }
66
+ /** @inheritDoc */
67
+ get iTemperature() {
68
+ return this.temperatureSensor.temperature;
69
+ }
70
+ /** @inheritDoc */
71
+ get sTemperature() {
72
+ return `${this.temperatureSensor.temperature}°C`;
73
+ }
74
+ /**
75
+ * Binds this device to its live Unifi-Protect projection and applies the current readings.
76
+ * @param sensor - The projection of the matching Unifi sensor
77
+ */
78
+ initialize(sensor) {
79
+ this._sensor = sensor;
80
+ this.update(sensor.config);
81
+ }
82
+ /**
83
+ * Applies the readings of the given sensor configuration.
84
+ * @param config - The current configuration of the Unifi sensor
85
+ */
86
+ update(config) {
87
+ const airQuality = config.airQuality;
88
+ this._lastUpdate = new Date();
89
+ // The controller repeats unchanged readings every few seconds, so only a real change wakes the consumers.
90
+ const temperature = OwnUnifiAirQualitySensor.metricValue(airQuality, 'temperature');
91
+ if (temperature !== undefined) {
92
+ if (temperature !== this._lastReportedTemperature) {
93
+ this._lastReportedTemperature = temperature;
94
+ this.temperatureSensor.temperature = temperature;
95
+ }
96
+ else {
97
+ // Only the setter refreshes lastSeen, and a stale one makes the sensor discard its value after an hour.
98
+ this.temperatureSensor.lastSeen = utils_1.Utils.nowMS();
99
+ }
100
+ }
101
+ const humidity = OwnUnifiAirQualitySensor.metricValue(airQuality, 'humidity');
102
+ if (humidity !== undefined && humidity !== this._lastReportedHumidity) {
103
+ this._lastReportedHumidity = humidity;
104
+ this.humiditySensor.humidity = humidity;
105
+ }
106
+ this.airQualitySensor.update({
107
+ aqi: OwnUnifiAirQualitySensor.metricValue(airQuality, 'aqi'),
108
+ co2: OwnUnifiAirQualitySensor.metricValue(airQuality, 'co2'),
109
+ nox: OwnUnifiAirQualitySensor.metricValue(airQuality, 'nox'),
110
+ pm1p0: OwnUnifiAirQualitySensor.metricValue(airQuality, 'pm1p0'),
111
+ pm2p5: OwnUnifiAirQualitySensor.metricValue(airQuality, 'pm2p5'),
112
+ pm4p0: OwnUnifiAirQualitySensor.metricValue(airQuality, 'pm4p0'),
113
+ pm10p0: OwnUnifiAirQualitySensor.metricValue(airQuality, 'pm10p0'),
114
+ tvoc: OwnUnifiAirQualitySensor.metricValue(airQuality, 'tvoc'),
115
+ vape: OwnUnifiAirQualitySensor.metricValue(airQuality, 'vape'),
116
+ voc: OwnUnifiAirQualitySensor.metricValue(airQuality, 'voc'),
117
+ });
118
+ }
119
+ /** @inheritDoc */
120
+ addAirQualityCallback(pCallback) {
121
+ this.airQualitySensor.addAirQualityCallback(pCallback);
122
+ }
123
+ /** @inheritDoc */
124
+ addHumidityCallback(pCallback) {
125
+ this.humiditySensor.addHumidityCallback(pCallback);
126
+ }
127
+ /** @inheritDoc */
128
+ addTempChangeCallback(pCallback) {
129
+ this.temperatureSensor.addTempChangeCallback(pCallback);
130
+ }
131
+ /** @inheritDoc */
132
+ onTemperaturChange(newTemperatur) {
133
+ this.roomTemperature = newTemperatur;
134
+ }
135
+ /** @inheritDoc */
136
+ dispose() {
137
+ this.temperatureSensor.dispose();
138
+ this.humiditySensor.dispose();
139
+ this.airQualitySensor.dispose();
140
+ }
141
+ /**
142
+ * Reads a single metric out of the controllers air quality readings.
143
+ *
144
+ * Kept structural on purpose: the controller reports `nox`, which the library types do not name,
145
+ * and a metric the device does not measure arrives with a `null` value. The value is rounded to one
146
+ * decimal, as the last digits of the raw reading are sensor jitter that would count as a change on
147
+ * every single update.
148
+ * @param airQuality - The air quality readings of the sensor
149
+ * @param metric - The name of the metric to read
150
+ * @returns The measured value, or undefined if the device does not report it
151
+ */
152
+ static metricValue(airQuality, metric) {
153
+ if (typeof airQuality !== 'object' || airQuality === null) {
154
+ return undefined;
155
+ }
156
+ const reading = Reflect.get(airQuality, metric);
157
+ if (typeof reading !== 'object' || reading === null) {
158
+ return undefined;
159
+ }
160
+ const value = Reflect.get(reading, 'value');
161
+ return typeof value === 'number' ? utils_1.Utils.round(value, 1) : undefined;
162
+ }
163
+ }
164
+ exports.OwnUnifiAirQualitySensor = OwnUnifiAirQualitySensor;
@@ -1,5 +1,5 @@
1
1
  import { CameraDevice } from '../index';
2
- import { ProtectCameraConfig, ProtectEventAdd, ProtectEventPacket } from 'unifi-protect';
2
+ import type { Camera, TypedEvent } from 'unifi-protect';
3
3
  export declare class OwnUnifiCamera extends CameraDevice {
4
4
  /**
5
5
  * The name of the camera in Unifi
@@ -13,14 +13,15 @@ export declare class OwnUnifiCamera extends CameraDevice {
13
13
  rtspStreamLink: string;
14
14
  /** @inheritDoc */
15
15
  readonly currentImageLink: string;
16
- private _config;
16
+ private _camera;
17
17
  constructor(name: string, roomName: string, unifiCameraName: string);
18
18
  /**
19
- * @inheritDoc
19
+ * Handles a realtime event the NVR attributed to this camera.
20
+ * @param event - The typed event as classified by the NVR client
20
21
  */
21
- update(packet: ProtectEventPacket, baseEvent?: ProtectEventAdd): void;
22
+ update(event: TypedEvent): void;
22
23
  private checkForMotionUpdate;
23
- initialize(data: ProtectCameraConfig): void;
24
+ initialize(camera: Camera): void;
24
25
  protected resetPersonDetectedState(): void;
25
26
  protected resetDogDetectedState(): void;
26
27
  protected resetMovementDetectedState(): void;
@@ -14,38 +14,28 @@ class OwnUnifiCamera extends index_1.CameraDevice {
14
14
  this.rtspStreamLink = '';
15
15
  /** @inheritDoc */
16
16
  this.currentImageLink = '';
17
- // @ts-expect-error Config wird später verwendet
18
- this._config = null;
17
+ // @ts-expect-error Kamera-Projektion wird später verwendet
18
+ this._camera = null;
19
19
  this.unifiCameraName = unifiCameraName;
20
20
  }
21
21
  /**
22
- * @inheritDoc
22
+ * Handles a realtime event the NVR attributed to this camera.
23
+ * @param event - The typed event as classified by the NVR client
23
24
  */
24
- update(packet, baseEvent) {
25
- this.checkForMotionUpdate(packet, baseEvent);
25
+ update(event) {
26
+ this.checkForMotionUpdate(event);
26
27
  this._lastUpdate = new Date();
27
28
  }
28
- checkForMotionUpdate(packet, baseEvent) {
29
- var _a, _b;
30
- const payload = packet.payload;
31
- const eventAddInfo = baseEvent !== null && baseEvent !== void 0 ? baseEvent : payload;
32
- const payloadAsEventAdd = payload;
33
- if (packet.header.modelKey !== 'smartDetectObject' &&
34
- (packet.header.modelKey !== 'event' ||
35
- !['smartDetectLine', 'smartDetectZone'].includes(eventAddInfo.type) ||
36
- !((_a = payloadAsEventAdd.smartDetectTypes) !== null && _a !== void 0 ? _a : []).length)) {
37
- // this.log(LogLevel.Debug, `Ignored event: ${JSON.stringify(packet)}`);
38
- // this.log(LogLevel.Debug, `Ignored event initial Info: ${JSON.stringify(baseEvent)}`);
29
+ checkForMotionUpdate(event) {
30
+ if (event.kind !== 'smartDetect' || !event.objectTypes.length) {
31
+ // this.log(LogLevel.Debug, `Ignored event: ${JSON.stringify(event)}`);
39
32
  return;
40
33
  }
41
- this.log(enums_1.LogLevel.Debug, `Update for "${packet.header.modelKey}" to value: ${JSON.stringify(payload)}`);
42
- const detectedTypes = packet.header.modelKey === 'smartDetectObject'
43
- ? [payloadAsEventAdd.type]
44
- : ((_b = payloadAsEventAdd === null || payloadAsEventAdd === void 0 ? void 0 : payloadAsEventAdd.smartDetectTypes) !== null && _b !== void 0 ? _b : []);
45
- for (const smartDetectType of detectedTypes) {
34
+ this.log(enums_1.LogLevel.Debug, `Update for "${event.kind}" to value: ${event.objectTypes.join(', ')}`);
35
+ for (const smartDetectType of event.objectTypes) {
46
36
  switch (smartDetectType) {
47
37
  case 'licensePlate':
48
- this.log(enums_1.LogLevel.Debug, `Detected "licensePlate" Data: ${JSON.stringify(payloadAsEventAdd)}`);
38
+ this.log(enums_1.LogLevel.Debug, `Detected "licensePlate" Data: ${JSON.stringify(event.metadata)}`);
49
39
  break;
50
40
  case 'person':
51
41
  this.onNewPersonDetectedValue(true, enums_1.CommandSource.Automatic);
@@ -53,8 +43,8 @@ class OwnUnifiCamera extends index_1.CameraDevice {
53
43
  }
54
44
  }
55
45
  }
56
- initialize(data) {
57
- this._config = data;
46
+ initialize(camera) {
47
+ this._camera = camera;
58
48
  }
59
49
  resetPersonDetectedState() {
60
50
  // Nothing
@@ -0,0 +1,11 @@
1
+ type ProtectModule = typeof import('unifi-protect');
2
+ /**
3
+ * Loads the ESM-only `unifi-protect` package.
4
+ *
5
+ * Since v5 the package exposes an "import" condition only, so `require()` fails with
6
+ * ERR_PACKAGE_PATH_NOT_EXPORTED. The `Function` indirection keeps TypeScript from downleveling
7
+ * the dynamic import into a `require()` call while this project still emits CommonJS.
8
+ * @returns The module namespace, loaded once and cached.
9
+ */
10
+ export declare function loadProtectModule(): Promise<ProtectModule>;
11
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadProtectModule = loadProtectModule;
4
+ let modulePromise = null;
5
+ /**
6
+ * Loads the ESM-only `unifi-protect` package.
7
+ *
8
+ * Since v5 the package exposes an "import" condition only, so `require()` fails with
9
+ * ERR_PACKAGE_PATH_NOT_EXPORTED. The `Function` indirection keeps TypeScript from downleveling
10
+ * the dynamic import into a `require()` call while this project still emits CommonJS.
11
+ * @returns The module namespace, loaded once and cached.
12
+ */
13
+ function loadProtectModule() {
14
+ modulePromise !== null && modulePromise !== void 0 ? modulePromise : (modulePromise = Function('specifier', 'return import(specifier)')('unifi-protect'));
15
+ return modulePromise;
16
+ }
@@ -1,10 +1,10 @@
1
- import { ProtectLogging } from 'unifi-protect';
1
+ import type { ProtectLogging } from 'unifi-protect';
2
2
  import { LogSource } from '../../enums';
3
3
  export declare class UnifiLogger implements ProtectLogging {
4
4
  private readonly source;
5
5
  constructor(source: LogSource);
6
- debug(message: string, ..._parameters: unknown[]): void;
7
- error(message: string, ..._parameters: unknown[]): void;
8
- info(message: string, ..._parameters: unknown[]): void;
9
- warn(message: string, ..._parameters: unknown[]): void;
6
+ debug(message: string, ...parameters: unknown[]): void;
7
+ error(message: string, ...parameters: unknown[]): void;
8
+ info(message: string, ...parameters: unknown[]): void;
9
+ warn(message: string, ...parameters: unknown[]): void;
10
10
  }
@@ -1,29 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UnifiLogger = void 0;
4
+ const node_util_1 = require("node:util");
4
5
  const logging_1 = require("../../logging");
5
6
  const enums_1 = require("../../enums");
6
7
  class UnifiLogger {
7
8
  constructor(source) {
8
9
  this.source = source;
9
10
  }
10
- debug(message, ..._parameters) {
11
- logging_1.ServerLogService.writeLog(enums_1.LogLevel.Debug, message, {
11
+ debug(message, ...parameters) {
12
+ logging_1.ServerLogService.writeLog(enums_1.LogLevel.Debug, (0, node_util_1.format)(message, ...parameters), {
12
13
  source: this.source,
13
14
  });
14
15
  }
15
- error(message, ..._parameters) {
16
- logging_1.ServerLogService.writeLog(enums_1.LogLevel.Error, message, {
16
+ error(message, ...parameters) {
17
+ logging_1.ServerLogService.writeLog(enums_1.LogLevel.Error, (0, node_util_1.format)(message, ...parameters), {
17
18
  source: this.source,
18
19
  });
19
20
  }
20
- info(message, ..._parameters) {
21
- logging_1.ServerLogService.writeLog(enums_1.LogLevel.Info, message, {
21
+ info(message, ...parameters) {
22
+ logging_1.ServerLogService.writeLog(enums_1.LogLevel.Info, (0, node_util_1.format)(message, ...parameters), {
22
23
  source: this.source,
23
24
  });
24
25
  }
25
- warn(message, ..._parameters) {
26
- logging_1.ServerLogService.writeLog(enums_1.LogLevel.Warn, message, {
26
+ warn(message, ...parameters) {
27
+ logging_1.ServerLogService.writeLog(enums_1.LogLevel.Warn, (0, node_util_1.format)(message, ...parameters), {
27
28
  source: this.source,
28
29
  });
29
30
  }