hap-nodejs 1.1.1-beta.4 → 1.1.1-beta.6
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/@types/bonjour-hap.d.ts +53 -50
- package/@types/simple-plist.d.ts +4 -0
- package/README.md +19 -16
- package/dist/accessories/AirConditioner_accessory.js +30 -28
- package/dist/accessories/AirConditioner_accessory.js.map +1 -1
- package/dist/accessories/AppleTVRemote_accessory.js +81 -69
- package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
- package/dist/accessories/Camera_accessory.js +136 -141
- package/dist/accessories/Camera_accessory.js.map +1 -1
- package/dist/accessories/Fan_accessory.js +22 -18
- package/dist/accessories/Fan_accessory.js.map +1 -1
- package/dist/accessories/GarageDoorOpener_accessory.js +35 -33
- package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
- package/dist/accessories/Light-AdaptiveLighting_accessory.js +44 -42
- package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
- package/dist/accessories/Light_accessory.js +34 -32
- package/dist/accessories/Light_accessory.js.map +1 -1
- package/dist/accessories/Lock_accessory.js +26 -25
- package/dist/accessories/Lock_accessory.js.map +1 -1
- package/dist/accessories/MotionSensor_accessory.js +16 -13
- package/dist/accessories/MotionSensor_accessory.js.map +1 -1
- package/dist/accessories/Outlet_accessory.js +22 -20
- package/dist/accessories/Outlet_accessory.js.map +1 -1
- package/dist/accessories/SmartSpeaker_accessory.js +20 -18
- package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
- package/dist/accessories/Sprinkler_accessory.js +37 -34
- package/dist/accessories/Sprinkler_accessory.js.map +1 -1
- package/dist/accessories/TV_accessory.js +45 -43
- package/dist/accessories/TV_accessory.js.map +1 -1
- package/dist/accessories/TemperatureSensor_accessory.js +15 -12
- package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.d.ts +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.d.ts.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.js +12 -9
- package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.js +14 -11
- package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.d.ts +3 -3
- package/dist/accessories/gstreamer-audioProducer.d.ts.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.js +38 -37
- package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
- package/dist/accessories/types.d.ts +63 -63
- package/dist/accessories/types.d.ts.map +1 -1
- package/dist/accessories/types.js +87 -83
- package/dist/accessories/types.js.map +1 -1
- package/dist/index.d.ts +28 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -40
- package/dist/index.js.map +1 -1
- package/dist/internal-types.d.ts +1 -1
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/internal-types.js +21 -19
- package/dist/internal-types.js.map +1 -1
- package/dist/lib/Accessory.d.ts +37 -38
- package/dist/lib/Accessory.d.ts.map +1 -1
- package/dist/lib/Accessory.js +296 -286
- package/dist/lib/Accessory.js.map +1 -1
- package/dist/lib/Advertiser.d.ts +7 -7
- package/dist/lib/Advertiser.d.ts.map +1 -1
- package/dist/lib/Advertiser.js +136 -128
- package/dist/lib/Advertiser.js.map +1 -1
- package/dist/lib/Bridge.d.ts +1 -1
- package/dist/lib/Bridge.d.ts.map +1 -1
- package/dist/lib/Bridge.js +6 -2
- package/dist/lib/Bridge.js.map +1 -1
- package/dist/lib/Characteristic.d.ts +41 -40
- package/dist/lib/Characteristic.d.ts.map +1 -1
- package/dist/lib/Characteristic.js +208 -204
- package/dist/lib/Characteristic.js.map +1 -1
- package/dist/lib/HAPServer.d.ts +30 -31
- package/dist/lib/HAPServer.d.ts.map +1 -1
- package/dist/lib/HAPServer.js +229 -220
- package/dist/lib/HAPServer.js.map +1 -1
- package/dist/lib/Service.d.ts +22 -22
- package/dist/lib/Service.d.ts.map +1 -1
- package/dist/lib/Service.js +67 -63
- package/dist/lib/Service.js.map +1 -1
- package/dist/lib/camera/RTPProxy.d.ts +1 -2
- package/dist/lib/camera/RTPProxy.d.ts.map +1 -1
- package/dist/lib/camera/RTPProxy.js +44 -28
- package/dist/lib/camera/RTPProxy.js.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.d.ts +33 -34
- package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.js +149 -181
- package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
- package/dist/lib/camera/RecordingManagement.d.ts +17 -19
- package/dist/lib/camera/RecordingManagement.d.ts.map +1 -1
- package/dist/lib/camera/RecordingManagement.js +151 -160
- package/dist/lib/camera/RecordingManagement.js.map +1 -1
- package/dist/lib/camera/index.d.ts +3 -3
- package/dist/lib/camera/index.d.ts.map +1 -1
- package/dist/lib/camera/index.js +6 -3
- package/dist/lib/camera/index.js.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.d.ts +33 -33
- package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.js +144 -152
- package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
- package/dist/lib/controller/CameraController.d.ts +20 -22
- package/dist/lib/controller/CameraController.d.ts.map +1 -1
- package/dist/lib/controller/CameraController.js +78 -74
- package/dist/lib/controller/CameraController.js.map +1 -1
- package/dist/lib/controller/Controller.d.ts +4 -4
- package/dist/lib/controller/Controller.d.ts.map +1 -1
- package/dist/lib/controller/Controller.js +8 -5
- package/dist/lib/controller/Controller.js.map +1 -1
- package/dist/lib/controller/DoorbellController.d.ts +4 -5
- package/dist/lib/controller/DoorbellController.d.ts.map +1 -1
- package/dist/lib/controller/DoorbellController.js +13 -9
- package/dist/lib/controller/DoorbellController.js.map +1 -1
- package/dist/lib/controller/RemoteController.d.ts +37 -39
- package/dist/lib/controller/RemoteController.d.ts.map +1 -1
- package/dist/lib/controller/RemoteController.js +197 -208
- package/dist/lib/controller/RemoteController.js.map +1 -1
- package/dist/lib/controller/index.d.ts +5 -5
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/controller/index.js +8 -5
- package/dist/lib/controller/index.js.map +1 -1
- package/dist/lib/datastream/DataStreamManagement.d.ts +2 -2
- package/dist/lib/datastream/DataStreamManagement.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamManagement.js +39 -39
- package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
- package/dist/lib/datastream/DataStreamParser.d.ts +0 -1
- package/dist/lib/datastream/DataStreamParser.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamParser.js +77 -57
- package/dist/lib/datastream/DataStreamParser.js.map +1 -1
- package/dist/lib/datastream/DataStreamServer.d.ts +22 -23
- package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamServer.js +164 -154
- package/dist/lib/datastream/DataStreamServer.js.map +1 -1
- package/dist/lib/datastream/index.d.ts +3 -3
- package/dist/lib/datastream/index.d.ts.map +1 -1
- package/dist/lib/datastream/index.js +6 -3
- package/dist/lib/datastream/index.js.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts +11 -1
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.js +1218 -957
- package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.js +695 -620
- package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
- package/dist/lib/definitions/generate-definitions.d.ts +3 -3
- package/dist/lib/definitions/generate-definitions.d.ts.map +1 -1
- package/dist/lib/definitions/generate-definitions.js +256 -244
- package/dist/lib/definitions/generate-definitions.js.map +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts.map +1 -1
- package/dist/lib/definitions/generator-configuration.js +170 -160
- package/dist/lib/definitions/generator-configuration.js.map +1 -1
- package/dist/lib/definitions/index.d.ts +2 -2
- package/dist/lib/definitions/index.d.ts.map +1 -1
- package/dist/lib/definitions/index.js +5 -2
- package/dist/lib/definitions/index.js.map +1 -1
- package/dist/lib/gen/HomeKit.d.ts +7 -0
- package/dist/lib/gen/HomeKit.d.ts.map +1 -0
- package/dist/lib/gen/HomeKit.js +8 -0
- package/dist/lib/gen/HomeKit.js.map +1 -0
- package/dist/lib/model/AccessoryInfo.d.ts +3 -4
- package/dist/lib/model/AccessoryInfo.d.ts.map +1 -1
- package/dist/lib/model/AccessoryInfo.js +53 -50
- package/dist/lib/model/AccessoryInfo.js.map +1 -1
- package/dist/lib/model/ControllerStorage.d.ts +3 -3
- package/dist/lib/model/ControllerStorage.d.ts.map +1 -1
- package/dist/lib/model/ControllerStorage.js +23 -18
- package/dist/lib/model/ControllerStorage.js.map +1 -1
- package/dist/lib/model/HAPStorage.d.ts +2 -2
- package/dist/lib/model/HAPStorage.d.ts.map +1 -1
- package/dist/lib/model/HAPStorage.js +11 -4
- package/dist/lib/model/HAPStorage.js.map +1 -1
- package/dist/lib/model/IdentifierCache.d.ts +1 -1
- package/dist/lib/model/IdentifierCache.d.ts.map +1 -1
- package/dist/lib/model/IdentifierCache.js +27 -19
- package/dist/lib/model/IdentifierCache.js.map +1 -1
- package/dist/lib/tv/AccessControlManagement.d.ts +9 -9
- package/dist/lib/tv/AccessControlManagement.d.ts.map +1 -1
- package/dist/lib/tv/AccessControlManagement.js +29 -27
- package/dist/lib/tv/AccessControlManagement.js.map +1 -1
- package/dist/lib/util/checkName.d.ts +2 -2
- package/dist/lib/util/checkName.d.ts.map +1 -1
- package/dist/lib/util/checkName.js +9 -6
- package/dist/lib/util/checkName.js.map +1 -1
- package/dist/lib/util/clone.d.ts.map +1 -1
- package/dist/lib/util/clone.js +5 -1
- package/dist/lib/util/clone.js.map +1 -1
- package/dist/lib/util/color-utils.d.ts +1 -1
- package/dist/lib/util/color-utils.d.ts.map +1 -1
- package/dist/lib/util/color-utils.js +9 -4
- package/dist/lib/util/color-utils.js.map +1 -1
- package/dist/lib/util/eventedhttp.d.ts +22 -23
- package/dist/lib/util/eventedhttp.d.ts.map +1 -1
- package/dist/lib/util/eventedhttp.js +116 -109
- package/dist/lib/util/eventedhttp.js.map +1 -1
- package/dist/lib/util/hapCrypto.d.ts +2 -3
- package/dist/lib/util/hapCrypto.d.ts.map +1 -1
- package/dist/lib/util/hapCrypto.js +40 -31
- package/dist/lib/util/hapCrypto.js.map +1 -1
- package/dist/lib/util/hapStatusError.d.ts +1 -1
- package/dist/lib/util/hapStatusError.d.ts.map +1 -1
- package/dist/lib/util/hapStatusError.js +8 -4
- package/dist/lib/util/hapStatusError.js.map +1 -1
- package/dist/lib/util/net-utils.d.ts +1 -1
- package/dist/lib/util/net-utils.js +23 -17
- package/dist/lib/util/net-utils.js.map +1 -1
- package/dist/lib/util/once.d.ts.map +1 -1
- package/dist/lib/util/once.js +6 -2
- package/dist/lib/util/once.js.map +1 -1
- package/dist/lib/util/promise-utils.d.ts +1 -1
- package/dist/lib/util/promise-utils.d.ts.map +1 -1
- package/dist/lib/util/promise-utils.js +10 -3
- package/dist/lib/util/promise-utils.js.map +1 -1
- package/dist/lib/util/request-util.d.ts +2 -3
- package/dist/lib/util/request-util.d.ts.map +1 -1
- package/dist/lib/util/request-util.js +19 -11
- package/dist/lib/util/request-util.js.map +1 -1
- package/dist/lib/util/time.d.ts +0 -1
- package/dist/lib/util/time.d.ts.map +1 -1
- package/dist/lib/util/time.js +11 -6
- package/dist/lib/util/time.js.map +1 -1
- package/dist/lib/util/tlv.d.ts +0 -1
- package/dist/lib/util/tlv.d.ts.map +1 -1
- package/dist/lib/util/tlv.js +43 -28
- package/dist/lib/util/tlv.js.map +1 -1
- package/dist/lib/util/uuid.d.ts +0 -1
- package/dist/lib/util/uuid.d.ts.map +1 -1
- package/dist/lib/util/uuid.js +38 -26
- package/dist/lib/util/uuid.js.map +1 -1
- package/dist/types.d.ts +24 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -3
- package/dist/types.js.map +1 -1
- package/package.json +45 -50
- package/dist/lib/dbus/align.d.ts +0 -2
- package/dist/lib/dbus/align.d.ts.map +0 -1
- package/dist/lib/dbus/align.js +0 -12
- package/dist/lib/dbus/align.js.map +0 -1
- package/dist/lib/dbus/bus.d.ts +0 -38
- package/dist/lib/dbus/bus.d.ts.map +0 -1
- package/dist/lib/dbus/bus.js +0 -222
- package/dist/lib/dbus/bus.js.map +0 -1
- package/dist/lib/dbus/constants.d.ts +0 -43
- package/dist/lib/dbus/constants.d.ts.map +0 -1
- package/dist/lib/dbus/constants.js +0 -53
- package/dist/lib/dbus/constants.js.map +0 -1
- package/dist/lib/dbus/dbus-buffer.d.ts +0 -30
- package/dist/lib/dbus/dbus-buffer.d.ts.map +0 -1
- package/dist/lib/dbus/dbus-buffer.js +0 -175
- package/dist/lib/dbus/dbus-buffer.js.map +0 -1
- package/dist/lib/dbus/handshake.d.ts +0 -2
- package/dist/lib/dbus/handshake.d.ts.map +0 -1
- package/dist/lib/dbus/handshake.js +0 -130
- package/dist/lib/dbus/handshake.js.map +0 -1
- package/dist/lib/dbus/index.d.ts +0 -3
- package/dist/lib/dbus/index.d.ts.map +0 -1
- package/dist/lib/dbus/index.js +0 -123
- package/dist/lib/dbus/index.js.map +0 -1
- package/dist/lib/dbus/introspect.d.ts +0 -30
- package/dist/lib/dbus/introspect.d.ts.map +0 -1
- package/dist/lib/dbus/introspect.js +0 -208
- package/dist/lib/dbus/introspect.js.map +0 -1
- package/dist/lib/dbus/marshall.d.ts +0 -2
- package/dist/lib/dbus/marshall.d.ts.map +0 -1
- package/dist/lib/dbus/marshall.js +0 -97
- package/dist/lib/dbus/marshall.js.map +0 -1
- package/dist/lib/dbus/marshallers.d.ts +0 -10
- package/dist/lib/dbus/marshallers.d.ts.map +0 -1
- package/dist/lib/dbus/marshallers.js +0 -329
- package/dist/lib/dbus/marshallers.js.map +0 -1
- package/dist/lib/dbus/message.d.ts +0 -4
- package/dist/lib/dbus/message.d.ts.map +0 -1
- package/dist/lib/dbus/message.js +0 -116
- package/dist/lib/dbus/message.js.map +0 -1
- package/dist/lib/dbus/put.d.ts +0 -21
- package/dist/lib/dbus/put.d.ts.map +0 -1
- package/dist/lib/dbus/put.js +0 -120
- package/dist/lib/dbus/put.js.map +0 -1
- package/dist/lib/dbus/readline.d.ts +0 -2
- package/dist/lib/dbus/readline.d.ts.map +0 -1
- package/dist/lib/dbus/readline.js +0 -27
- package/dist/lib/dbus/readline.js.map +0 -1
- package/dist/lib/dbus/signature.d.ts +0 -2
- package/dist/lib/dbus/signature.d.ts.map +0 -1
- package/dist/lib/dbus/signature.js +0 -59
- package/dist/lib/dbus/signature.js.map +0 -1
- package/dist/lib/dbus/stdifaces.d.ts +0 -3
- package/dist/lib/dbus/stdifaces.d.ts.map +0 -1
- package/dist/lib/dbus/stdifaces.js +0 -206
- package/dist/lib/dbus/stdifaces.js.map +0 -1
package/dist/lib/Accessory.js
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Accessory = exports.AccessoryEventTypes = exports.MDNSAdvertiser = exports.CharacteristicWarningType = exports.Categories = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
7
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
8
|
+
const events_1 = require("events");
|
|
9
|
+
const net_1 = tslib_1.__importDefault(require("net"));
|
|
10
|
+
const Advertiser_1 = require("./Advertiser");
|
|
11
|
+
// noinspection JSDeprecatedSymbols
|
|
12
|
+
const Characteristic_1 = require("./Characteristic");
|
|
13
|
+
const controller_1 = require("./controller");
|
|
14
|
+
const HAPServer_1 = require("./HAPServer");
|
|
15
|
+
const AccessoryInfo_1 = require("./model/AccessoryInfo");
|
|
16
|
+
const ControllerStorage_1 = require("./model/ControllerStorage");
|
|
17
|
+
const IdentifierCache_1 = require("./model/IdentifierCache");
|
|
18
|
+
const Service_1 = require("./Service");
|
|
19
|
+
const clone_1 = require("./util/clone");
|
|
20
|
+
const request_util_1 = require("./util/request-util");
|
|
21
|
+
const uuid = tslib_1.__importStar(require("./util/uuid"));
|
|
22
|
+
const uuid_1 = require("./util/uuid");
|
|
23
|
+
const checkName_1 = require("./util/checkName");
|
|
24
|
+
const debug = (0, debug_1.default)("HAP-NodeJS:Accessory");
|
|
20
25
|
const MAX_ACCESSORIES = 149; // Maximum number of bridged accessories per bridge.
|
|
21
26
|
const MAX_SERVICES = 100;
|
|
22
27
|
/**
|
|
@@ -24,9 +29,9 @@ const MAX_SERVICES = 100;
|
|
|
24
29
|
*
|
|
25
30
|
* @group Accessory
|
|
26
31
|
*/
|
|
27
|
-
|
|
28
|
-
export var Categories;
|
|
32
|
+
var Categories;
|
|
29
33
|
(function (Categories) {
|
|
34
|
+
// noinspection JSUnusedGlobalSymbols
|
|
30
35
|
Categories[Categories["OTHER"] = 1] = "OTHER";
|
|
31
36
|
Categories[Categories["BRIDGE"] = 2] = "BRIDGE";
|
|
32
37
|
Categories[Categories["FAN"] = 3] = "FAN";
|
|
@@ -38,7 +43,7 @@ export var Categories;
|
|
|
38
43
|
Categories[Categories["THERMOSTAT"] = 9] = "THERMOSTAT";
|
|
39
44
|
Categories[Categories["SENSOR"] = 10] = "SENSOR";
|
|
40
45
|
Categories[Categories["ALARM_SYSTEM"] = 11] = "ALARM_SYSTEM";
|
|
41
|
-
// eslint-disable-next-line
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
42
47
|
Categories[Categories["SECURITY_SYSTEM"] = 11] = "SECURITY_SYSTEM";
|
|
43
48
|
Categories[Categories["DOOR"] = 12] = "DOOR";
|
|
44
49
|
Categories[Categories["WINDOW"] = 13] = "WINDOW";
|
|
@@ -46,7 +51,7 @@ export var Categories;
|
|
|
46
51
|
Categories[Categories["PROGRAMMABLE_SWITCH"] = 15] = "PROGRAMMABLE_SWITCH";
|
|
47
52
|
Categories[Categories["RANGE_EXTENDER"] = 16] = "RANGE_EXTENDER";
|
|
48
53
|
Categories[Categories["CAMERA"] = 17] = "CAMERA";
|
|
49
|
-
// eslint-disable-next-line
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
|
|
50
55
|
Categories[Categories["IP_CAMERA"] = 17] = "IP_CAMERA";
|
|
51
56
|
Categories[Categories["VIDEO_DOORBELL"] = 18] = "VIDEO_DOORBELL";
|
|
52
57
|
Categories[Categories["AIR_PURIFIER"] = 19] = "AIR_PURIFIER";
|
|
@@ -67,12 +72,11 @@ export var Categories;
|
|
|
67
72
|
Categories[Categories["AUDIO_RECEIVER"] = 34] = "AUDIO_RECEIVER";
|
|
68
73
|
Categories[Categories["TV_SET_TOP_BOX"] = 35] = "TV_SET_TOP_BOX";
|
|
69
74
|
Categories[Categories["TV_STREAMING_STICK"] = 36] = "TV_STREAMING_STICK";
|
|
70
|
-
})(Categories || (Categories = {}));
|
|
75
|
+
})(Categories || (exports.Categories = Categories = {}));
|
|
71
76
|
/**
|
|
72
77
|
* @group Accessory
|
|
73
78
|
*/
|
|
74
|
-
|
|
75
|
-
export var CharacteristicWarningType;
|
|
79
|
+
var CharacteristicWarningType;
|
|
76
80
|
(function (CharacteristicWarningType) {
|
|
77
81
|
CharacteristicWarningType["SLOW_WRITE"] = "slow-write";
|
|
78
82
|
CharacteristicWarningType["TIMEOUT_WRITE"] = "timeout-write";
|
|
@@ -81,12 +85,11 @@ export var CharacteristicWarningType;
|
|
|
81
85
|
CharacteristicWarningType["WARN_MESSAGE"] = "warn-message";
|
|
82
86
|
CharacteristicWarningType["ERROR_MESSAGE"] = "error-message";
|
|
83
87
|
CharacteristicWarningType["DEBUG_MESSAGE"] = "debug-message";
|
|
84
|
-
})(CharacteristicWarningType || (CharacteristicWarningType = {}));
|
|
88
|
+
})(CharacteristicWarningType || (exports.CharacteristicWarningType = CharacteristicWarningType = {}));
|
|
85
89
|
/**
|
|
86
90
|
* @group Accessory
|
|
87
91
|
*/
|
|
88
|
-
|
|
89
|
-
export var MDNSAdvertiser;
|
|
92
|
+
var MDNSAdvertiser;
|
|
90
93
|
(function (MDNSAdvertiser) {
|
|
91
94
|
/**
|
|
92
95
|
* Use the `@homebridge/ciao` module as advertiser.
|
|
@@ -108,8 +111,7 @@ export var MDNSAdvertiser;
|
|
|
108
111
|
* Consequentially, treat this feature as an experimental feature.
|
|
109
112
|
*/
|
|
110
113
|
MDNSAdvertiser["RESOLVED"] = "resolved";
|
|
111
|
-
})(MDNSAdvertiser || (MDNSAdvertiser = {}));
|
|
112
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
114
|
+
})(MDNSAdvertiser || (exports.MDNSAdvertiser = MDNSAdvertiser = {}));
|
|
113
115
|
var WriteRequestState;
|
|
114
116
|
(function (WriteRequestState) {
|
|
115
117
|
WriteRequestState[WriteRequestState["REGULAR_REQUEST"] = 0] = "REGULAR_REQUEST";
|
|
@@ -119,8 +121,7 @@ var WriteRequestState;
|
|
|
119
121
|
/**
|
|
120
122
|
* @group Accessory
|
|
121
123
|
*/
|
|
122
|
-
|
|
123
|
-
export var AccessoryEventTypes;
|
|
124
|
+
var AccessoryEventTypes;
|
|
124
125
|
(function (AccessoryEventTypes) {
|
|
125
126
|
/**
|
|
126
127
|
* Emitted when an iOS device wishes for this Accessory to identify itself. If `paired` is false, then
|
|
@@ -149,7 +150,7 @@ export var AccessoryEventTypes;
|
|
|
149
150
|
AccessoryEventTypes["PAIRED"] = "paired";
|
|
150
151
|
AccessoryEventTypes["UNPAIRED"] = "unpaired";
|
|
151
152
|
AccessoryEventTypes["CHARACTERISTIC_WARNING"] = "characteristic-warning";
|
|
152
|
-
})(AccessoryEventTypes || (AccessoryEventTypes = {}));
|
|
153
|
+
})(AccessoryEventTypes || (exports.AccessoryEventTypes = AccessoryEventTypes = {}));
|
|
153
154
|
/**
|
|
154
155
|
* Accessory is a virtual HomeKit device. It can publish an associated HAP server for iOS devices to communicate
|
|
155
156
|
* with - or it can run behind another "Bridge" Accessory server.
|
|
@@ -161,8 +162,8 @@ export var AccessoryEventTypes;
|
|
|
161
162
|
*
|
|
162
163
|
* @group Accessory
|
|
163
164
|
*/
|
|
164
|
-
// eslint-disable-next-line
|
|
165
|
-
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
166
|
+
class Accessory extends events_1.EventEmitter {
|
|
166
167
|
displayName;
|
|
167
168
|
UUID;
|
|
168
169
|
// Timeout in milliseconds until a characteristic warning is issue
|
|
@@ -184,38 +185,38 @@ export class Accessory extends EventEmitter {
|
|
|
184
185
|
/**
|
|
185
186
|
* Captures if initialization steps inside {@link publish} have been called.
|
|
186
187
|
* This is important when calling {@link publish} multiple times (e.g. after calling {@link unpublish}).
|
|
187
|
-
* @private
|
|
188
|
+
* @private Private API
|
|
188
189
|
*/
|
|
189
190
|
initialized = false;
|
|
190
191
|
controllers = {};
|
|
191
192
|
serializedControllers; // store uninitialized controller data after a Accessory.deserialize call
|
|
192
193
|
activeCameraController;
|
|
193
194
|
/**
|
|
194
|
-
* @private
|
|
195
|
+
* @private Private API.
|
|
195
196
|
*/
|
|
196
197
|
_accessoryInfo;
|
|
197
198
|
/**
|
|
198
|
-
* @private
|
|
199
|
+
* @private Private API.
|
|
199
200
|
*/
|
|
200
201
|
_setupID = null;
|
|
201
202
|
/**
|
|
202
|
-
* @private
|
|
203
|
+
* @private Private API.
|
|
203
204
|
*/
|
|
204
205
|
_identifierCache;
|
|
205
206
|
/**
|
|
206
|
-
* @private
|
|
207
|
+
* @private Private API.
|
|
207
208
|
*/
|
|
208
|
-
controllerStorage = new ControllerStorage(this);
|
|
209
|
+
controllerStorage = new ControllerStorage_1.ControllerStorage(this);
|
|
209
210
|
/**
|
|
210
|
-
* @private
|
|
211
|
+
* @private Private API.
|
|
211
212
|
*/
|
|
212
213
|
_advertiser;
|
|
213
214
|
/**
|
|
214
|
-
* @private
|
|
215
|
+
* @private Private API.
|
|
215
216
|
*/
|
|
216
217
|
_server;
|
|
217
218
|
/**
|
|
218
|
-
* @private
|
|
219
|
+
* @private Private API.
|
|
219
220
|
*/
|
|
220
221
|
_setupURI;
|
|
221
222
|
configurationChangeDebounceTimeout;
|
|
@@ -228,18 +229,18 @@ export class Accessory extends EventEmitter {
|
|
|
228
229
|
super();
|
|
229
230
|
this.displayName = displayName;
|
|
230
231
|
this.UUID = UUID;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
(0, assert_1.default)(displayName, "Accessories must be created with a non-empty displayName.");
|
|
233
|
+
(0, assert_1.default)(UUID, "Accessories must be created with a valid UUID.");
|
|
234
|
+
(0, assert_1.default)(uuid.isValid(UUID), "UUID '" + UUID + "' is not a valid UUID. Try using the provided 'generateUUID' function to create a " +
|
|
235
|
+
"valid UUID from any arbitrary string, like a serial number.");
|
|
235
236
|
// create our initial "Accessory Information" Service that all Accessories are expected to have
|
|
236
|
-
checkName(this.displayName,
|
|
237
|
-
this.addService(Service.AccessoryInformation)
|
|
238
|
-
.setCharacteristic(Characteristic.Name, displayName);
|
|
237
|
+
(0, checkName_1.checkName)(this.displayName, "Name", displayName);
|
|
238
|
+
this.addService(Service_1.Service.AccessoryInformation)
|
|
239
|
+
.setCharacteristic(Characteristic_1.Characteristic.Name, displayName);
|
|
239
240
|
// sign up for when iOS attempts to "set" the `Identify` characteristic - this means a paired device wishes
|
|
240
241
|
// for us to identify ourselves (as opposed to an unpaired device - that case is handled by HAPServer 'identify' event)
|
|
241
|
-
this.getService(Service.AccessoryInformation)
|
|
242
|
-
.getCharacteristic(Characteristic.Identify)
|
|
242
|
+
this.getService(Service_1.Service.AccessoryInformation)
|
|
243
|
+
.getCharacteristic(Characteristic_1.Characteristic.Identify)
|
|
243
244
|
.on("set" /* CharacteristicEventTypes.SET */, (value, callback) => {
|
|
244
245
|
if (value) {
|
|
245
246
|
const paired = true;
|
|
@@ -248,37 +249,40 @@ export class Accessory extends EventEmitter {
|
|
|
248
249
|
});
|
|
249
250
|
}
|
|
250
251
|
identificationRequest(paired, callback) {
|
|
251
|
-
debug(
|
|
252
|
+
debug("[%s] Identification request", this.displayName);
|
|
252
253
|
if (this.listeners("identify" /* AccessoryEventTypes.IDENTIFY */).length > 0) {
|
|
253
254
|
// allow implementors to identify this Accessory in whatever way is appropriate, and pass along
|
|
254
255
|
// the standard callback for completion.
|
|
255
256
|
this.emit("identify" /* AccessoryEventTypes.IDENTIFY */, paired, callback);
|
|
256
257
|
}
|
|
257
258
|
else {
|
|
258
|
-
debug(
|
|
259
|
+
debug("[%s] Identification request ignored; no listeners to 'identify' event", this.displayName);
|
|
259
260
|
callback();
|
|
260
261
|
}
|
|
261
262
|
}
|
|
263
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
262
264
|
addService(serviceParam, ...constructorArgs) {
|
|
263
265
|
// service might be a constructor like `Service.AccessoryInformation` instead of an instance
|
|
264
266
|
// of Service. Coerce if necessary.
|
|
265
|
-
const service = typeof serviceParam ===
|
|
266
|
-
? new serviceParam(constructorArgs[0], constructorArgs[1], constructorArgs[2])
|
|
267
|
+
const service = typeof serviceParam === "function"
|
|
268
|
+
? new serviceParam(constructorArgs[0], constructorArgs[1], constructorArgs[2])
|
|
267
269
|
: serviceParam;
|
|
268
270
|
// check for UUID+subtype conflict
|
|
269
271
|
for (const existing of this.services) {
|
|
270
272
|
if (existing.UUID === service.UUID) {
|
|
271
273
|
// OK we have two Services with the same UUID. Check that each defines a `subtype` property and that each is unique.
|
|
272
274
|
if (!service.subtype) {
|
|
273
|
-
throw new Error(
|
|
275
|
+
throw new Error("Cannot add a Service with the same UUID '" + existing.UUID +
|
|
276
|
+
"' as another Service in this Accessory without also defining a unique 'subtype' property.");
|
|
274
277
|
}
|
|
275
278
|
if (service.subtype === existing.subtype) {
|
|
276
|
-
throw new Error(
|
|
279
|
+
throw new Error("Cannot add a Service with the same UUID '" + existing.UUID +
|
|
280
|
+
"' and subtype '" + existing.subtype + "' as another Service in this Accessory.");
|
|
277
281
|
}
|
|
278
282
|
}
|
|
279
283
|
}
|
|
280
284
|
if (this.services.length >= MAX_SERVICES) {
|
|
281
|
-
throw new Error(
|
|
285
|
+
throw new Error("Cannot add more than " + MAX_SERVICES + " services to a single accessory!");
|
|
282
286
|
}
|
|
283
287
|
this.services.push(service);
|
|
284
288
|
if (service.isPrimaryService) { // check if a primary service was added
|
|
@@ -291,7 +295,7 @@ export class Accessory extends EventEmitter {
|
|
|
291
295
|
this.enqueueConfigurationUpdate();
|
|
292
296
|
}
|
|
293
297
|
else {
|
|
294
|
-
this.emit("service-configurationChange" /* AccessoryEventTypes.SERVICE_CONFIGURATION_CHANGE */, { service });
|
|
298
|
+
this.emit("service-configurationChange" /* AccessoryEventTypes.SERVICE_CONFIGURATION_CHANGE */, { service: service });
|
|
295
299
|
}
|
|
296
300
|
this.setupServiceEventHandlers(service);
|
|
297
301
|
return service;
|
|
@@ -308,7 +312,7 @@ export class Accessory extends EventEmitter {
|
|
|
308
312
|
this.enqueueConfigurationUpdate();
|
|
309
313
|
}
|
|
310
314
|
else {
|
|
311
|
-
this.emit("service-configurationChange" /* AccessoryEventTypes.SERVICE_CONFIGURATION_CHANGE */, { service });
|
|
315
|
+
this.emit("service-configurationChange" /* AccessoryEventTypes.SERVICE_CONFIGURATION_CHANGE */, { service: service });
|
|
312
316
|
}
|
|
313
317
|
service.removeAllListeners();
|
|
314
318
|
}
|
|
@@ -320,12 +324,12 @@ export class Accessory extends EventEmitter {
|
|
|
320
324
|
}
|
|
321
325
|
getService(name) {
|
|
322
326
|
for (const service of this.services) {
|
|
323
|
-
if (typeof name ===
|
|
327
|
+
if (typeof name === "string" && (service.displayName === name || service.name === name || service.subtype === name)) {
|
|
324
328
|
return service;
|
|
325
329
|
}
|
|
326
330
|
else {
|
|
327
331
|
// @ts-expect-error ('UUID' does not exist on type 'never')
|
|
328
|
-
if (typeof name ===
|
|
332
|
+
if (typeof name === "function" && ((service instanceof name) || (name.UUID === service.UUID))) {
|
|
329
333
|
return service;
|
|
330
334
|
}
|
|
331
335
|
}
|
|
@@ -334,12 +338,12 @@ export class Accessory extends EventEmitter {
|
|
|
334
338
|
}
|
|
335
339
|
getServiceById(uuid, subType) {
|
|
336
340
|
for (const service of this.services) {
|
|
337
|
-
if (typeof uuid ===
|
|
341
|
+
if (typeof uuid === "string" && (service.displayName === uuid || service.name === uuid) && service.subtype === subType) {
|
|
338
342
|
return service;
|
|
339
343
|
}
|
|
340
344
|
else {
|
|
341
345
|
// @ts-expect-error ('UUID' does not exist on type 'never')
|
|
342
|
-
if (typeof uuid ===
|
|
346
|
+
if (typeof uuid === "function" && ((service instanceof uuid) || (uuid.UUID === service.UUID)) && service.subtype === subType) {
|
|
343
347
|
return service;
|
|
344
348
|
}
|
|
345
349
|
}
|
|
@@ -357,17 +361,17 @@ export class Accessory extends EventEmitter {
|
|
|
357
361
|
};
|
|
358
362
|
addBridgedAccessory(accessory, deferUpdate = false) {
|
|
359
363
|
if (accessory._isBridge || accessory === this) {
|
|
360
|
-
throw new Error(
|
|
364
|
+
throw new Error("Illegal state: either trying to bridge a bridge or trying to bridge itself!");
|
|
361
365
|
}
|
|
362
366
|
if (accessory.initialized) {
|
|
363
|
-
throw new Error(
|
|
367
|
+
throw new Error("Tried to bridge an accessory which was already published once!");
|
|
364
368
|
}
|
|
365
369
|
if (accessory.bridge != null) {
|
|
366
370
|
// this also prevents that we bridge the same accessory twice!
|
|
367
|
-
throw new Error(
|
|
371
|
+
throw new Error("Tried to bridge " + accessory.displayName + " while it was already bridged by " + accessory.bridge.displayName);
|
|
368
372
|
}
|
|
369
373
|
if (this.bridgedAccessories.length >= MAX_ACCESSORIES) {
|
|
370
|
-
throw new Error(
|
|
374
|
+
throw new Error("Cannot Bridge more than " + MAX_ACCESSORIES + " Accessories");
|
|
371
375
|
}
|
|
372
376
|
// listen for changes in ANY characteristics of ANY services on this Accessory
|
|
373
377
|
accessory.on("service-characteristic-change" /* AccessoryEventTypes.SERVICE_CHARACTERISTIC_CHANGE */, change => this.handleCharacteristicChangeEvent(accessory, change.service, change));
|
|
@@ -392,7 +396,7 @@ export class Accessory extends EventEmitter {
|
|
|
392
396
|
// check for UUID conflict
|
|
393
397
|
const accessoryIndex = this.bridgedAccessories.indexOf(accessory);
|
|
394
398
|
if (accessoryIndex === -1) {
|
|
395
|
-
throw new Error(
|
|
399
|
+
throw new Error("Cannot find the bridged Accessory to remove.");
|
|
396
400
|
}
|
|
397
401
|
this.bridgedAccessories.splice(accessoryIndex, 1);
|
|
398
402
|
accessory.bridged = false;
|
|
@@ -447,9 +451,8 @@ export class Accessory extends EventEmitter {
|
|
|
447
451
|
* @param controllerConstructor - The Controller instance or constructor to the Controller with no required arguments.
|
|
448
452
|
*/
|
|
449
453
|
configureController(controllerConstructor) {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
? new controllerConstructor() // eslint-disable-line new-cap
|
|
454
|
+
const controller = typeof controllerConstructor === "function"
|
|
455
|
+
? new controllerConstructor() // any custom constructor arguments should be passed before using .bind(...)
|
|
453
456
|
: controllerConstructor;
|
|
454
457
|
const id = controller.controllerId();
|
|
455
458
|
if (this.controllers[id]) {
|
|
@@ -458,7 +461,7 @@ export class Accessory extends EventEmitter {
|
|
|
458
461
|
const savedServiceMap = this.serializedControllers && this.serializedControllers[id];
|
|
459
462
|
let serviceMap;
|
|
460
463
|
if (savedServiceMap) { // we found data to restore from
|
|
461
|
-
const clonedServiceMap = clone(savedServiceMap);
|
|
464
|
+
const clonedServiceMap = (0, clone_1.clone)(savedServiceMap);
|
|
462
465
|
const updatedServiceMap = controller.initWithServices(savedServiceMap); // init controller with existing services
|
|
463
466
|
serviceMap = updatedServiceMap || savedServiceMap; // initWithServices could return an updated serviceMap, otherwise just use the existing one
|
|
464
467
|
if (updatedServiceMap) { // controller returned a ServiceMap and thus signaled an updated set of services
|
|
@@ -475,7 +478,7 @@ export class Accessory extends EventEmitter {
|
|
|
475
478
|
else {
|
|
476
479
|
serviceMap = controller.constructServices(); // let the controller create his services
|
|
477
480
|
controller.configureServices(); // let the controller setup all its handlers
|
|
478
|
-
Object.values(serviceMap).forEach(
|
|
481
|
+
Object.values(serviceMap).forEach(service => {
|
|
479
482
|
if (service && !this.services.includes(service)) {
|
|
480
483
|
this.addService(service);
|
|
481
484
|
}
|
|
@@ -483,14 +486,14 @@ export class Accessory extends EventEmitter {
|
|
|
483
486
|
}
|
|
484
487
|
// --- init handlers and setup context ---
|
|
485
488
|
const context = {
|
|
486
|
-
controller,
|
|
487
|
-
serviceMap,
|
|
489
|
+
controller: controller,
|
|
490
|
+
serviceMap: serviceMap,
|
|
488
491
|
};
|
|
489
|
-
if (isSerializableController(controller)) {
|
|
492
|
+
if ((0, controller_1.isSerializableController)(controller)) {
|
|
490
493
|
this.controllerStorage.trackController(controller);
|
|
491
494
|
}
|
|
492
495
|
this.controllers[id] = context;
|
|
493
|
-
if (controller instanceof CameraController) { // save CameraController for Snapshot handling
|
|
496
|
+
if (controller instanceof controller_1.CameraController) { // save CameraController for Snapshot handling
|
|
494
497
|
this.activeCameraController = controller;
|
|
495
498
|
}
|
|
496
499
|
}
|
|
@@ -506,9 +509,10 @@ export class Accessory extends EventEmitter {
|
|
|
506
509
|
const storedController = this.controllers[id];
|
|
507
510
|
if (storedController) {
|
|
508
511
|
if (storedController.controller !== controller) {
|
|
509
|
-
throw new Error(
|
|
512
|
+
throw new Error("[" + this.displayName + "] tried removing a controller with the id/type '" + id +
|
|
513
|
+
"' though provided controller isn't the same instance that is registered!");
|
|
510
514
|
}
|
|
511
|
-
if (isSerializableController(controller)) {
|
|
515
|
+
if ((0, controller_1.isSerializableController)(controller)) {
|
|
512
516
|
// this will reset the state change delegate before we call handleControllerRemoved()
|
|
513
517
|
this.controllerStorage.untrackController(controller);
|
|
514
518
|
}
|
|
@@ -520,7 +524,7 @@ export class Accessory extends EventEmitter {
|
|
|
520
524
|
if (this.activeCameraController === controller) {
|
|
521
525
|
this.activeCameraController = undefined;
|
|
522
526
|
}
|
|
523
|
-
Object.values(storedController.serviceMap).forEach(
|
|
527
|
+
Object.values(storedController.serviceMap).forEach(service => {
|
|
524
528
|
if (service) {
|
|
525
529
|
this.removeService(service);
|
|
526
530
|
}
|
|
@@ -536,14 +540,14 @@ export class Accessory extends EventEmitter {
|
|
|
536
540
|
if (controller.handleFactoryReset) { // if the controller implements handleFactoryReset, setup event handlers for this controller
|
|
537
541
|
controller.handleFactoryReset();
|
|
538
542
|
}
|
|
539
|
-
if (isSerializableController(controller)) {
|
|
543
|
+
if ((0, controller_1.isSerializableController)(controller)) {
|
|
540
544
|
this.controllerStorage.purgeControllerData(controller);
|
|
541
545
|
}
|
|
542
546
|
}
|
|
543
547
|
}
|
|
544
548
|
handleUpdatedControllerServiceMap(originalServiceMap, updatedServiceMap) {
|
|
545
|
-
updatedServiceMap = clone(updatedServiceMap); // clone it so we can alter it
|
|
546
|
-
Object.keys(originalServiceMap).forEach(
|
|
549
|
+
updatedServiceMap = (0, clone_1.clone)(updatedServiceMap); // clone it so we can alter it
|
|
550
|
+
Object.keys(originalServiceMap).forEach(name => {
|
|
547
551
|
const service = originalServiceMap[name];
|
|
548
552
|
const updatedService = updatedServiceMap[name];
|
|
549
553
|
if (service && updatedService) { // we check all names contained in both ServiceMaps for changes
|
|
@@ -556,12 +560,12 @@ export class Accessory extends EventEmitter {
|
|
|
556
560
|
}
|
|
557
561
|
});
|
|
558
562
|
// now originalServiceMap contains only deleted services and updateServiceMap only added services
|
|
559
|
-
Object.values(originalServiceMap).forEach(
|
|
563
|
+
Object.values(originalServiceMap).forEach(service => {
|
|
560
564
|
if (service) {
|
|
561
565
|
this.removeService(service);
|
|
562
566
|
}
|
|
563
567
|
});
|
|
564
|
-
Object.values(updatedServiceMap).forEach(
|
|
568
|
+
Object.values(updatedServiceMap).forEach(service => {
|
|
565
569
|
if (service) {
|
|
566
570
|
this.addService(service);
|
|
567
571
|
}
|
|
@@ -571,23 +575,23 @@ export class Accessory extends EventEmitter {
|
|
|
571
575
|
if (this._setupURI) {
|
|
572
576
|
return this._setupURI;
|
|
573
577
|
}
|
|
574
|
-
|
|
578
|
+
(0, assert_1.default)(!!this._accessoryInfo, "Cannot generate setupURI on an accessory that isn't published yet!");
|
|
575
579
|
const buffer = Buffer.alloc(8);
|
|
576
|
-
let value_low =
|
|
580
|
+
let value_low = parseInt(this._accessoryInfo.pincode.replace(/-/g, ""), 10);
|
|
577
581
|
const value_high = this._accessoryInfo.category >> 1;
|
|
578
582
|
value_low |= 1 << 28; // Supports IP;
|
|
579
583
|
buffer.writeUInt32BE(value_low, 4);
|
|
580
|
-
if (this._accessoryInfo.category
|
|
581
|
-
buffer[4]
|
|
584
|
+
if (this._accessoryInfo.category & 1) {
|
|
585
|
+
buffer[4] = buffer[4] | 1 << 7;
|
|
582
586
|
}
|
|
583
587
|
buffer.writeUInt32BE(value_high, 0);
|
|
584
588
|
let encodedPayload = (buffer.readUInt32BE(4) + (buffer.readUInt32BE(0) * 0x100000000)).toString(36).toUpperCase();
|
|
585
589
|
if (encodedPayload.length !== 9) {
|
|
586
590
|
for (let i = 0; i <= 9 - encodedPayload.length; i++) {
|
|
587
|
-
encodedPayload =
|
|
591
|
+
encodedPayload = "0" + encodedPayload;
|
|
588
592
|
}
|
|
589
593
|
}
|
|
590
|
-
this._setupURI =
|
|
594
|
+
this._setupURI = "X-HM://" + encodedPayload + this._setupID;
|
|
591
595
|
return this._setupURI;
|
|
592
596
|
}
|
|
593
597
|
/**
|
|
@@ -596,31 +600,30 @@ export class Accessory extends EventEmitter {
|
|
|
596
600
|
* If it is called on a bridge it will call this method for all bridged accessories.
|
|
597
601
|
*/
|
|
598
602
|
validateAccessory(mainAccessory) {
|
|
599
|
-
const service = this.getService(Service.AccessoryInformation);
|
|
603
|
+
const service = this.getService(Service_1.Service.AccessoryInformation);
|
|
600
604
|
if (!service) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
+ `This might prevent the accessory from being added to the Home app or leading to the accessory being unresponsive!`);
|
|
605
|
+
console.log("HAP-NodeJS WARNING: The accessory '" + this.displayName + "' is getting published without a AccessoryInformation service. " +
|
|
606
|
+
"This might prevent the accessory from being added to the Home app or leading to the accessory being unresponsive!");
|
|
604
607
|
}
|
|
605
608
|
else {
|
|
609
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
606
610
|
const checkValue = (name, value) => {
|
|
607
611
|
if (!value) {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
+ `This might prevent the accessory from being added to the Home App or leading to the accessory being unresponsive!`);
|
|
612
|
+
console.log("HAP-NodeJS WARNING: The accessory '" + this.displayName + "' is getting published with the characteristic '" + name + "'" +
|
|
613
|
+
" (of the AccessoryInformation service) not having a value set. " +
|
|
614
|
+
"This might prevent the accessory from being added to the Home App or leading to the accessory being unresponsive!");
|
|
612
615
|
}
|
|
613
616
|
};
|
|
614
|
-
checkName(this.displayName,
|
|
615
|
-
checkValue(
|
|
616
|
-
checkValue(
|
|
617
|
-
checkValue(
|
|
618
|
-
checkValue(
|
|
619
|
-
checkValue(
|
|
617
|
+
(0, checkName_1.checkName)(this.displayName, "Name", service.getCharacteristic(Characteristic_1.Characteristic.Name).value);
|
|
618
|
+
checkValue("FirmwareRevision", service.getCharacteristic(Characteristic_1.Characteristic.FirmwareRevision).value);
|
|
619
|
+
checkValue("Manufacturer", service.getCharacteristic(Characteristic_1.Characteristic.Manufacturer).value);
|
|
620
|
+
checkValue("Model", service.getCharacteristic(Characteristic_1.Characteristic.Model).value);
|
|
621
|
+
checkValue("Name", service.getCharacteristic(Characteristic_1.Characteristic.Name).value);
|
|
622
|
+
checkValue("SerialNumber", service.getCharacteristic(Characteristic_1.Characteristic.SerialNumber).value);
|
|
620
623
|
}
|
|
621
624
|
if (mainAccessory) {
|
|
622
625
|
// the main accessory which is advertised via bonjour must have a name with length <= 63 (limitation of DNS FQDN names)
|
|
623
|
-
|
|
626
|
+
(0, assert_1.default)(Buffer.from(this.displayName, "utf8").length <= 63, "Accessory displayName cannot be longer than 63 bytes!");
|
|
624
627
|
}
|
|
625
628
|
if (this.bridged) {
|
|
626
629
|
this.bridgedAccessories.forEach(accessory => accessory.validateAccessory());
|
|
@@ -629,7 +632,7 @@ export class Accessory extends EventEmitter {
|
|
|
629
632
|
/**
|
|
630
633
|
* Assigns aid/iid to ourselves, any Accessories we are bridging, and all associated Services+Characteristics. Uses
|
|
631
634
|
* the provided identifierCache to keep IDs stable.
|
|
632
|
-
* @private
|
|
635
|
+
* @private Private API
|
|
633
636
|
*/
|
|
634
637
|
_assignIDs(identifierCache) {
|
|
635
638
|
// if we are responsible for our own identifierCache, start the expiration process
|
|
@@ -662,11 +665,11 @@ export class Accessory extends EventEmitter {
|
|
|
662
665
|
// expire any now-unused cache keys (for Accessories, Services, or Characteristics
|
|
663
666
|
// that have been removed since the last call to assignIDs())
|
|
664
667
|
if (this._identifierCache) {
|
|
665
|
-
//
|
|
668
|
+
//Check weather we want to purge the unused ids
|
|
666
669
|
if (this.shouldPurgeUnusedIDs) {
|
|
667
670
|
this._identifierCache.stopTrackingUsageAndExpireUnused();
|
|
668
671
|
}
|
|
669
|
-
//
|
|
672
|
+
//Save in case we have new ones
|
|
670
673
|
this._identifierCache.save();
|
|
671
674
|
}
|
|
672
675
|
}
|
|
@@ -681,10 +684,10 @@ export class Accessory extends EventEmitter {
|
|
|
681
684
|
* when you have disabled auto purge, so you can do it manually
|
|
682
685
|
*/
|
|
683
686
|
purgeUnusedIDs() {
|
|
684
|
-
//
|
|
687
|
+
//Cache the state of the purge mechanism and set it to true
|
|
685
688
|
const oldValue = this.shouldPurgeUnusedIDs;
|
|
686
689
|
this.shouldPurgeUnusedIDs = true;
|
|
687
|
-
//
|
|
690
|
+
//Reassign all ids
|
|
688
691
|
this._assignIDs(this._identifierCache);
|
|
689
692
|
// Revert the purge mechanism state
|
|
690
693
|
this.shouldPurgeUnusedIDs = oldValue;
|
|
@@ -693,8 +696,8 @@ export class Accessory extends EventEmitter {
|
|
|
693
696
|
* Returns a JSON representation of this accessory suitable for delivering to HAP clients.
|
|
694
697
|
*/
|
|
695
698
|
async toHAP(connection, contactGetHandlers = true) {
|
|
696
|
-
|
|
697
|
-
|
|
699
|
+
(0, assert_1.default)(this.aid, "aid cannot be undefined for accessory '" + this.displayName + "'");
|
|
700
|
+
(0, assert_1.default)(this.services.length, "accessory '" + this.displayName + "' does not have any services!");
|
|
698
701
|
const accessory = {
|
|
699
702
|
aid: this.aid,
|
|
700
703
|
services: await Promise.all(this.services.map(service => service.toHAP(connection, contactGetHandlers))),
|
|
@@ -713,8 +716,8 @@ export class Accessory extends EventEmitter {
|
|
|
713
716
|
if (assignIds) {
|
|
714
717
|
this._assignIDs(this._identifierCache); // make sure our aid/iid's are all assigned
|
|
715
718
|
}
|
|
716
|
-
|
|
717
|
-
|
|
719
|
+
(0, assert_1.default)(this.aid, "aid cannot be undefined for accessory '" + this.displayName + "'");
|
|
720
|
+
(0, assert_1.default)(this.services.length, "accessory '" + this.displayName + "' does not have any services!");
|
|
718
721
|
const accessory = {
|
|
719
722
|
aid: this.aid,
|
|
720
723
|
services: this.services.map(service => service.internalHAPRepresentation()),
|
|
@@ -746,34 +749,34 @@ export class Accessory extends EventEmitter {
|
|
|
746
749
|
*/
|
|
747
750
|
async publish(info, allowInsecureRequest) {
|
|
748
751
|
if (this.bridged) {
|
|
749
|
-
throw new Error(
|
|
752
|
+
throw new Error("Can't publish in accessory which is bridged by another accessory. Bridged by " + this.bridge?.displayName);
|
|
750
753
|
}
|
|
751
|
-
let service = this.getService(Service.ProtocolInformation);
|
|
754
|
+
let service = this.getService(Service_1.Service.ProtocolInformation);
|
|
752
755
|
if (!service) {
|
|
753
|
-
service = this.addService(Service.ProtocolInformation); // add the protocol information service to the primary accessory
|
|
756
|
+
service = this.addService(Service_1.Service.ProtocolInformation); // add the protocol information service to the primary accessory
|
|
754
757
|
}
|
|
755
|
-
service.setCharacteristic(Characteristic.Version, CiaoAdvertiser.protocolVersionService);
|
|
758
|
+
service.setCharacteristic(Characteristic_1.Characteristic.Version, Advertiser_1.CiaoAdvertiser.protocolVersionService);
|
|
756
759
|
if (this.lastKnownUsername && this.lastKnownUsername !== info.username) { // username changed since last publish
|
|
757
760
|
Accessory.cleanupAccessoryData(this.lastKnownUsername); // delete old Accessory data
|
|
758
761
|
}
|
|
759
762
|
if (!this.initialized && (info.addIdentifyingMaterial ?? true)) {
|
|
760
763
|
// adding some identifying material to our displayName if it's our first publish() call
|
|
761
|
-
this.displayName =
|
|
762
|
-
.update(info.username,
|
|
763
|
-
.digest(
|
|
764
|
-
this.getService(Service.AccessoryInformation).updateCharacteristic(Characteristic.Name, this.displayName);
|
|
764
|
+
this.displayName = this.displayName + " " + crypto_1.default.createHash("sha512")
|
|
765
|
+
.update(info.username, "utf8")
|
|
766
|
+
.digest("hex").slice(0, 4).toUpperCase();
|
|
767
|
+
this.getService(Service_1.Service.AccessoryInformation).updateCharacteristic(Characteristic_1.Characteristic.Name, this.displayName);
|
|
765
768
|
}
|
|
766
769
|
// attempt to load existing AccessoryInfo from disk
|
|
767
|
-
this._accessoryInfo = AccessoryInfo.load(info.username);
|
|
770
|
+
this._accessoryInfo = AccessoryInfo_1.AccessoryInfo.load(info.username);
|
|
768
771
|
// if we don't have one, create a new one.
|
|
769
772
|
if (!this._accessoryInfo) {
|
|
770
|
-
debug(
|
|
771
|
-
this._accessoryInfo = AccessoryInfo.create(info.username);
|
|
773
|
+
debug("[%s] Creating new AccessoryInfo for our HAP server", this.displayName);
|
|
774
|
+
this._accessoryInfo = AccessoryInfo_1.AccessoryInfo.create(info.username);
|
|
772
775
|
}
|
|
773
776
|
if (info.setupID) {
|
|
774
777
|
this._setupID = info.setupID;
|
|
775
778
|
}
|
|
776
|
-
else if (this._accessoryInfo.setupID === undefined || this._accessoryInfo.setupID ===
|
|
779
|
+
else if (this._accessoryInfo.setupID === undefined || this._accessoryInfo.setupID === "") {
|
|
777
780
|
this._setupID = Accessory._generateSetupID();
|
|
778
781
|
}
|
|
779
782
|
else {
|
|
@@ -782,16 +785,16 @@ export class Accessory extends EventEmitter {
|
|
|
782
785
|
this._accessoryInfo.setupID = this._setupID;
|
|
783
786
|
// make sure we have up-to-date values in AccessoryInfo, then save it in case they changed (or if we just created it)
|
|
784
787
|
this._accessoryInfo.displayName = this.displayName;
|
|
785
|
-
this._accessoryInfo.model = this.getService(Service.AccessoryInformation).getCharacteristic(Characteristic.Model).value;
|
|
788
|
+
this._accessoryInfo.model = this.getService(Service_1.Service.AccessoryInformation).getCharacteristic(Characteristic_1.Characteristic.Model).value;
|
|
786
789
|
this._accessoryInfo.category = info.category || 1 /* Categories.OTHER */;
|
|
787
790
|
this._accessoryInfo.pincode = info.pincode;
|
|
788
791
|
this._accessoryInfo.save();
|
|
789
792
|
// create our IdentifierCache, so we can provide clients with stable aid/iid's
|
|
790
|
-
this._identifierCache = IdentifierCache.load(info.username);
|
|
793
|
+
this._identifierCache = IdentifierCache_1.IdentifierCache.load(info.username);
|
|
791
794
|
// if we don't have one, create a new one.
|
|
792
795
|
if (!this._identifierCache) {
|
|
793
|
-
debug(
|
|
794
|
-
this._identifierCache = new IdentifierCache(info.username);
|
|
796
|
+
debug("[%s] Creating new IdentifierCache", this.displayName);
|
|
797
|
+
this._identifierCache = new IdentifierCache_1.IdentifierCache(info.username);
|
|
795
798
|
}
|
|
796
799
|
// If it's bridge and there are no accessories already assigned to the bridge
|
|
797
800
|
// probably purge is not needed since it's going to delete all the ids
|
|
@@ -816,7 +819,6 @@ export class Accessory extends EventEmitter {
|
|
|
816
819
|
this.validateAccessory(true);
|
|
817
820
|
// create our Advertiser which broadcasts our presence over mdns
|
|
818
821
|
const parsed = Accessory.parseBindOption(info);
|
|
819
|
-
debug('[%s] Starting HAP server and publishing Accessory...', this.displayName);
|
|
820
822
|
// Select the advertiser to use based on the user's choice and availability
|
|
821
823
|
// 1. Check if info.advertiser is set by the user.
|
|
822
824
|
// 2. If info.advertiser is set, check if it is available.
|
|
@@ -829,16 +831,16 @@ export class Accessory extends EventEmitter {
|
|
|
829
831
|
// > If not, use ciao.
|
|
830
832
|
if (info.advertiser) {
|
|
831
833
|
const originalAdvertiser = info.advertiser;
|
|
832
|
-
debug(
|
|
833
|
-
if ((info.advertiser === "avahi" /* MDNSAdvertiser.AVAHI */ && await AvahiAdvertiser.isAvailable())
|
|
834
|
-
|| (info.advertiser === "resolved" /* MDNSAdvertiser.RESOLVED */ && await ResolvedAdvertiser.isAvailable())
|
|
834
|
+
debug("[%s] Advertiser set to %s", this.displayName, info.advertiser);
|
|
835
|
+
if ((info.advertiser === "avahi" /* MDNSAdvertiser.AVAHI */ && await Advertiser_1.AvahiAdvertiser.isAvailable())
|
|
836
|
+
|| (info.advertiser === "resolved" /* MDNSAdvertiser.RESOLVED */ && await Advertiser_1.ResolvedAdvertiser.isAvailable())
|
|
835
837
|
|| (info.advertiser === "bonjour-hap" /* MDNSAdvertiser.BONJOUR */)
|
|
836
838
|
|| (info.advertiser === "ciao" /* MDNSAdvertiser.CIAO */)) {
|
|
837
839
|
// User chosen advertiser is available, use it
|
|
838
|
-
debug(
|
|
840
|
+
debug("[%s] Using advertiser %s", this.displayName, info.advertiser);
|
|
839
841
|
}
|
|
840
842
|
else {
|
|
841
|
-
if (await AvahiAdvertiser.isAvailable()) {
|
|
843
|
+
if (await Advertiser_1.AvahiAdvertiser.isAvailable()) {
|
|
842
844
|
info.advertiser = "avahi" /* MDNSAdvertiser.AVAHI */;
|
|
843
845
|
}
|
|
844
846
|
else {
|
|
@@ -849,7 +851,7 @@ export class Accessory extends EventEmitter {
|
|
|
849
851
|
}
|
|
850
852
|
}
|
|
851
853
|
else {
|
|
852
|
-
if (await AvahiAdvertiser.isAvailable()) {
|
|
854
|
+
if (await Advertiser_1.AvahiAdvertiser.isAvailable()) {
|
|
853
855
|
info.advertiser = "avahi" /* MDNSAdvertiser.AVAHI */;
|
|
854
856
|
}
|
|
855
857
|
else {
|
|
@@ -858,7 +860,7 @@ export class Accessory extends EventEmitter {
|
|
|
858
860
|
}
|
|
859
861
|
switch (info.advertiser) {
|
|
860
862
|
case "ciao" /* MDNSAdvertiser.CIAO */:
|
|
861
|
-
this._advertiser = new CiaoAdvertiser(this._accessoryInfo, {
|
|
863
|
+
this._advertiser = new Advertiser_1.CiaoAdvertiser(this._accessoryInfo, {
|
|
862
864
|
interface: parsed.advertiserAddress,
|
|
863
865
|
}, {
|
|
864
866
|
restrictedAddresses: parsed.serviceRestrictedAddress,
|
|
@@ -866,31 +868,32 @@ export class Accessory extends EventEmitter {
|
|
|
866
868
|
});
|
|
867
869
|
break;
|
|
868
870
|
case "bonjour-hap" /* MDNSAdvertiser.BONJOUR */:
|
|
869
|
-
this._advertiser = new BonjourHAPAdvertiser(this._accessoryInfo, {
|
|
871
|
+
this._advertiser = new Advertiser_1.BonjourHAPAdvertiser(this._accessoryInfo, {
|
|
870
872
|
restrictedAddresses: parsed.serviceRestrictedAddress,
|
|
871
873
|
disabledIpv6: parsed.serviceDisableIpv6,
|
|
872
874
|
});
|
|
873
875
|
break;
|
|
874
876
|
case "avahi" /* MDNSAdvertiser.AVAHI */:
|
|
875
|
-
this._advertiser = new AvahiAdvertiser(this._accessoryInfo);
|
|
877
|
+
this._advertiser = new Advertiser_1.AvahiAdvertiser(this._accessoryInfo);
|
|
876
878
|
break;
|
|
877
879
|
case "resolved" /* MDNSAdvertiser.RESOLVED */:
|
|
878
|
-
this._advertiser = new ResolvedAdvertiser(this._accessoryInfo);
|
|
880
|
+
this._advertiser = new Advertiser_1.ResolvedAdvertiser(this._accessoryInfo);
|
|
879
881
|
break;
|
|
882
|
+
default:
|
|
883
|
+
throw new Error("Unsupported advertiser setting: '" + info.advertiser + "'");
|
|
880
884
|
}
|
|
881
|
-
|
|
882
|
-
this._advertiser.on("updated-name" /* AdvertiserEvent.UPDATED_NAME */, (name) => {
|
|
885
|
+
this._advertiser.on("updated-name" /* AdvertiserEvent.UPDATED_NAME */, name => {
|
|
883
886
|
this.displayName = name;
|
|
884
887
|
if (this._accessoryInfo) {
|
|
885
888
|
this._accessoryInfo.displayName = name;
|
|
886
889
|
this._accessoryInfo.save();
|
|
887
890
|
}
|
|
888
891
|
// bonjour service name MUST match the name in the accessory information service
|
|
889
|
-
this.getService(Service.AccessoryInformation)
|
|
890
|
-
.updateCharacteristic(Characteristic.Name, name);
|
|
892
|
+
this.getService(Service_1.Service.AccessoryInformation)
|
|
893
|
+
.updateCharacteristic(Characteristic_1.Characteristic.Name, name);
|
|
891
894
|
});
|
|
892
895
|
// create our HAP server which handles all communication between iOS devices and us
|
|
893
|
-
this._server = new HAPServer(this._accessoryInfo);
|
|
896
|
+
this._server = new HAPServer_1.HAPServer(this._accessoryInfo);
|
|
894
897
|
this._server.allowInsecureRequest = !!allowInsecureRequest;
|
|
895
898
|
this._server.on("listening" /* HAPServerEventTypes.LISTENING */, this.onListening.bind(this));
|
|
896
899
|
this._server.on("identify" /* HAPServerEventTypes.IDENTIFY */, this.identificationRequest.bind(this, false));
|
|
@@ -917,7 +920,7 @@ export class Accessory extends EventEmitter {
|
|
|
917
920
|
Accessory.cleanupAccessoryData(this._accessoryInfo.username);
|
|
918
921
|
this._accessoryInfo = undefined;
|
|
919
922
|
this._identifierCache = undefined;
|
|
920
|
-
this.controllerStorage = new ControllerStorage(this);
|
|
923
|
+
this.controllerStorage = new ControllerStorage_1.ControllerStorage(this);
|
|
921
924
|
}
|
|
922
925
|
this.removeAllListeners();
|
|
923
926
|
return promise;
|
|
@@ -928,7 +931,8 @@ export class Accessory extends EventEmitter {
|
|
|
928
931
|
this._server = undefined;
|
|
929
932
|
}
|
|
930
933
|
if (this._advertiser) {
|
|
931
|
-
|
|
934
|
+
// noinspection JSIgnoredPromiseFromCall
|
|
935
|
+
await this._advertiser.destroy();
|
|
932
936
|
this._advertiser = undefined;
|
|
933
937
|
}
|
|
934
938
|
}
|
|
@@ -954,25 +958,25 @@ export class Accessory extends EventEmitter {
|
|
|
954
958
|
// not responding or new accessories/services not yet shown
|
|
955
959
|
}
|
|
956
960
|
onListening(port, hostname) {
|
|
957
|
-
|
|
961
|
+
(0, assert_1.default)(this._advertiser, "Advertiser wasn't created at onListening!");
|
|
958
962
|
// the HAP server is listening, so we can now start advertising our presence.
|
|
959
963
|
this._advertiser.initPort(port);
|
|
960
964
|
this._advertiser.startAdvertising()
|
|
961
965
|
.then(() => this.emit("advertised" /* AccessoryEventTypes.ADVERTISED */))
|
|
962
|
-
.catch(
|
|
963
|
-
console.error(
|
|
966
|
+
.catch(reason => {
|
|
967
|
+
console.error("Could not create mDNS advertisement. The HAP-Server won't be discoverable: " + reason);
|
|
964
968
|
if (reason.stack) {
|
|
965
|
-
debug(
|
|
969
|
+
debug("Detailed error: " + reason.stack);
|
|
966
970
|
}
|
|
967
971
|
});
|
|
968
972
|
this.emit("listening" /* AccessoryEventTypes.LISTENING */, port, hostname);
|
|
969
973
|
}
|
|
970
974
|
handleInitialPairSetupFinished(username, publicKey, callback) {
|
|
971
|
-
debug(
|
|
972
|
-
this._accessoryInfo
|
|
973
|
-
this._accessoryInfo
|
|
975
|
+
debug("[%s] Paired with client %s", this.displayName, username);
|
|
976
|
+
this._accessoryInfo && this._accessoryInfo.addPairedClient(username, publicKey, 1 /* PermissionTypes.ADMIN */);
|
|
977
|
+
this._accessoryInfo && this._accessoryInfo.save();
|
|
974
978
|
// update our advertisement, so it can pick up on the paired status of AccessoryInfo
|
|
975
|
-
this._advertiser
|
|
979
|
+
this._advertiser && this._advertiser.updateAdvertisement();
|
|
976
980
|
callback();
|
|
977
981
|
this.emit("paired" /* AccessoryEventTypes.PAIRED */);
|
|
978
982
|
}
|
|
@@ -1013,7 +1017,7 @@ export class Accessory extends EventEmitter {
|
|
|
1013
1017
|
this._accessoryInfo.save();
|
|
1014
1018
|
callback(0); // first of all ensure the pairing is removed before we advertise availability again
|
|
1015
1019
|
if (!this._accessoryInfo.paired()) {
|
|
1016
|
-
this._advertiser
|
|
1020
|
+
this._advertiser && this._advertiser.updateAdvertisement();
|
|
1017
1021
|
this.emit("unpaired" /* AccessoryEventTypes.UNPAIRED */);
|
|
1018
1022
|
this.handleAccessoryUnpairedForControllers();
|
|
1019
1023
|
for (const accessory of this.bridgedAccessories) {
|
|
@@ -1037,19 +1041,19 @@ export class Accessory extends EventEmitter {
|
|
|
1037
1041
|
const now = Date.now();
|
|
1038
1042
|
const contactGetHandlers = now - this.lastAccessoriesRequest > 5_000; // we query the latest value if last /accessories was more than 5s ago
|
|
1039
1043
|
this.lastAccessoriesRequest = now;
|
|
1040
|
-
this.toHAP(connection, contactGetHandlers).then(
|
|
1044
|
+
this.toHAP(connection, contactGetHandlers).then(value => {
|
|
1041
1045
|
callback(undefined, {
|
|
1042
1046
|
accessories: value,
|
|
1043
1047
|
});
|
|
1044
|
-
},
|
|
1045
|
-
console.error(
|
|
1048
|
+
}, reason => {
|
|
1049
|
+
console.error("[" + this.displayName + "] /accessories request error with: " + reason.stack);
|
|
1046
1050
|
callback({ httpCode: 500 /* HAPHTTPCode.INTERNAL_SERVER_ERROR */, status: -70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */ });
|
|
1047
1051
|
});
|
|
1048
1052
|
}
|
|
1049
1053
|
handleGetCharacteristics(connection, request, callback) {
|
|
1050
1054
|
const characteristics = [];
|
|
1051
|
-
const response = { characteristics };
|
|
1052
|
-
const missingCharacteristics = new Set(request.ids.map(id =>
|
|
1055
|
+
const response = { characteristics: characteristics };
|
|
1056
|
+
const missingCharacteristics = new Set(request.ids.map(id => id.aid + "." + id.iid));
|
|
1053
1057
|
if (missingCharacteristics.size !== request.ids.length) {
|
|
1054
1058
|
// if those sizes differ, we have duplicates and can't properly handle that
|
|
1055
1059
|
callback({ httpCode: 422 /* HAPHTTPCode.UNPROCESSABLE_ENTITY */, status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ });
|
|
@@ -1057,27 +1061,29 @@ export class Accessory extends EventEmitter {
|
|
|
1057
1061
|
}
|
|
1058
1062
|
let timeout = setTimeout(() => {
|
|
1059
1063
|
for (const id of missingCharacteristics) {
|
|
1060
|
-
const split = id.split(
|
|
1061
|
-
const aid =
|
|
1062
|
-
const iid =
|
|
1064
|
+
const split = id.split(".");
|
|
1065
|
+
const aid = parseInt(split[0], 10);
|
|
1066
|
+
const iid = parseInt(split[1], 10);
|
|
1063
1067
|
const accessory = this.getAccessoryByAID(aid);
|
|
1064
1068
|
const characteristic = accessory.getCharacteristicByIID(iid);
|
|
1065
|
-
this.sendCharacteristicWarning(characteristic, "slow-read" /* CharacteristicWarningType.SLOW_READ */,
|
|
1069
|
+
this.sendCharacteristicWarning(characteristic, "slow-read" /* CharacteristicWarningType.SLOW_READ */, "The read handler for the characteristic '" +
|
|
1070
|
+
characteristic.displayName + "' on the accessory '" + accessory.displayName + "' was slow to respond!");
|
|
1066
1071
|
}
|
|
1067
1072
|
// after a total of 10s we do no longer wait for a request to appear and just return status code timeout
|
|
1068
1073
|
timeout = setTimeout(() => {
|
|
1069
1074
|
timeout = undefined;
|
|
1070
1075
|
for (const id of missingCharacteristics) {
|
|
1071
|
-
const split = id.split(
|
|
1072
|
-
const aid =
|
|
1073
|
-
const iid =
|
|
1076
|
+
const split = id.split(".");
|
|
1077
|
+
const aid = parseInt(split[0], 10);
|
|
1078
|
+
const iid = parseInt(split[1], 10);
|
|
1074
1079
|
const accessory = this.getAccessoryByAID(aid);
|
|
1075
1080
|
const characteristic = accessory.getCharacteristicByIID(iid);
|
|
1076
|
-
this.sendCharacteristicWarning(characteristic, "timeout-read" /* CharacteristicWarningType.TIMEOUT_READ */,
|
|
1077
|
-
+
|
|
1081
|
+
this.sendCharacteristicWarning(characteristic, "timeout-read" /* CharacteristicWarningType.TIMEOUT_READ */, "The read handler for the characteristic '" +
|
|
1082
|
+
characteristic.displayName + "' on the accessory '" + accessory.displayName + "' didn't respond at all!. " +
|
|
1083
|
+
"Please check that you properly call the callback!");
|
|
1078
1084
|
characteristics.push({
|
|
1079
|
-
aid,
|
|
1080
|
-
iid,
|
|
1085
|
+
aid: aid,
|
|
1086
|
+
iid: iid,
|
|
1081
1087
|
status: -70408 /* HAPStatus.OPERATION_TIMED_OUT */,
|
|
1082
1088
|
});
|
|
1083
1089
|
}
|
|
@@ -1088,21 +1094,21 @@ export class Accessory extends EventEmitter {
|
|
|
1088
1094
|
}, Accessory.TIMEOUT_WARNING);
|
|
1089
1095
|
timeout.unref();
|
|
1090
1096
|
for (const id of request.ids) {
|
|
1091
|
-
const name =
|
|
1092
|
-
this.handleCharacteristicRead(connection, id, request).then(
|
|
1097
|
+
const name = id.aid + "." + id.iid;
|
|
1098
|
+
this.handleCharacteristicRead(connection, id, request).then(value => {
|
|
1093
1099
|
return {
|
|
1094
1100
|
aid: id.aid,
|
|
1095
1101
|
iid: id.iid,
|
|
1096
1102
|
...value,
|
|
1097
1103
|
};
|
|
1098
|
-
},
|
|
1104
|
+
}, reason => {
|
|
1099
1105
|
console.error(`[${this.displayName}] Read request for characteristic ${name} encountered an error: ${reason.stack}`);
|
|
1100
1106
|
return {
|
|
1101
1107
|
aid: id.aid,
|
|
1102
1108
|
iid: id.iid,
|
|
1103
1109
|
status: -70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */,
|
|
1104
1110
|
};
|
|
1105
|
-
}).then(
|
|
1111
|
+
}).then(value => {
|
|
1106
1112
|
if (!timeout) {
|
|
1107
1113
|
return; // if timeout is undefined, response was already sent out
|
|
1108
1114
|
}
|
|
@@ -1121,25 +1127,25 @@ export class Accessory extends EventEmitter {
|
|
|
1121
1127
|
async handleCharacteristicRead(connection, id, request) {
|
|
1122
1128
|
const characteristic = this.findCharacteristic(id.aid, id.iid);
|
|
1123
1129
|
if (!characteristic) {
|
|
1124
|
-
debug(
|
|
1130
|
+
debug("[%s] Could not find a Characteristic with aid of %s and iid of %s", this.displayName, id.aid, id.iid);
|
|
1125
1131
|
return { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ };
|
|
1126
1132
|
}
|
|
1127
1133
|
if (!characteristic.props.perms.includes("pr" /* Perms.PAIRED_READ */)) { // check if read is allowed for this characteristic
|
|
1128
|
-
debug(
|
|
1134
|
+
debug("[%s] Tried reading from characteristic which does not allow reading (aid of %s and iid of %s)", this.displayName, id.aid, id.iid);
|
|
1129
1135
|
return { status: -70405 /* HAPStatus.WRITE_ONLY_CHARACTERISTIC */ };
|
|
1130
1136
|
}
|
|
1131
1137
|
if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(0 /* Access.READ */)) {
|
|
1132
1138
|
const verifiable = this._accessoryInfo && connection.username;
|
|
1133
1139
|
if (!verifiable) {
|
|
1134
|
-
debug(
|
|
1140
|
+
debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for reading (aid of %s and iid of %s)", this.displayName, id.aid, id.iid);
|
|
1135
1141
|
}
|
|
1136
1142
|
if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
|
|
1137
1143
|
return { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ };
|
|
1138
1144
|
}
|
|
1139
1145
|
}
|
|
1140
|
-
return characteristic.handleGetRequest(connection).then(
|
|
1141
|
-
value = formatOutgoingCharacteristicValue(value, characteristic.props);
|
|
1142
|
-
debug(
|
|
1146
|
+
return characteristic.handleGetRequest(connection).then(value => {
|
|
1147
|
+
value = (0, request_util_1.formatOutgoingCharacteristicValue)(value, characteristic.props);
|
|
1148
|
+
debug("[%s] Got Characteristic \"%s\" value: \"%s\"", this.displayName, characteristic.displayName, value);
|
|
1143
1149
|
const data = {
|
|
1144
1150
|
value: value == null ? null : value,
|
|
1145
1151
|
};
|
|
@@ -1155,7 +1161,7 @@ export class Accessory extends EventEmitter {
|
|
|
1155
1161
|
data.perms = characteristic.props.perms;
|
|
1156
1162
|
}
|
|
1157
1163
|
if (request.includeType) {
|
|
1158
|
-
data.type = toShortForm(characteristic.UUID);
|
|
1164
|
+
data.type = (0, uuid_1.toShortForm)(characteristic.UUID);
|
|
1159
1165
|
}
|
|
1160
1166
|
if (request.includeEvent) {
|
|
1161
1167
|
data.ev = connection.hasEventNotifications(id.aid, id.iid);
|
|
@@ -1163,12 +1169,12 @@ export class Accessory extends EventEmitter {
|
|
|
1163
1169
|
return data;
|
|
1164
1170
|
}, (reason) => {
|
|
1165
1171
|
// @ts-expect-error: preserveConstEnums compiler option
|
|
1166
|
-
debug(
|
|
1172
|
+
debug("[%s] Error getting value for characteristic \"%s\": %s", this.displayName, characteristic.displayName, HAPServer_1.HAPStatus[reason]);
|
|
1167
1173
|
return { status: reason };
|
|
1168
1174
|
});
|
|
1169
1175
|
}
|
|
1170
1176
|
handleSetCharacteristics(connection, writeRequest, callback) {
|
|
1171
|
-
debug(
|
|
1177
|
+
debug("[%s] Processing characteristic set: %s", this.displayName, JSON.stringify(writeRequest));
|
|
1172
1178
|
let writeState = 0 /* WriteRequestState.REGULAR_REQUEST */;
|
|
1173
1179
|
if (writeRequest.pid !== undefined) { // check for timed writes
|
|
1174
1180
|
if (connection.timedWritePid === writeRequest.pid) {
|
|
@@ -1176,17 +1182,17 @@ export class Accessory extends EventEmitter {
|
|
|
1176
1182
|
clearTimeout(connection.timedWriteTimeout);
|
|
1177
1183
|
connection.timedWritePid = undefined;
|
|
1178
1184
|
connection.timedWriteTimeout = undefined;
|
|
1179
|
-
debug(
|
|
1185
|
+
debug("[%s] Timed write request got acknowledged for pid %d", this.displayName, writeRequest.pid);
|
|
1180
1186
|
}
|
|
1181
1187
|
else {
|
|
1182
1188
|
writeState = 2 /* WriteRequestState.TIMED_WRITE_REJECTED */;
|
|
1183
|
-
debug(
|
|
1189
|
+
debug("[%s] TTL for timed write request has probably expired for pid %d", this.displayName, writeRequest.pid);
|
|
1184
1190
|
}
|
|
1185
1191
|
}
|
|
1186
1192
|
const characteristics = [];
|
|
1187
|
-
const response = { characteristics };
|
|
1193
|
+
const response = { characteristics: characteristics };
|
|
1188
1194
|
const missingCharacteristics = new Set(writeRequest.characteristics
|
|
1189
|
-
.map(characteristic =>
|
|
1195
|
+
.map(characteristic => characteristic.aid + "." + characteristic.iid));
|
|
1190
1196
|
if (missingCharacteristics.size !== writeRequest.characteristics.length) {
|
|
1191
1197
|
// if those sizes differ, we have duplicates and can't properly handle that
|
|
1192
1198
|
callback({ httpCode: 422 /* HAPHTTPCode.UNPROCESSABLE_ENTITY */, status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ });
|
|
@@ -1194,27 +1200,29 @@ export class Accessory extends EventEmitter {
|
|
|
1194
1200
|
}
|
|
1195
1201
|
let timeout = setTimeout(() => {
|
|
1196
1202
|
for (const id of missingCharacteristics) {
|
|
1197
|
-
const split = id.split(
|
|
1198
|
-
const aid =
|
|
1199
|
-
const iid =
|
|
1203
|
+
const split = id.split(".");
|
|
1204
|
+
const aid = parseInt(split[0], 10);
|
|
1205
|
+
const iid = parseInt(split[1], 10);
|
|
1200
1206
|
const accessory = this.getAccessoryByAID(aid);
|
|
1201
1207
|
const characteristic = accessory.getCharacteristicByIID(iid);
|
|
1202
|
-
this.sendCharacteristicWarning(characteristic, "slow-write" /* CharacteristicWarningType.SLOW_WRITE */,
|
|
1208
|
+
this.sendCharacteristicWarning(characteristic, "slow-write" /* CharacteristicWarningType.SLOW_WRITE */, "The write handler for the characteristic '" +
|
|
1209
|
+
characteristic.displayName + "' on the accessory '" + accessory.displayName + "' was slow to respond!");
|
|
1203
1210
|
}
|
|
1204
1211
|
// after a total of 10s we do no longer wait for a request to appear and just return status code timeout
|
|
1205
1212
|
timeout = setTimeout(() => {
|
|
1206
1213
|
timeout = undefined;
|
|
1207
1214
|
for (const id of missingCharacteristics) {
|
|
1208
|
-
const split = id.split(
|
|
1209
|
-
const aid =
|
|
1210
|
-
const iid =
|
|
1215
|
+
const split = id.split(".");
|
|
1216
|
+
const aid = parseInt(split[0], 10);
|
|
1217
|
+
const iid = parseInt(split[1], 10);
|
|
1211
1218
|
const accessory = this.getAccessoryByAID(aid);
|
|
1212
1219
|
const characteristic = accessory.getCharacteristicByIID(iid);
|
|
1213
|
-
this.sendCharacteristicWarning(characteristic, "timeout-write" /* CharacteristicWarningType.TIMEOUT_WRITE */,
|
|
1214
|
-
+
|
|
1220
|
+
this.sendCharacteristicWarning(characteristic, "timeout-write" /* CharacteristicWarningType.TIMEOUT_WRITE */, "The write handler for the characteristic '" +
|
|
1221
|
+
characteristic.displayName + "' on the accessory '" + accessory.displayName + "' didn't respond at all!. " +
|
|
1222
|
+
"Please check that you properly call the callback!");
|
|
1215
1223
|
characteristics.push({
|
|
1216
|
-
aid,
|
|
1217
|
-
iid,
|
|
1224
|
+
aid: aid,
|
|
1225
|
+
iid: iid,
|
|
1218
1226
|
status: -70408 /* HAPStatus.OPERATION_TIMED_OUT */,
|
|
1219
1227
|
});
|
|
1220
1228
|
}
|
|
@@ -1225,21 +1233,21 @@ export class Accessory extends EventEmitter {
|
|
|
1225
1233
|
}, Accessory.TIMEOUT_WARNING);
|
|
1226
1234
|
timeout.unref();
|
|
1227
1235
|
for (const data of writeRequest.characteristics) {
|
|
1228
|
-
const name =
|
|
1229
|
-
this.handleCharacteristicWrite(connection, data, writeState).then(
|
|
1236
|
+
const name = data.aid + "." + data.iid;
|
|
1237
|
+
this.handleCharacteristicWrite(connection, data, writeState).then(value => {
|
|
1230
1238
|
return {
|
|
1231
1239
|
aid: data.aid,
|
|
1232
1240
|
iid: data.iid,
|
|
1233
1241
|
...value,
|
|
1234
1242
|
};
|
|
1235
|
-
},
|
|
1243
|
+
}, reason => {
|
|
1236
1244
|
console.error(`[${this.displayName}] Write request for characteristic ${name} encountered an error: ${reason.stack}`);
|
|
1237
1245
|
return {
|
|
1238
1246
|
aid: data.aid,
|
|
1239
1247
|
iid: data.iid,
|
|
1240
1248
|
status: -70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */,
|
|
1241
1249
|
};
|
|
1242
|
-
}).then(
|
|
1250
|
+
}).then(value => {
|
|
1243
1251
|
if (!timeout) {
|
|
1244
1252
|
return; // if timeout is undefined, response was already sent out
|
|
1245
1253
|
}
|
|
@@ -1258,7 +1266,7 @@ export class Accessory extends EventEmitter {
|
|
|
1258
1266
|
async handleCharacteristicWrite(connection, data, writeState) {
|
|
1259
1267
|
const characteristic = this.findCharacteristic(data.aid, data.iid);
|
|
1260
1268
|
if (!characteristic) {
|
|
1261
|
-
debug(
|
|
1269
|
+
debug("[%s] Could not find a Characteristic with aid of %s and iid of %s", this.displayName, data.aid, data.iid);
|
|
1262
1270
|
return { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ };
|
|
1263
1271
|
}
|
|
1264
1272
|
if (writeState === 2 /* WriteRequestState.TIMED_WRITE_REJECTED */) {
|
|
@@ -1269,13 +1277,13 @@ export class Accessory extends EventEmitter {
|
|
|
1269
1277
|
}
|
|
1270
1278
|
if (data.ev != null) { // register/unregister event notifications
|
|
1271
1279
|
if (!characteristic.props.perms.includes("ev" /* Perms.NOTIFY */)) { // check if notify is allowed for this characteristic
|
|
1272
|
-
debug(
|
|
1280
|
+
debug("[%s] Tried %s notifications for Characteristic which does not allow notify (aid of %s and iid of %s)", this.displayName, data.ev ? "enabling" : "disabling", data.aid, data.iid);
|
|
1273
1281
|
return { status: -70406 /* HAPStatus.NOTIFICATION_NOT_SUPPORTED */ };
|
|
1274
1282
|
}
|
|
1275
1283
|
if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(2 /* Access.NOTIFY */)) {
|
|
1276
1284
|
const verifiable = connection.username && this._accessoryInfo;
|
|
1277
1285
|
if (!verifiable) {
|
|
1278
|
-
debug(
|
|
1286
|
+
debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for notify (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
|
|
1279
1287
|
}
|
|
1280
1288
|
if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
|
|
1281
1289
|
return { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ };
|
|
@@ -1285,24 +1293,24 @@ export class Accessory extends EventEmitter {
|
|
|
1285
1293
|
if (data.ev && !notificationsEnabled) {
|
|
1286
1294
|
connection.enableEventNotifications(data.aid, data.iid);
|
|
1287
1295
|
characteristic.subscribe();
|
|
1288
|
-
debug(
|
|
1296
|
+
debug("[%s] Registered Characteristic \"%s\" on \"%s\" for events", connection.remoteAddress, characteristic.displayName, this.displayName);
|
|
1289
1297
|
}
|
|
1290
1298
|
else if (!data.ev && notificationsEnabled) {
|
|
1291
1299
|
characteristic.unsubscribe();
|
|
1292
1300
|
connection.disableEventNotifications(data.aid, data.iid);
|
|
1293
|
-
debug(
|
|
1301
|
+
debug("[%s] Unregistered Characteristic \"%s\" on \"%s\" for events", connection.remoteAddress, characteristic.displayName, this.displayName);
|
|
1294
1302
|
}
|
|
1295
1303
|
// response is returned below in the else block
|
|
1296
1304
|
}
|
|
1297
1305
|
if (data.value != null) {
|
|
1298
1306
|
if (!characteristic.props.perms.includes("pw" /* Perms.PAIRED_WRITE */)) { // check if write is allowed for this characteristic
|
|
1299
|
-
debug(
|
|
1307
|
+
debug("[%s] Tried writing to Characteristic which does not allow writing (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
|
|
1300
1308
|
return { status: -70404 /* HAPStatus.READ_ONLY_CHARACTERISTIC */ };
|
|
1301
1309
|
}
|
|
1302
1310
|
if (characteristic.props.adminOnlyAccess && characteristic.props.adminOnlyAccess.includes(1 /* Access.WRITE */)) {
|
|
1303
1311
|
const verifiable = connection.username && this._accessoryInfo;
|
|
1304
1312
|
if (!verifiable) {
|
|
1305
|
-
debug(
|
|
1313
|
+
debug("[%s] Could not verify admin permissions for Characteristic which requires admin permissions for write (aid of %s and iid of %s)", this.displayName, data.aid, data.iid);
|
|
1306
1314
|
}
|
|
1307
1315
|
if (!verifiable || !this._accessoryInfo.hasAdminPermissions(connection.username)) {
|
|
1308
1316
|
return { status: -70401 /* HAPStatus.INSUFFICIENT_PRIVILEGES */ };
|
|
@@ -1316,7 +1324,7 @@ export class Accessory extends EventEmitter {
|
|
|
1316
1324
|
allowWrite = characteristic.additionalAuthorizationHandler(data.authData);
|
|
1317
1325
|
}
|
|
1318
1326
|
catch (error) {
|
|
1319
|
-
console.warn(
|
|
1327
|
+
console.warn("[" + this.displayName + "] Additional authorization handler has thrown an error when checking authData: " + error.stack);
|
|
1320
1328
|
allowWrite = false;
|
|
1321
1329
|
}
|
|
1322
1330
|
if (!allowWrite) {
|
|
@@ -1324,29 +1332,29 @@ export class Accessory extends EventEmitter {
|
|
|
1324
1332
|
}
|
|
1325
1333
|
}
|
|
1326
1334
|
if (characteristic.props.perms.includes("tw" /* Perms.TIMED_WRITE */) && writeState !== 1 /* WriteRequestState.TIMED_WRITE_AUTHENTICATED */) {
|
|
1327
|
-
debug(
|
|
1335
|
+
debug("[%s] Tried writing to a timed write only Characteristic without properly preparing (iid of %s and aid of %s)", this.displayName, data.aid, data.iid);
|
|
1328
1336
|
return { status: -70410 /* HAPStatus.INVALID_VALUE_IN_REQUEST */ };
|
|
1329
1337
|
}
|
|
1330
|
-
return characteristic.handleSetRequest(data.value, connection).then(
|
|
1331
|
-
debug(
|
|
1338
|
+
return characteristic.handleSetRequest(data.value, connection).then(value => {
|
|
1339
|
+
debug("[%s] Setting Characteristic \"%s\" to value %s", this.displayName, characteristic.displayName, data.value);
|
|
1332
1340
|
return {
|
|
1333
1341
|
// if write response is requests and value is provided, return that
|
|
1334
|
-
value: data.r && value ? formatOutgoingCharacteristicValue(value, characteristic.props) : undefined,
|
|
1342
|
+
value: data.r && value ? (0, request_util_1.formatOutgoingCharacteristicValue)(value, characteristic.props) : undefined,
|
|
1335
1343
|
status: 0 /* HAPStatus.SUCCESS */,
|
|
1336
1344
|
};
|
|
1337
1345
|
}, (status) => {
|
|
1338
|
-
// @ts-expect-error:
|
|
1339
|
-
debug(
|
|
1340
|
-
return { status };
|
|
1346
|
+
// @ts-expect-error: forceConsistentCasingInFileNames compiler option
|
|
1347
|
+
debug("[%s] Error setting Characteristic \"%s\" to value %s: ", this.displayName, characteristic.displayName, data.value, HAPServer_1.HAPStatus[status]);
|
|
1348
|
+
return { status: status };
|
|
1341
1349
|
});
|
|
1342
1350
|
}
|
|
1343
1351
|
return { status: 0 /* HAPStatus.SUCCESS */ };
|
|
1344
1352
|
}
|
|
1345
1353
|
handleResource(data, callback) {
|
|
1346
|
-
if (data[
|
|
1347
|
-
const aid = data.aid; // aid is optionally supplied by HomeKit (for example when camera is bridged, multiple cams, etc
|
|
1348
|
-
let accessory;
|
|
1349
|
-
let controller;
|
|
1354
|
+
if (data["resource-type"] === "image" /* ResourceRequestType.IMAGE */) {
|
|
1355
|
+
const aid = data.aid; // aid is optionally supplied by HomeKit (for example when camera is bridged, multiple cams, etc)
|
|
1356
|
+
let accessory = undefined;
|
|
1357
|
+
let controller = undefined;
|
|
1350
1358
|
if (aid) {
|
|
1351
1359
|
accessory = this.getAccessoryByAID(aid);
|
|
1352
1360
|
if (accessory && accessory.activeCameraController) {
|
|
@@ -1354,30 +1362,31 @@ export class Accessory extends EventEmitter {
|
|
|
1354
1362
|
}
|
|
1355
1363
|
}
|
|
1356
1364
|
else if (this.activeCameraController) { // aid was not supplied, check if this accessory is a camera
|
|
1357
|
-
|
|
1365
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1366
|
+
accessory = this;
|
|
1358
1367
|
controller = this.activeCameraController;
|
|
1359
1368
|
}
|
|
1360
1369
|
if (!controller) {
|
|
1361
|
-
debug(
|
|
1370
|
+
debug("[%s] received snapshot request though no camera controller was associated!");
|
|
1362
1371
|
callback({ httpCode: 404 /* HAPHTTPCode.NOT_FOUND */, status: -70409 /* HAPStatus.RESOURCE_DOES_NOT_EXIST */ });
|
|
1363
1372
|
return;
|
|
1364
1373
|
}
|
|
1365
|
-
controller.handleSnapshotRequest(data[
|
|
1366
|
-
.then(
|
|
1374
|
+
controller.handleSnapshotRequest(data["image-height"], data["image-width"], accessory?.displayName, data.reason)
|
|
1375
|
+
.then(buffer => {
|
|
1367
1376
|
callback(undefined, buffer);
|
|
1368
1377
|
}, (status) => {
|
|
1369
|
-
callback({ httpCode: 207 /* HAPHTTPCode.MULTI_STATUS */, status });
|
|
1378
|
+
callback({ httpCode: 207 /* HAPHTTPCode.MULTI_STATUS */, status: status });
|
|
1370
1379
|
});
|
|
1371
1380
|
return;
|
|
1372
1381
|
}
|
|
1373
|
-
debug(
|
|
1382
|
+
debug("[%s] received request for unsupported image type: " + data["resource-type"], this._accessoryInfo?.username);
|
|
1374
1383
|
callback({ httpCode: 404 /* HAPHTTPCode.NOT_FOUND */, status: -70409 /* HAPStatus.RESOURCE_DOES_NOT_EXIST */ });
|
|
1375
1384
|
}
|
|
1376
1385
|
handleHAPConnectionClosed(connection) {
|
|
1377
1386
|
for (const event of connection.getRegisteredEvents()) {
|
|
1378
|
-
const ids = event.split(
|
|
1379
|
-
const aid =
|
|
1380
|
-
const iid =
|
|
1387
|
+
const ids = event.split(".");
|
|
1388
|
+
const aid = parseInt(ids[0], 10);
|
|
1389
|
+
const iid = parseInt(ids[1], 10);
|
|
1381
1390
|
const characteristic = this.findCharacteristic(aid, iid);
|
|
1382
1391
|
if (characteristic) {
|
|
1383
1392
|
characteristic.unsubscribe();
|
|
@@ -1398,7 +1407,7 @@ export class Accessory extends EventEmitter {
|
|
|
1398
1407
|
this.primaryService = service;
|
|
1399
1408
|
}
|
|
1400
1409
|
if (this.bridged) {
|
|
1401
|
-
this.emit("service-configurationChange" /* AccessoryEventTypes.SERVICE_CONFIGURATION_CHANGE */, { service });
|
|
1410
|
+
this.emit("service-configurationChange" /* AccessoryEventTypes.SERVICE_CONFIGURATION_CHANGE */, { service: service });
|
|
1402
1411
|
}
|
|
1403
1412
|
else {
|
|
1404
1413
|
this.enqueueConfigurationUpdate();
|
|
@@ -1406,23 +1415,23 @@ export class Accessory extends EventEmitter {
|
|
|
1406
1415
|
}
|
|
1407
1416
|
handleCharacteristicChangeEvent(accessory, service, change) {
|
|
1408
1417
|
if (this.bridged) { // forward this to our main accessory
|
|
1409
|
-
this.emit("service-characteristic-change" /* AccessoryEventTypes.SERVICE_CHARACTERISTIC_CHANGE */, { ...change, service });
|
|
1418
|
+
this.emit("service-characteristic-change" /* AccessoryEventTypes.SERVICE_CHARACTERISTIC_CHANGE */, { ...change, service: service });
|
|
1410
1419
|
}
|
|
1411
1420
|
else {
|
|
1412
1421
|
if (!this._server) {
|
|
1413
1422
|
return; // we're not running a HAPServer, so there's no one to notify about this event
|
|
1414
1423
|
}
|
|
1415
1424
|
if (accessory.aid == null || change.characteristic.iid == null) {
|
|
1416
|
-
debug(
|
|
1425
|
+
debug("[%s] Muting event notification for %s as ids aren't yet assigned!", accessory.displayName, change.characteristic.displayName);
|
|
1417
1426
|
return;
|
|
1418
1427
|
}
|
|
1419
|
-
if (change.context != null && typeof change.context ===
|
|
1420
|
-
debug(
|
|
1428
|
+
if (change.context != null && typeof change.context === "object" && change.context.omitEventUpdate) {
|
|
1429
|
+
debug("[%s] Omitting event updates for %s as specified in the context object!", accessory.displayName, change.characteristic.displayName);
|
|
1421
1430
|
return;
|
|
1422
1431
|
}
|
|
1423
1432
|
if (!(change.reason === "event" /* ChangeReason.EVENT */ || change.oldValue !== change.newValue
|
|
1424
|
-
|| change.characteristic.UUID === Characteristic.ProgrammableSwitchEvent.UUID // those specific checks are out of backwards compatibility
|
|
1425
|
-
|| change.characteristic.UUID === Characteristic.ButtonEvent.UUID // new characteristics should use sendEventNotification call
|
|
1433
|
+
|| change.characteristic.UUID === Characteristic_1.Characteristic.ProgrammableSwitchEvent.UUID // those specific checks are out of backwards compatibility
|
|
1434
|
+
|| change.characteristic.UUID === Characteristic_1.Characteristic.ButtonEvent.UUID // new characteristics should use sendEventNotification call
|
|
1426
1435
|
)) {
|
|
1427
1436
|
// we only emit a change event if the reason was a call to sendEventNotification, if the value changed
|
|
1428
1437
|
// as of a write request or a read request or if the change happened on dedicated event characteristics
|
|
@@ -1430,26 +1439,26 @@ export class Accessory extends EventEmitter {
|
|
|
1430
1439
|
return;
|
|
1431
1440
|
}
|
|
1432
1441
|
const uuid = change.characteristic.UUID;
|
|
1433
|
-
const immediateDelivery = uuid === Characteristic.ButtonEvent.UUID || uuid === Characteristic.ProgrammableSwitchEvent.UUID
|
|
1434
|
-
|| uuid === Characteristic.MotionDetected.UUID || uuid === Characteristic.ContactSensorState.UUID;
|
|
1435
|
-
const value = formatOutgoingCharacteristicValue(change.newValue, change.characteristic.props);
|
|
1442
|
+
const immediateDelivery = uuid === Characteristic_1.Characteristic.ButtonEvent.UUID || uuid === Characteristic_1.Characteristic.ProgrammableSwitchEvent.UUID
|
|
1443
|
+
|| uuid === Characteristic_1.Characteristic.MotionDetected.UUID || uuid === Characteristic_1.Characteristic.ContactSensorState.UUID;
|
|
1444
|
+
const value = (0, request_util_1.formatOutgoingCharacteristicValue)(change.newValue, change.characteristic.props);
|
|
1436
1445
|
this._server.sendEventNotifications(accessory.aid, change.characteristic.iid, value, change.originator, immediateDelivery);
|
|
1437
1446
|
}
|
|
1438
1447
|
}
|
|
1439
1448
|
sendCharacteristicWarning(characteristic, type, message) {
|
|
1440
1449
|
this.handleCharacteristicWarning({
|
|
1441
|
-
characteristic,
|
|
1442
|
-
type,
|
|
1443
|
-
message,
|
|
1450
|
+
characteristic: characteristic,
|
|
1451
|
+
type: type,
|
|
1452
|
+
message: message,
|
|
1444
1453
|
originatorChain: [characteristic.displayName], // we are missing the service displayName, but that's okay
|
|
1445
|
-
stack: new Error().stack,
|
|
1454
|
+
stack: new Error().stack,
|
|
1446
1455
|
});
|
|
1447
1456
|
}
|
|
1448
1457
|
handleCharacteristicWarning(warning) {
|
|
1449
1458
|
warning.originatorChain = [this.displayName, ...warning.originatorChain];
|
|
1450
1459
|
const emitted = this.emit("characteristic-warning" /* AccessoryEventTypes.CHARACTERISTIC_WARNING */, warning);
|
|
1451
1460
|
if (!emitted) {
|
|
1452
|
-
const message = `[${warning.originatorChain.join(
|
|
1461
|
+
const message = `[${warning.originatorChain.join("@")}] ${warning.message}`;
|
|
1453
1462
|
if (warning.type === "error-message" /* CharacteristicWarningType.ERROR_MESSAGE */
|
|
1454
1463
|
|| warning.type === "timeout-read" /* CharacteristicWarningType.TIMEOUT_READ */ || warning.type === "timeout-write" /* CharacteristicWarningType.TIMEOUT_WRITE */) {
|
|
1455
1464
|
console.error(message);
|
|
@@ -1457,7 +1466,7 @@ export class Accessory extends EventEmitter {
|
|
|
1457
1466
|
else {
|
|
1458
1467
|
console.warn(message);
|
|
1459
1468
|
}
|
|
1460
|
-
debug(
|
|
1469
|
+
debug("[%s] Above characteristic warning was thrown at: %s", this.displayName, warning.stack ?? "unknown");
|
|
1461
1470
|
}
|
|
1462
1471
|
}
|
|
1463
1472
|
setupServiceEventHandlers(service) {
|
|
@@ -1472,8 +1481,8 @@ export class Accessory extends EventEmitter {
|
|
|
1472
1481
|
this.services = targetServices.slice();
|
|
1473
1482
|
// Fix Identify
|
|
1474
1483
|
this
|
|
1475
|
-
.getService(Service.AccessoryInformation)
|
|
1476
|
-
.getCharacteristic(Characteristic.Identify)
|
|
1484
|
+
.getService(Service_1.Service.AccessoryInformation)
|
|
1485
|
+
.getCharacteristic(Characteristic_1.Characteristic.Identify)
|
|
1477
1486
|
.on("set" /* CharacteristicEventTypes.SET */, (value, callback) => {
|
|
1478
1487
|
if (value) {
|
|
1479
1488
|
const paired = true;
|
|
@@ -1482,9 +1491,9 @@ export class Accessory extends EventEmitter {
|
|
|
1482
1491
|
});
|
|
1483
1492
|
}
|
|
1484
1493
|
static _generateSetupID() {
|
|
1485
|
-
const chars =
|
|
1494
|
+
const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
1486
1495
|
const max = chars.length;
|
|
1487
|
-
let setupID =
|
|
1496
|
+
let setupID = "";
|
|
1488
1497
|
for (let i = 0; i < 4; i++) {
|
|
1489
1498
|
const index = Math.floor(Math.random() * max);
|
|
1490
1499
|
setupID += chars.charAt(index);
|
|
@@ -1502,10 +1511,10 @@ export class Accessory extends EventEmitter {
|
|
|
1502
1511
|
};
|
|
1503
1512
|
const linkedServices = {};
|
|
1504
1513
|
let hasLinkedServices = false;
|
|
1505
|
-
accessory.services.forEach(
|
|
1506
|
-
json.services.push(Service.serialize(service));
|
|
1514
|
+
accessory.services.forEach(service => {
|
|
1515
|
+
json.services.push(Service_1.Service.serialize(service));
|
|
1507
1516
|
const linkedServicesPresentation = [];
|
|
1508
|
-
service.linkedServices.forEach(
|
|
1517
|
+
service.linkedServices.forEach(linkedService => {
|
|
1509
1518
|
linkedServicesPresentation.push(linkedService.getServiceId());
|
|
1510
1519
|
});
|
|
1511
1520
|
if (linkedServicesPresentation.length > 0) {
|
|
@@ -1525,7 +1534,7 @@ export class Accessory extends EventEmitter {
|
|
|
1525
1534
|
});
|
|
1526
1535
|
});
|
|
1527
1536
|
// also save controller which didn't get initialized (could lead to service duplication if we throw that data away)
|
|
1528
|
-
Object.entries(accessory.serializedControllers
|
|
1537
|
+
accessory.serializedControllers && Object.entries(accessory.serializedControllers).forEach(([id, serviceMap]) => {
|
|
1529
1538
|
controllers.push({
|
|
1530
1539
|
type: id,
|
|
1531
1540
|
services: Accessory.serializeServiceMap(serviceMap),
|
|
@@ -1542,8 +1551,8 @@ export class Accessory extends EventEmitter {
|
|
|
1542
1551
|
accessory.category = json.category;
|
|
1543
1552
|
const services = [];
|
|
1544
1553
|
const servicesMap = {};
|
|
1545
|
-
json.services.forEach(
|
|
1546
|
-
const service = Service.deserialize(serialized);
|
|
1554
|
+
json.services.forEach(serialized => {
|
|
1555
|
+
const service = Service_1.Service.deserialize(serialized);
|
|
1547
1556
|
services.push(service);
|
|
1548
1557
|
servicesMap[service.getServiceId()] = service;
|
|
1549
1558
|
});
|
|
@@ -1553,7 +1562,7 @@ export class Accessory extends EventEmitter {
|
|
|
1553
1562
|
if (!primaryService) {
|
|
1554
1563
|
continue;
|
|
1555
1564
|
}
|
|
1556
|
-
linkedServicesKeys.forEach(
|
|
1565
|
+
linkedServicesKeys.forEach(linkedServiceKey => {
|
|
1557
1566
|
const linkedService = servicesMap[linkedServiceKey];
|
|
1558
1567
|
if (linkedService) {
|
|
1559
1568
|
primaryService.addLinkedService(linkedService);
|
|
@@ -1563,7 +1572,7 @@ export class Accessory extends EventEmitter {
|
|
|
1563
1572
|
}
|
|
1564
1573
|
if (json.controllers) { // just save it for later if it exists {@see configureController}
|
|
1565
1574
|
accessory.serializedControllers = {};
|
|
1566
|
-
json.controllers.forEach(
|
|
1575
|
+
json.controllers.forEach(serializedController => {
|
|
1567
1576
|
accessory.serializedControllers[serializedController.type] = Accessory.deserializeServiceMap(serializedController.services, servicesMap);
|
|
1568
1577
|
});
|
|
1569
1578
|
}
|
|
@@ -1571,9 +1580,9 @@ export class Accessory extends EventEmitter {
|
|
|
1571
1580
|
return accessory;
|
|
1572
1581
|
}
|
|
1573
1582
|
static cleanupAccessoryData(username) {
|
|
1574
|
-
IdentifierCache.remove(username);
|
|
1575
|
-
AccessoryInfo.remove(username);
|
|
1576
|
-
ControllerStorage.remove(username);
|
|
1583
|
+
IdentifierCache_1.IdentifierCache.remove(username);
|
|
1584
|
+
AccessoryInfo_1.AccessoryInfo.remove(username);
|
|
1585
|
+
ControllerStorage_1.ControllerStorage.remove(username);
|
|
1577
1586
|
}
|
|
1578
1587
|
static serializeServiceMap(serviceMap) {
|
|
1579
1588
|
const serialized = {};
|
|
@@ -1596,22 +1605,22 @@ export class Accessory extends EventEmitter {
|
|
|
1596
1605
|
return controllerServiceMap;
|
|
1597
1606
|
}
|
|
1598
1607
|
static parseBindOption(info) {
|
|
1599
|
-
let advertiserAddress;
|
|
1600
|
-
let disableIpv6;
|
|
1601
|
-
let serverAddress;
|
|
1608
|
+
let advertiserAddress = undefined;
|
|
1609
|
+
let disableIpv6 = undefined;
|
|
1610
|
+
let serverAddress = undefined;
|
|
1602
1611
|
if (info.bind) {
|
|
1603
1612
|
const entries = new Set(Array.isArray(info.bind) ? info.bind : [info.bind]);
|
|
1604
|
-
if (entries.has(
|
|
1605
|
-
serverAddress =
|
|
1606
|
-
entries.delete(
|
|
1613
|
+
if (entries.has("::")) {
|
|
1614
|
+
serverAddress = "::";
|
|
1615
|
+
entries.delete("::");
|
|
1607
1616
|
if (entries.size) {
|
|
1608
1617
|
advertiserAddress = Array.from(entries);
|
|
1609
1618
|
}
|
|
1610
1619
|
}
|
|
1611
|
-
else if (entries.has(
|
|
1620
|
+
else if (entries.has("0.0.0.0")) {
|
|
1612
1621
|
disableIpv6 = true;
|
|
1613
|
-
serverAddress =
|
|
1614
|
-
entries.delete(
|
|
1622
|
+
serverAddress = "0.0.0.0";
|
|
1623
|
+
entries.delete("0.0.0.0");
|
|
1615
1624
|
if (entries.size) {
|
|
1616
1625
|
advertiserAddress = Array.from(entries);
|
|
1617
1626
|
}
|
|
@@ -1619,38 +1628,39 @@ export class Accessory extends EventEmitter {
|
|
|
1619
1628
|
else if (entries.size === 1) {
|
|
1620
1629
|
advertiserAddress = Array.from(entries);
|
|
1621
1630
|
const entry = entries.values().next().value; // grab the first one
|
|
1622
|
-
const version = isIP(entry); // check if ip address was specified or an interface name
|
|
1631
|
+
const version = net_1.default.isIP(entry); // check if ip address was specified or an interface name
|
|
1623
1632
|
if (version) {
|
|
1624
|
-
serverAddress = version === 4 ?
|
|
1633
|
+
serverAddress = version === 4 ? "0.0.0.0" : "::"; // we currently bind to unspecified addresses so config-ui always has a connection via loopback
|
|
1625
1634
|
}
|
|
1626
1635
|
else {
|
|
1627
|
-
serverAddress =
|
|
1636
|
+
serverAddress = "::"; // the interface could have both ipv4 and ipv6 addresses
|
|
1628
1637
|
}
|
|
1629
1638
|
}
|
|
1630
1639
|
else if (entries.size > 1) {
|
|
1631
1640
|
advertiserAddress = Array.from(entries);
|
|
1632
1641
|
let bindUnspecifiedIpv6 = false; // we bind on "::" if there are interface names, or we detect ipv6 addresses
|
|
1633
1642
|
for (const entry of entries) {
|
|
1634
|
-
const version = isIP(entry);
|
|
1643
|
+
const version = net_1.default.isIP(entry);
|
|
1635
1644
|
if (version === 0 || version === 6) {
|
|
1636
1645
|
bindUnspecifiedIpv6 = true;
|
|
1637
1646
|
break;
|
|
1638
1647
|
}
|
|
1639
1648
|
}
|
|
1640
1649
|
if (bindUnspecifiedIpv6) {
|
|
1641
|
-
serverAddress =
|
|
1650
|
+
serverAddress = "::";
|
|
1642
1651
|
}
|
|
1643
1652
|
else {
|
|
1644
|
-
serverAddress =
|
|
1653
|
+
serverAddress = "0.0.0.0";
|
|
1645
1654
|
}
|
|
1646
1655
|
}
|
|
1647
1656
|
}
|
|
1648
1657
|
return {
|
|
1649
|
-
advertiserAddress,
|
|
1658
|
+
advertiserAddress: advertiserAddress,
|
|
1650
1659
|
serviceRestrictedAddress: advertiserAddress,
|
|
1651
1660
|
serviceDisableIpv6: disableIpv6,
|
|
1652
|
-
serverAddress,
|
|
1661
|
+
serverAddress: serverAddress,
|
|
1653
1662
|
};
|
|
1654
1663
|
}
|
|
1655
1664
|
}
|
|
1665
|
+
exports.Accessory = Accessory;
|
|
1656
1666
|
//# sourceMappingURL=Accessory.js.map
|