node-red-contrib-homekit-bridged 2.0.0-dev.5 → 2.0.0-dev.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/build/lib/HAPHostNode.js +183 -141
  2. package/build/lib/HAPServiceNode.js +199 -172
  3. package/build/lib/HAPServiceNode2.js +207 -172
  4. package/build/lib/NRCHKBError.js +23 -2
  5. package/build/lib/PairingQRCode.js +62 -0
  6. package/build/lib/Storage.js +152 -90
  7. package/build/lib/api.js +654 -288
  8. package/build/lib/camera/CameraControl.js +119 -84
  9. package/build/lib/camera/CameraDelegate.js +481 -404
  10. package/build/lib/camera/MP4StreamingServer.js +148 -139
  11. package/build/lib/hap/HAPCharacteristic.js +25 -4
  12. package/build/lib/hap/HAPService.js +25 -4
  13. package/build/lib/hap/eve-app/EveCharacteristics.js +124 -81
  14. package/build/lib/hap/eve-app/EveServices.js +50 -17
  15. package/build/lib/hap/hap-nodejs.js +32 -0
  16. package/build/lib/migration/HomeKitService2Migration.js +34 -0
  17. package/build/lib/migration/NodeMigration.js +75 -0
  18. package/build/lib/types/AccessoryInformationType.js +15 -1
  19. package/build/lib/types/CameraConfigType.js +15 -1
  20. package/build/lib/types/CustomCharacteristicType.js +15 -1
  21. package/build/lib/types/HAPHostConfigType.js +15 -1
  22. package/build/lib/types/HAPHostNodeType.js +15 -1
  23. package/build/lib/types/HAPService2ConfigType.js +15 -1
  24. package/build/lib/types/HAPService2NodeType.js +15 -1
  25. package/build/lib/types/HAPServiceConfigType.js +15 -1
  26. package/build/lib/types/HAPServiceNodeType.js +15 -1
  27. package/build/lib/types/HAPStatusConfigType.js +15 -1
  28. package/build/lib/types/HAPStatusNodeType.js +15 -1
  29. package/build/lib/types/HostType.js +28 -7
  30. package/build/lib/types/NodeType.js +15 -1
  31. package/build/lib/types/PublishTimersType.js +15 -1
  32. package/build/lib/types/UniFiControllerConfigType.js +16 -0
  33. package/build/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.js +28 -7
  34. package/build/lib/types/hap-nodejs/HapCategories.js +64 -43
  35. package/build/lib/types/storage/SerializedHostType.js +15 -1
  36. package/build/lib/types/storage/StorageType.js +34 -10
  37. package/build/lib/unifi/ProtectDiscovery.js +80 -0
  38. package/build/lib/utils/AccessoryUtils.js +152 -110
  39. package/build/lib/utils/BridgeUtils.js +82 -39
  40. package/build/lib/utils/CharacteristicUtils.js +5 -49
  41. package/build/lib/utils/CharacteristicUtils2.js +5 -49
  42. package/build/lib/utils/CharacteristicUtilsBase.js +81 -0
  43. package/build/lib/utils/NodeStatusUtils.js +89 -40
  44. package/build/lib/utils/ServiceUtils.js +433 -375
  45. package/build/lib/utils/ServiceUtils2.js +519 -309
  46. package/build/lib/utils/index.js +10 -11
  47. package/build/nodes/bridge.html +206 -168
  48. package/build/nodes/bridge.js +27 -9
  49. package/build/nodes/locales/en-US/node-red-contrib-homekit-bridged.json +22 -0
  50. package/build/nodes/nrchkb.html +1753 -117
  51. package/build/nodes/nrchkb.js +66 -88
  52. package/build/nodes/plugin-instance.html +509 -0
  53. package/build/nodes/plugin-instance.js +46 -0
  54. package/build/nodes/service.html +544 -307
  55. package/build/nodes/service.js +5 -6
  56. package/build/nodes/service2.html +1721 -455
  57. package/build/nodes/service2.js +5 -8
  58. package/build/nodes/standalone.html +208 -176
  59. package/build/nodes/standalone.js +27 -9
  60. package/build/nodes/status.html +51 -18
  61. package/build/nodes/status.js +47 -40
  62. package/build/nodes/unifi-controller.html +92 -0
  63. package/build/nodes/unifi-controller.js +20 -0
  64. package/build/plugins/embedded/homebridge-camera-ffmpeg/index.js +479 -0
  65. package/build/plugins/embedded/homebridge-unifi-protect/index.js +521 -0
  66. package/build/plugins/embedded/index.js +58 -0
  67. package/build/plugins/nrchkb-homekit-plugins.js +17 -0
  68. package/build/plugins/registry/index.js +203 -0
  69. package/build/plugins/registry/types.js +16 -0
  70. package/build/scripts/migrate-homekit-service-flows.js +47 -0
  71. package/examples/demo/01 - ALL Demos single import.json +1885 -1885
  72. package/examples/demo/02 - Air Purifier.json +279 -279
  73. package/examples/demo/03 - Air Quality sensor with Battery.json +254 -254
  74. package/examples/demo/04 - Dimmable Bulb.json +172 -172
  75. package/examples/demo/05 - Color Bulb (HSV).json +195 -195
  76. package/examples/demo/06 - Fan (simple, 3 speeds).json +240 -240
  77. package/examples/demo/07 - Fan (with speed, oscillate, rotation direction).json +175 -175
  78. package/examples/demo/08 - CO2 detector.json +224 -224
  79. package/examples/demo/09 - CO (carbon monoxide) example.json +255 -255
  80. package/examples/demo/10 - Door window contact sensor.json +234 -234
  81. package/examples/demos (advanced)/01 - Television with inputs and speaker.json +541 -541
  82. package/examples/switch/01 - Plain Switch.json +178 -178
  83. package/package.json +95 -84
  84. package/build/lib/HAPHostNode.d.ts +0 -1
  85. package/build/lib/HAPServiceNode.d.ts +0 -1
  86. package/build/lib/HAPServiceNode2.d.ts +0 -1
  87. package/build/lib/NRCHKBError.d.ts +0 -3
  88. package/build/lib/Storage.d.ts +0 -30
  89. package/build/lib/api.d.ts +0 -1
  90. package/build/lib/camera/CameraControl.d.ts +0 -3
  91. package/build/lib/camera/CameraDelegate.d.ts +0 -38
  92. package/build/lib/camera/MP4StreamingServer.d.ts +0 -26
  93. package/build/lib/hap/HAPCharacteristic.d.ts +0 -9
  94. package/build/lib/hap/HAPService.d.ts +0 -6
  95. package/build/lib/hap/eve-app/EveCharacteristics.d.ts +0 -20
  96. package/build/lib/hap/eve-app/EveServices.d.ts +0 -5
  97. package/build/lib/types/AccessoryInformationType.d.ts +0 -11
  98. package/build/lib/types/CameraConfigType.d.ts +0 -24
  99. package/build/lib/types/CustomCharacteristicType.d.ts +0 -6
  100. package/build/lib/types/HAPHostConfigType.d.ts +0 -22
  101. package/build/lib/types/HAPHostNodeType.d.ts +0 -14
  102. package/build/lib/types/HAPService2ConfigType.d.ts +0 -6
  103. package/build/lib/types/HAPService2NodeType.d.ts +0 -7
  104. package/build/lib/types/HAPServiceConfigType.d.ts +0 -26
  105. package/build/lib/types/HAPServiceNodeType.d.ts +0 -38
  106. package/build/lib/types/HAPStatusConfigType.d.ts +0 -5
  107. package/build/lib/types/HAPStatusNodeType.d.ts +0 -12
  108. package/build/lib/types/HostType.d.ts +0 -5
  109. package/build/lib/types/NodeType.d.ts +0 -3
  110. package/build/lib/types/PublishTimersType.d.ts +0 -4
  111. package/build/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.d.ts +0 -5
  112. package/build/lib/types/hap-nodejs/HapCategories.d.ts +0 -41
  113. package/build/lib/types/storage/SerializedHostType.d.ts +0 -5
  114. package/build/lib/types/storage/StorageType.d.ts +0 -8
  115. package/build/lib/utils/AccessoryUtils.d.ts +0 -1
  116. package/build/lib/utils/BridgeUtils.d.ts +0 -1
  117. package/build/lib/utils/CharacteristicUtils.d.ts +0 -1
  118. package/build/lib/utils/CharacteristicUtils2.d.ts +0 -1
  119. package/build/lib/utils/NodeStatusUtils.d.ts +0 -17
  120. package/build/lib/utils/ServiceUtils.d.ts +0 -1
  121. package/build/lib/utils/ServiceUtils2.d.ts +0 -1
  122. package/build/lib/utils/index.d.ts +0 -1
  123. package/build/nodes/bridge.d.ts +0 -1
  124. package/build/nodes/nrchkb.d.ts +0 -1
  125. package/build/nodes/service.d.ts +0 -1
  126. package/build/nodes/service2.d.ts +0 -1
  127. package/build/nodes/standalone.d.ts +0 -1
  128. package/build/nodes/status.d.ts +0 -1
@@ -1,388 +1,446 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var import_hap_nodejs = require("@homebridge/hap-nodejs");
25
+ var import_logger = require("@nrchkb/logger");
26
+ var import_CameraControl = require("../camera/CameraControl");
27
+ var import_NRCHKBError = __toESM(require("../NRCHKBError"));
28
+ const buildAdaptiveLightingOptions = (config) => ({
29
+ controllerMode: config.adaptiveLightingOptionsMode !== void 0 ? +config.adaptiveLightingOptionsMode : import_hap_nodejs.AdaptiveLightingControllerMode.AUTOMATIC,
30
+ customTemperatureAdjustment: config.adaptiveLightingOptionsCustomTemperatureAdjustment !== void 0 ? +config.adaptiveLightingOptionsCustomTemperatureAdjustment : void 0
17
31
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
32
+ const describeContext = (context) => {
33
+ if (context === null) {
34
+ return "null";
35
+ }
36
+ if (context === void 0) {
37
+ return "undefined";
38
+ }
39
+ const type = typeof context;
40
+ if (type !== "object") {
41
+ return String(context);
42
+ }
43
+ if (Array.isArray(context)) {
44
+ return `Array(${context.length})`;
45
+ }
46
+ const keys = Object.keys(context);
47
+ return keys.length > 0 ? `Object(${keys.slice(0, 5).join(",")}${keys.length > 5 ? ",..." : ""})` : "Object";
37
48
  };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const util = __importStar(require("node:util"));
40
- const hap_nodejs_1 = require("@homebridge/hap-nodejs");
41
- const logger_1 = require("@nrchkb/logger");
42
- const CameraControl_1 = require("../camera/CameraControl");
43
- const NRCHKBError_1 = __importDefault(require("../NRCHKBError"));
44
- module.exports = (node) => {
45
- const log = (0, logger_1.logger)('NRCHKB', 'ServiceUtils', node.config.name, node);
46
- const HapNodeJS = require('@homebridge/hap-nodejs');
47
- const Service = HapNodeJS.Service;
48
- const Characteristic = HapNodeJS.Characteristic;
49
- const NO_RESPONSE_MSG = 'NO_RESPONSE';
50
- const prepareHapData = (context, connection) => {
51
- const hap = {};
52
- if (connection) {
53
- hap.session = {
54
- sessionID: connection.sessionID,
55
- username: connection.username,
56
- remoteAddress: connection.remoteAddress,
57
- localAddress: connection.localAddress,
58
- httpPort: connection.remotePort
59
- };
60
- hap.context = {};
61
- }
62
- if (context) {
63
- hap.context = context;
64
- }
65
- return hap;
66
- };
67
- const onCharacteristicGet = function (callback, context, connection) {
68
- var _a, _b;
69
- log.debug(`onCharacteristicGet with status: ${this.statusCode}, value: ${this.value}, reachability is ${((_a = node.parentNode) !== null && _a !== void 0 ? _a : node).reachable} with context ${util.inspect(context)} on connection ${connection === null || connection === void 0 ? void 0 : connection.sessionID}`);
70
- if (callback) {
71
- try {
72
- callback(((_b = node.parentNode) !== null && _b !== void 0 ? _b : node).reachable
73
- ? null
74
- : new hap_nodejs_1.HapStatusError(-70402), this.value);
75
- }
76
- catch (_) { }
77
- }
78
- };
79
- const onValueChange = function (allCharacteristics, outputNumber, { oldValue, newValue, context }, connection) {
80
- var _a, _b, _c, _d, _e;
81
- const topic = node.config.topic ? node.config.topic : node.topic_in;
82
- const msg = { payload: {}, hap: {}, name: node.name, topic: topic };
83
- const key = this.constructor.name;
84
- msg.payload[key] = newValue;
85
- msg.hap = prepareHapData(context, connection);
86
- msg.hap.allChars = allCharacteristics.reduce((allChars, singleChar) => {
87
- const cKey = singleChar.constructor.name;
88
- allChars[cKey] = singleChar.value;
89
- return allChars;
90
- }, {});
91
- if (oldValue !== undefined) {
92
- msg.hap.oldValue = oldValue;
93
- }
94
- msg.hap.reachable = (_a = node.reachable) !== null && _a !== void 0 ? _a : (_b = node.parentNode) === null || _b === void 0 ? void 0 : _b.reachable;
95
- if (msg.hap.reachable === false) {
96
- ;
97
- [node, ...((_c = node.childNodes) !== null && _c !== void 0 ? _c : [])].forEach((n) => {
98
- n.nodeStatusUtils.setStatus({
99
- fill: 'red',
100
- shape: 'ring',
101
- text: 'Not reachable',
102
- type: 'NO_RESPONSE'
103
- });
104
- });
105
- }
106
- else {
107
- msg.hap.newValue = newValue;
108
- node.nodeStatusUtils.setStatus({
109
- fill: 'yellow',
110
- shape: 'dot',
111
- text: `${key}: ${newValue}`
112
- }, 3000);
113
- (_d = node.childNodes) === null || _d === void 0 ? void 0 : _d.forEach((n) => {
114
- n.nodeStatusUtils.clearStatusByType('NO_RESPONSE');
115
- });
116
- (_e = node.parentNode) === null || _e === void 0 ? void 0 : _e.nodeStatusUtils.clearStatusByType('NO_RESPONSE');
117
- }
118
- log.debug(`${node.name} received ${key} : ${newValue}`);
119
- if (connection || context || node.hostNode.config.allowMessagePassthrough) {
120
- if (outputNumber === 0) {
121
- node.send(msg);
122
- }
123
- else if (outputNumber === 1) {
124
- node.send([null, msg]);
125
- }
126
- }
127
- };
128
- const onCharacteristicSet = (allCharacteristics) => function (newValue, callback, context, connection) {
129
- var _a, _b;
130
- log.debug(`onCharacteristicSet with status: ${this.statusCode}, value: ${this.value}, reachability is ${((_a = node.parentNode) !== null && _a !== void 0 ? _a : node).reachable}
131
- with context ${util.inspect(context)} on connection ${connection === null || connection === void 0 ? void 0 : connection.sessionID}`);
132
- try {
133
- if (callback) {
134
- callback(((_b = node.parentNode) !== null && _b !== void 0 ? _b : node).reachable
135
- ? null
136
- : new hap_nodejs_1.HapStatusError(-70402));
137
- }
138
- }
139
- catch (_) { }
140
- onValueChange.call(this, allCharacteristics, 1, {
141
- newValue,
142
- context
143
- }, connection);
144
- };
145
- const onCharacteristicChange = (allCharacteristics) => function (change) {
146
- var _a;
147
- const { oldValue, newValue, context, originator, reason } = change;
148
- log.debug(`onCharacteristicChange with reason: ${reason}, oldValue: ${oldValue}, newValue: ${newValue}, reachability is ${((_a = node.parentNode) !== null && _a !== void 0 ? _a : node).reachable}
149
- with context ${util.inspect(context)} on connection ${originator === null || originator === void 0 ? void 0 : originator.sessionID}`);
150
- if (oldValue !== newValue) {
151
- onValueChange.call(this, allCharacteristics, 0, {
152
- oldValue,
153
- newValue,
154
- context
155
- }, originator);
156
- }
157
- };
158
- const onInput = (msg) => {
159
- var _a, _b;
160
- if (msg.payload) {
161
- const type = typeof msg.payload;
162
- if (type !== 'object') {
163
- log.error(`Invalid payload type: ${type}`);
164
- return;
165
- }
166
- }
167
- else {
168
- log.error('Invalid message (payload missing)');
169
- return;
49
+ const describeSupported = (supported) => Array.from(supported).join("', '");
50
+ const buildServiceUtils = (node) => {
51
+ const log = (0, import_logger.logger)("NRCHKB", "ServiceUtils", node.config.name, node);
52
+ const { Service, Characteristic } = require("@homebridge/hap-nodejs");
53
+ const NO_RESPONSE_MSG = "NO_RESPONSE";
54
+ const prepareHapData = (context, connection) => {
55
+ const hap = {};
56
+ if (connection) {
57
+ hap.session = {
58
+ sessionID: connection.sessionID,
59
+ username: connection.username,
60
+ remoteAddress: connection.remoteAddress,
61
+ localAddress: connection.localAddress,
62
+ httpPort: connection.remotePort
63
+ };
64
+ hap.context = {};
65
+ }
66
+ if (context) {
67
+ hap.context = context;
68
+ }
69
+ return hap;
70
+ };
71
+ const onCharacteristicGet = function(callback, context, connection) {
72
+ const reachability = (node.parentNode ?? node).reachable;
73
+ log.debug(
74
+ `onCharacteristicGet with status: ${this.statusCode}, value: ${this.value}, reachability is ${reachability} with context ${describeContext(context)} on connection ${connection?.sessionID}`
75
+ );
76
+ if (callback) {
77
+ try {
78
+ callback(
79
+ (node.parentNode ?? node).reachable ? null : new import_hap_nodejs.HapStatusError(
80
+ import_hap_nodejs.HAPStatus.SERVICE_COMMUNICATION_FAILURE
81
+ ),
82
+ this.value
83
+ );
84
+ } catch (_) {
85
+ }
86
+ }
87
+ };
88
+ const onValueChange = function(allCharacteristics, outputNumber, { oldValue, newValue, context }, connection) {
89
+ const topic = node.config.topic ? node.config.topic : node.topic_in;
90
+ const msg = { payload: {}, hap: {}, name: node.name, topic };
91
+ const key = this.constructor.name;
92
+ msg.payload[key] = newValue;
93
+ msg.hap = prepareHapData(context, connection);
94
+ const allChars = {};
95
+ for (const singleChar of allCharacteristics) {
96
+ const cKey = singleChar.constructor.name;
97
+ allChars[cKey] = singleChar.value;
98
+ }
99
+ msg.hap.allChars = allChars;
100
+ if (oldValue !== void 0) {
101
+ msg.hap.oldValue = oldValue;
102
+ }
103
+ msg.hap.reachable = node.reachable ?? node.parentNode?.reachable;
104
+ if (msg.hap.reachable === false) {
105
+ ;
106
+ [node, ...node.childNodes ?? []].forEach((n) => {
107
+ n.nodeStatusUtils.setStatus({
108
+ fill: "red",
109
+ shape: "ring",
110
+ text: "Not reachable",
111
+ type: "NO_RESPONSE"
112
+ });
113
+ });
114
+ } else {
115
+ msg.hap.newValue = newValue;
116
+ node.nodeStatusUtils.setStatus(
117
+ {
118
+ fill: "yellow",
119
+ shape: "dot",
120
+ text: `${key}: ${newValue}`
121
+ },
122
+ 3e3
123
+ );
124
+ node.childNodes?.forEach((n) => {
125
+ n.nodeStatusUtils.clearStatusByType("NO_RESPONSE");
126
+ });
127
+ node.parentNode?.nodeStatusUtils.clearStatusByType("NO_RESPONSE");
128
+ }
129
+ log.debug(`${node.name} received ${key} : ${newValue}`);
130
+ if (connection || context || node.hostNode.config.allowMessagePassthrough) {
131
+ if (outputNumber === 0) {
132
+ node.send(msg);
133
+ } else if (outputNumber === 1) {
134
+ node.send([null, msg]);
135
+ }
136
+ }
137
+ };
138
+ const onCharacteristicSet = (allCharacteristics) => function(newValue, callback, context, connection) {
139
+ const reachability = (node.parentNode ?? node).reachable;
140
+ log.debug(
141
+ `onCharacteristicSet with status: ${this.statusCode}, value: ${this.value}, reachability is ${reachability} with context ${describeContext(context)} on connection ${connection?.sessionID}`
142
+ );
143
+ try {
144
+ if (callback) {
145
+ callback(
146
+ (node.parentNode ?? node).reachable ? null : new import_hap_nodejs.HapStatusError(
147
+ import_hap_nodejs.HAPStatus.SERVICE_COMMUNICATION_FAILURE
148
+ )
149
+ );
150
+ }
151
+ } catch (_) {
152
+ }
153
+ onValueChange.call(
154
+ this,
155
+ allCharacteristics,
156
+ 1,
157
+ {
158
+ newValue,
159
+ context
160
+ },
161
+ connection
162
+ );
163
+ };
164
+ const onCharacteristicChange = (allCharacteristics) => function(change) {
165
+ const { oldValue, newValue, context, originator, reason } = change;
166
+ log.debug(
167
+ `onCharacteristicChange with reason: ${reason}, oldValue: ${oldValue}, newValue: ${newValue}, reachability is ${(node.parentNode ?? node).reachable} with context ${describeContext(context)} on connection ${originator?.sessionID}`
168
+ );
169
+ if (oldValue !== newValue) {
170
+ onValueChange.call(
171
+ this,
172
+ allCharacteristics,
173
+ 0,
174
+ {
175
+ oldValue,
176
+ newValue,
177
+ context
178
+ },
179
+ originator
180
+ );
181
+ }
182
+ };
183
+ const onInput = (msg) => {
184
+ if (msg.payload) {
185
+ const type = typeof msg.payload;
186
+ if (type !== "object") {
187
+ log.error(`Invalid payload type: ${type}`);
188
+ return;
189
+ }
190
+ } else {
191
+ log.error("Invalid message (payload missing)");
192
+ return;
193
+ }
194
+ const topic = node.config.topic ?? node.name;
195
+ if (node.config.filter && msg.topic !== topic) {
196
+ log.debug(
197
+ "msg.topic doesn't match configured value and filter is enabled. Dropping message."
198
+ );
199
+ return;
200
+ }
201
+ let context = null;
202
+ if (msg.payload.Context) {
203
+ context = msg.payload.Context;
204
+ delete msg.payload.Context;
205
+ }
206
+ node.topic_in = msg.topic ?? "";
207
+ for (const key in msg.payload) {
208
+ if (!Object.hasOwn(msg.payload, key)) {
209
+ continue;
210
+ }
211
+ if (!node.supported.has(key)) {
212
+ if (key === "AdaptiveLightingController" && node.adaptiveLightingController) {
213
+ const value = msg.payload?.[key];
214
+ const event = value?.event;
215
+ if (event === "disable") {
216
+ node.adaptiveLightingController?.disableAdaptiveLighting();
217
+ }
218
+ } else {
219
+ log.error(
220
+ `Instead of '${key}' try one of these characteristics: '${describeSupported(node.supported)}'`
221
+ );
170
222
  }
171
- const topic = (_a = node.config.topic) !== null && _a !== void 0 ? _a : node.name;
172
- if (node.config.filter && msg.topic !== topic) {
173
- log.debug("msg.topic doesn't match configured value and filter is enabled. Dropping message.");
174
- return;
223
+ } else {
224
+ const value = msg.payload?.[key];
225
+ const normalizedValue = value === NO_RESPONSE_MSG ? false : value;
226
+ const parentNode = node.parentNode ?? node;
227
+ parentNode.reachable = value !== NO_RESPONSE_MSG;
228
+ const characteristic = node.service.getCharacteristic(
229
+ Characteristic[key]
230
+ );
231
+ if (context !== null) {
232
+ characteristic.setValue(normalizedValue, context);
233
+ } else {
234
+ characteristic.setValue(normalizedValue);
175
235
  }
176
- let context = null;
177
- if (msg.payload.Context) {
178
- context = msg.payload.Context;
179
- delete msg.payload.Context;
236
+ }
237
+ }
238
+ };
239
+ const onClose = (removed, done) => {
240
+ if (node.waitForParentTimer) {
241
+ clearTimeout(node.waitForParentTimer);
242
+ node.waitForParentTimer = void 0;
243
+ }
244
+ Object.values(node.publishTimers).forEach((timer) => {
245
+ clearTimeout(timer);
246
+ });
247
+ node.publishTimers = {};
248
+ const characteristics = node.service ? node.service.characteristics.concat(
249
+ node.service.optionalCharacteristics
250
+ ) : [];
251
+ characteristics.forEach((characteristic) => {
252
+ characteristic.removeListener("get", node.onCharacteristicGet);
253
+ characteristic.removeListener("set", node.onCharacteristicSet);
254
+ characteristic.removeListener("change", node.onCharacteristicChange);
255
+ });
256
+ if (node.config.isParent && node.accessory && node.onIdentify) {
257
+ node.accessory.removeListener("identify", node.onIdentify);
258
+ }
259
+ if (removed && node.accessory) {
260
+ if (node.config.isParent) {
261
+ node.hostNode.host.removeBridgedAccessories([node.accessory]);
262
+ node.accessory.destroy();
263
+ } else if (node.service && node.parentService) {
264
+ node.accessory.removeService(node.service);
265
+ node.parentService.removeLinkedService(node.service);
266
+ }
267
+ }
268
+ node.nodeStatusUtils.cleanup();
269
+ done();
270
+ };
271
+ const getOrCreate = (accessory, serviceInformation, parentService) => {
272
+ if (serviceInformation.serviceName === "CameraControl") {
273
+ let service2 = accessory.services.find(
274
+ (service3) => {
275
+ return service3.UUID === Service.CameraRTPStreamManagement.UUID;
180
276
  }
181
- node.topic_in = (_b = msg.topic) !== null && _b !== void 0 ? _b : '';
182
- Object.keys(msg.payload).forEach((key) => {
183
- var _a, _b, _c, _d;
184
- if (node.supported.indexOf(key) < 0) {
185
- if (key === 'AdaptiveLightingController' &&
186
- node.adaptiveLightingController) {
187
- const value = (_a = msg.payload) === null || _a === void 0 ? void 0 : _a[key];
188
- const event = value === null || value === void 0 ? void 0 : value.event;
189
- if (event === 'disable') {
190
- (_b = node.adaptiveLightingController) === null || _b === void 0 ? void 0 : _b.disableAdaptiveLighting();
191
- }
192
- }
193
- else {
194
- log.error(`Instead of '${key}' try one of these characteristics: '${node.supported.join("', '")}'`);
195
- }
196
- }
197
- else {
198
- const value = (_c = msg.payload) === null || _c === void 0 ? void 0 : _c[key];
199
- const parentNode = (_d = node.parentNode) !== null && _d !== void 0 ? _d : node;
200
- parentNode.reachable = value !== NO_RESPONSE_MSG;
201
- const characteristic = node.service.getCharacteristic(Characteristic[key]);
202
- if (context !== null) {
203
- characteristic.setValue(value, context);
204
- }
205
- else {
206
- characteristic.setValue(value);
207
- }
208
- }
209
- });
210
- };
211
- const onClose = (removed, done) => {
212
- const characteristics = node.service.characteristics.concat(node.service.optionalCharacteristics);
213
- characteristics.forEach((characteristic) => {
214
- characteristic.removeListener('get', node.onCharacteristicGet);
215
- characteristic.removeListener('set', node.onCharacteristicSet);
216
- characteristic.removeListener('change', node.onCharacteristicChange);
277
+ );
278
+ if (!service2) {
279
+ configureCameraSource(accessory, serviceInformation.config);
280
+ service2 = accessory.services.find((service3) => {
281
+ return service3.UUID === Service.CameraRTPStreamManagement.UUID;
217
282
  });
218
- if (node.config.isParent) {
219
- node.accessory.removeListener('identify', node.onIdentify);
283
+ }
284
+ if (!service2) {
285
+ throw new import_NRCHKBError.default(
286
+ "Failed to configure CameraControl service."
287
+ );
288
+ }
289
+ return service2;
290
+ }
291
+ const ServiceConstructor = Service[serviceInformation.serviceName];
292
+ if (typeof ServiceConstructor !== "function") {
293
+ throw new import_NRCHKBError.default(
294
+ `Unknown HomeKit service "${serviceInformation.serviceName}".`
295
+ );
296
+ }
297
+ const newService = new ServiceConstructor(
298
+ serviceInformation.name,
299
+ serviceInformation.UUID
300
+ );
301
+ log.debug(
302
+ `Looking for service with UUID ${serviceInformation.UUID} ...`
303
+ );
304
+ let service = accessory.services.find(
305
+ (service2) => {
306
+ return newService.subtype === service2.subtype;
307
+ }
308
+ );
309
+ if (service && newService.UUID !== service.UUID) {
310
+ log.debug("... service type changed! Removing the old service.");
311
+ accessory.removeService(service);
312
+ service = void 0;
313
+ }
314
+ if (!service) {
315
+ log.debug(
316
+ `... didn't find it. Adding new ${serviceInformation.serviceName} service.`
317
+ );
318
+ service = accessory.addService(newService);
319
+ } else {
320
+ log.debug("... found it! Updating it.");
321
+ service.getCharacteristic(Characteristic.Name).setValue(serviceInformation.name);
322
+ }
323
+ if (parentService) {
324
+ if (service) {
325
+ log.debug("... and linking service to parent.");
326
+ parentService.addLinkedService(service);
327
+ }
328
+ }
329
+ return service ?? newService;
330
+ };
331
+ const configureCameraSource = (accessory, config) => {
332
+ if (config.cameraConfigSource) {
333
+ log.debug("Configuring Camera Source");
334
+ if (!config.cameraConfigVideoProcessor) {
335
+ log.error(
336
+ "Missing configuration for CameraControl: videoProcessor cannot be empty!"
337
+ );
338
+ } else {
339
+ (0, import_CameraControl.configureCamera)(accessory, config);
340
+ }
341
+ } else {
342
+ log.error("Missing configuration for CameraControl.");
343
+ }
344
+ };
345
+ const waitForParent = () => {
346
+ log.debug("Waiting for Parent Service");
347
+ return new Promise((resolve) => {
348
+ node.nodeStatusUtils.setStatus({
349
+ fill: "blue",
350
+ shape: "dot",
351
+ text: "Waiting for Parent Service"
352
+ });
353
+ const checkAndWait = () => {
354
+ const parentNode = node.RED.nodes.getNode(
355
+ node.config.parentService
356
+ );
357
+ if (parentNode?.configured) {
358
+ node.waitForParentTimer = void 0;
359
+ resolve(parentNode);
360
+ } else {
361
+ node.waitForParentTimer = setTimeout(checkAndWait, 1e3);
220
362
  }
221
- if (removed) {
222
- if (node.config.isParent) {
223
- node.hostNode.host.removeBridgedAccessories([node.accessory]);
224
- node.accessory.destroy();
225
- }
226
- else {
227
- node.accessory.removeService(node.service);
228
- node.parentService.removeLinkedService(node.service);
363
+ };
364
+ checkAndWait();
365
+ }).catch((error) => {
366
+ log.error(`Waiting for Parent Service failed due to: ${error}`);
367
+ throw new import_NRCHKBError.default(error);
368
+ });
369
+ };
370
+ const handleWaitForSetup = (config, msg, resolve) => {
371
+ if (node.setupDone) {
372
+ return;
373
+ }
374
+ if (msg && Object.hasOwn(msg, "payload") && msg.payload && typeof msg.payload === "object" && Object.hasOwn(msg.payload, "nrchkb") && msg.payload.nrchkb && typeof msg.payload.nrchkb === "object" && Object.hasOwn(msg.payload.nrchkb, "setup")) {
375
+ node.setupDone = true;
376
+ const newConfig = {
377
+ ...config,
378
+ ...msg.payload.nrchkb.setup
379
+ };
380
+ node.removeListener("input", node.handleWaitForSetup);
381
+ resolve(newConfig);
382
+ } else {
383
+ log.error(
384
+ 'Invalid message (required {"payload":{"nrchkb":{"setup":{}}}})'
385
+ );
386
+ }
387
+ };
388
+ const configureAdaptiveLightning = () => {
389
+ if (node.service.UUID === Service.Lightbulb.UUID && node.config.adaptiveLightingOptionsEnable) {
390
+ try {
391
+ node.service.getCharacteristic(Characteristic.Brightness);
392
+ node.service.getCharacteristic(Characteristic.ColorTemperature);
393
+ const options = buildAdaptiveLightingOptions(node.config);
394
+ log.trace(`Configuring Adaptive Lighting with options:`);
395
+ log.trace(JSON.stringify(options));
396
+ const adaptiveLightingController = new import_hap_nodejs.AdaptiveLightingController(node.service, options);
397
+ adaptiveLightingController.on("update", () => {
398
+ const activeAdaptiveLightingTransition = {
399
+ transitionStartMillis: adaptiveLightingController.getAdaptiveLightingStartTimeOfTransition(),
400
+ timeMillisOffset: adaptiveLightingController.getAdaptiveLightingTimeOffset(),
401
+ transitionCurve: adaptiveLightingController.getAdaptiveLightingTransitionCurve(),
402
+ brightnessAdjustmentRange: adaptiveLightingController.getAdaptiveLightingBrightnessMultiplierRange(),
403
+ updateInterval: adaptiveLightingController.getAdaptiveLightingUpdateInterval(),
404
+ notifyIntervalThreshold: adaptiveLightingController.getAdaptiveLightingNotifyIntervalThreshold()
405
+ };
406
+ node.send({
407
+ payload: {
408
+ AdaptiveLightingController: {
409
+ event: "update",
410
+ data: activeAdaptiveLightingTransition
411
+ }
229
412
  }
230
- }
231
- done();
232
- };
233
- const getOrCreate = (accessory, serviceInformation, parentService) => {
234
- const newService = new Service[serviceInformation.serviceName](serviceInformation.name, serviceInformation.UUID);
235
- log.debug(`Looking for service with UUID ${serviceInformation.UUID} ...`);
236
- let service = accessory.services.find((service) => {
237
- return newService.subtype === service.subtype;
413
+ });
238
414
  });
239
- if (service && newService.UUID !== service.UUID) {
240
- log.debug('... service type changed! Removing the old service.');
241
- accessory.removeService(service);
242
- service = undefined;
243
- }
244
- if (!service) {
245
- log.debug(`... didn't find it. Adding new ${serviceInformation.serviceName} service.`);
246
- if (serviceInformation.serviceName === 'CameraControl') {
247
- configureCameraSource(accessory, newService, serviceInformation.config);
248
- service = newService;
249
- }
250
- else {
251
- service = accessory.addService(newService);
415
+ adaptiveLightingController.on("disable", () => {
416
+ node.send({
417
+ payload: {
418
+ AdaptiveLightingController: {
419
+ event: "disable"
420
+ }
252
421
  }
253
- }
254
- else {
255
- log.debug('... found it! Updating it.');
256
- service
257
- .getCharacteristic(Characteristic.Name)
258
- .setValue(serviceInformation.name);
259
- }
260
- if (parentService) {
261
- if (serviceInformation.serviceName === 'CameraControl') {
262
- log.debug('... and adding service to accessory.');
263
- }
264
- else if (service) {
265
- log.debug('... and linking service to parent.');
266
- parentService.addLinkedService(service);
267
- }
268
- }
269
- return service;
270
- };
271
- const configureCameraSource = (accessory, _service, config) => {
272
- if (config.cameraConfigSource) {
273
- log.debug('Configuring Camera Source');
274
- if (!config.cameraConfigVideoProcessor) {
275
- log.error('Missing configuration for CameraControl: videoProcessor cannot be empty!');
276
- }
277
- else {
278
- (0, CameraControl_1.configureCamera)(accessory, config);
279
- }
280
- }
281
- else {
282
- log.error('Missing configuration for CameraControl.');
283
- }
284
- };
285
- const waitForParent = () => {
286
- log.debug('Waiting for Parent Service');
287
- return new Promise((resolve) => {
288
- node.nodeStatusUtils.setStatus({
289
- fill: 'blue',
290
- shape: 'dot',
291
- text: 'Waiting for Parent Service'
292
- });
293
- const checkAndWait = () => {
294
- const parentNode = node.RED.nodes.getNode(node.config.parentService);
295
- if (parentNode === null || parentNode === void 0 ? void 0 : parentNode.configured) {
296
- resolve(parentNode);
297
- }
298
- else {
299
- setTimeout(checkAndWait, 1000);
300
- }
301
- };
302
- checkAndWait();
303
- }).catch((error) => {
304
- log.error(`Waiting for Parent Service failed due to: ${error}`);
305
- throw new NRCHKBError_1.default(error);
422
+ });
306
423
  });
307
- };
308
- const handleWaitForSetup = (config, msg, resolve) => {
309
- if (node.setupDone) {
310
- return;
311
- }
312
- if (Object.hasOwn(msg, 'payload') &&
313
- Object.hasOwn(msg.payload, 'nrchkb') &&
314
- Object.hasOwn(msg.payload.nrchkb, 'setup')) {
315
- node.setupDone = true;
316
- const newConfig = Object.assign(Object.assign({}, config), msg.payload.nrchkb.setup);
317
- node.removeListener('input', node.handleWaitForSetup);
318
- resolve(newConfig);
319
- }
320
- else {
321
- log.error('Invalid message (required {"payload":{"nrchkb":{"setup":{}}}})');
322
- }
323
- };
324
- const configureAdaptiveLightning = () => {
325
- if (node.service.UUID === Service.Lightbulb.UUID &&
326
- node.config.adaptiveLightingOptionsEnable) {
327
- try {
328
- node.service.getCharacteristic(Characteristic.Brightness);
329
- node.service.getCharacteristic(Characteristic.ColorTemperature);
330
- const options = {
331
- controllerMode: node.config.adaptiveLightingOptionsMode
332
- ? +node.config.adaptiveLightingOptionsMode
333
- : 1,
334
- customTemperatureAdjustment: node.config
335
- .adaptiveLightingOptionsCustomTemperatureAdjustment
336
- ? +node.config.adaptiveLightingOptionsCustomTemperatureAdjustment
337
- : undefined
338
- };
339
- log.trace(`Configuring Adaptive Lighting with options:`);
340
- log.trace(JSON.stringify(options));
341
- const adaptiveLightingController = new hap_nodejs_1.AdaptiveLightingController(node.service, options);
342
- adaptiveLightingController.on('update', () => {
343
- const activeAdaptiveLightingTransition = {
344
- transitionStartMillis: adaptiveLightingController.getAdaptiveLightingStartTimeOfTransition(),
345
- timeMillisOffset: adaptiveLightingController.getAdaptiveLightingTimeOffset(),
346
- transitionCurve: adaptiveLightingController.getAdaptiveLightingTransitionCurve(),
347
- brightnessAdjustmentRange: adaptiveLightingController.getAdaptiveLightingBrightnessMultiplierRange(),
348
- updateInterval: adaptiveLightingController.getAdaptiveLightingUpdateInterval(),
349
- notifyIntervalThreshold: adaptiveLightingController.getAdaptiveLightingNotifyIntervalThreshold()
350
- };
351
- node.send({
352
- payload: {
353
- AdaptiveLightingController: {
354
- event: 'update',
355
- data: activeAdaptiveLightingTransition
356
- }
357
- }
358
- });
359
- });
360
- adaptiveLightingController.on('disable', () => {
361
- node.send({
362
- payload: {
363
- AdaptiveLightingController: {
364
- event: 'disable'
365
- }
366
- }
367
- });
368
- });
369
- node.accessory.configureController(adaptiveLightingController);
370
- node.adaptiveLightingController = adaptiveLightingController;
371
- }
372
- catch (error) {
373
- log.error(`Failed to configure Adaptive Lightning due to ${error}`);
374
- }
375
- }
376
- };
377
- return {
378
- getOrCreate,
379
- onCharacteristicGet,
380
- onCharacteristicSet,
381
- onCharacteristicChange,
382
- onInput,
383
- onClose,
384
- waitForParent,
385
- handleWaitForSetup,
386
- configureAdaptiveLightning
387
- };
424
+ node.accessory.configureController(adaptiveLightingController);
425
+ node.adaptiveLightingController = adaptiveLightingController;
426
+ } catch (error) {
427
+ log.error(
428
+ `Failed to configure Adaptive Lightning due to ${error}`
429
+ );
430
+ }
431
+ }
432
+ };
433
+ return {
434
+ getOrCreate,
435
+ onCharacteristicGet,
436
+ onCharacteristicSet,
437
+ onCharacteristicChange,
438
+ onInput,
439
+ onClose,
440
+ waitForParent,
441
+ handleWaitForSetup,
442
+ configureAdaptiveLightning
443
+ };
388
444
  };
445
+ buildServiceUtils.buildAdaptiveLightingOptions = buildAdaptiveLightingOptions;
446
+ module.exports = buildServiceUtils;