node-red-contrib-homekit-bridged 2.0.0-dev.5 → 2.0.0-dev.7
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/build/lib/HAPHostNode.js +183 -141
- package/build/lib/HAPServiceNode.js +199 -172
- package/build/lib/HAPServiceNode2.js +207 -172
- package/build/lib/NRCHKBError.js +23 -2
- package/build/lib/PairingQRCode.js +62 -0
- package/build/lib/Storage.js +157 -92
- package/build/lib/api.js +654 -288
- package/build/lib/camera/CameraControl.js +119 -84
- package/build/lib/camera/CameraDelegate.js +481 -404
- package/build/lib/camera/MP4StreamingServer.js +148 -139
- package/build/lib/hap/HAPCharacteristic.js +25 -4
- package/build/lib/hap/HAPService.js +25 -4
- package/build/lib/hap/eve-app/EveCharacteristics.js +124 -81
- package/build/lib/hap/eve-app/EveServices.js +50 -17
- package/build/lib/hap/hap-nodejs.js +32 -0
- package/build/lib/migration/HomeKitService2Migration.js +34 -0
- package/build/lib/migration/NodeMigration.js +75 -0
- package/build/lib/types/AccessoryInformationType.js +15 -1
- package/build/lib/types/CameraConfigType.js +15 -1
- package/build/lib/types/CustomCharacteristicType.js +15 -1
- package/build/lib/types/HAPHostConfigType.js +15 -1
- package/build/lib/types/HAPHostNodeType.js +15 -1
- package/build/lib/types/HAPService2ConfigType.js +15 -1
- package/build/lib/types/HAPService2NodeType.js +15 -1
- package/build/lib/types/HAPServiceConfigType.js +15 -1
- package/build/lib/types/HAPServiceNodeType.js +15 -1
- package/build/lib/types/HAPStatusConfigType.js +15 -1
- package/build/lib/types/HAPStatusNodeType.js +15 -1
- package/build/lib/types/HostType.js +28 -7
- package/build/lib/types/NodeType.js +15 -1
- package/build/lib/types/PublishTimersType.js +15 -1
- package/build/lib/types/UniFiControllerConfigType.js +16 -0
- package/build/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.js +28 -7
- package/build/lib/types/hap-nodejs/HapCategories.js +64 -43
- package/build/lib/types/storage/SerializedHostType.js +15 -1
- package/build/lib/types/storage/StorageType.js +34 -10
- package/build/lib/unifi/ProtectDiscovery.js +80 -0
- package/build/lib/utils/AccessoryUtils.js +152 -110
- package/build/lib/utils/BridgeUtils.js +82 -39
- package/build/lib/utils/CharacteristicUtils.js +5 -49
- package/build/lib/utils/CharacteristicUtils2.js +5 -49
- package/build/lib/utils/CharacteristicUtilsBase.js +81 -0
- package/build/lib/utils/NodeStatusUtils.js +89 -40
- package/build/lib/utils/ServiceUtils.js +434 -375
- package/build/lib/utils/ServiceUtils2.js +514 -309
- package/build/lib/utils/index.js +10 -11
- package/build/nodes/bridge.html +184 -166
- package/build/nodes/bridge.js +27 -9
- package/build/nodes/locales/en-US/node-red-contrib-homekit-bridged.json +22 -0
- package/build/nodes/nrchkb.html +1601 -88
- package/build/nodes/nrchkb.js +66 -88
- package/build/nodes/plugin-instance.html +499 -0
- package/build/nodes/plugin-instance.js +46 -0
- package/build/nodes/service.html +517 -299
- package/build/nodes/service.js +5 -6
- package/build/nodes/service2.html +1683 -460
- package/build/nodes/service2.js +5 -8
- package/build/nodes/standalone.html +187 -174
- package/build/nodes/standalone.js +27 -9
- package/build/nodes/status.html +51 -18
- package/build/nodes/status.js +47 -40
- package/build/nodes/unifi-controller.html +92 -0
- package/build/nodes/unifi-controller.js +20 -0
- package/build/plugins/embedded/homebridge-camera-ffmpeg/index.js +479 -0
- package/build/plugins/embedded/homebridge-unifi-protect/index.js +521 -0
- package/build/plugins/embedded/index.js +58 -0
- package/build/plugins/nrchkb-homekit-plugins.js +17 -0
- package/build/plugins/registry/index.js +203 -0
- package/build/plugins/registry/types.js +16 -0
- package/build/scripts/migrate-homekit-service-flows.js +47 -0
- package/examples/demo/01 - ALL Demos single import.json +1885 -1885
- package/examples/demo/02 - Air Purifier.json +279 -279
- package/examples/demo/03 - Air Quality sensor with Battery.json +254 -254
- package/examples/demo/04 - Dimmable Bulb.json +172 -172
- package/examples/demo/05 - Color Bulb (HSV).json +195 -195
- package/examples/demo/06 - Fan (simple, 3 speeds).json +240 -240
- package/examples/demo/07 - Fan (with speed, oscillate, rotation direction).json +175 -175
- package/examples/demo/08 - CO2 detector.json +224 -224
- package/examples/demo/09 - CO (carbon monoxide) example.json +255 -255
- package/examples/demo/10 - Door window contact sensor.json +234 -234
- package/examples/demos (advanced)/01 - Television with inputs and speaker.json +541 -541
- package/examples/switch/01 - Plain Switch.json +178 -178
- package/package.json +95 -84
- package/build/lib/HAPHostNode.d.ts +0 -1
- package/build/lib/HAPServiceNode.d.ts +0 -1
- package/build/lib/HAPServiceNode2.d.ts +0 -1
- package/build/lib/NRCHKBError.d.ts +0 -3
- package/build/lib/Storage.d.ts +0 -30
- package/build/lib/api.d.ts +0 -1
- package/build/lib/camera/CameraControl.d.ts +0 -3
- package/build/lib/camera/CameraDelegate.d.ts +0 -38
- package/build/lib/camera/MP4StreamingServer.d.ts +0 -26
- package/build/lib/hap/HAPCharacteristic.d.ts +0 -9
- package/build/lib/hap/HAPService.d.ts +0 -6
- package/build/lib/hap/eve-app/EveCharacteristics.d.ts +0 -20
- package/build/lib/hap/eve-app/EveServices.d.ts +0 -5
- package/build/lib/types/AccessoryInformationType.d.ts +0 -11
- package/build/lib/types/CameraConfigType.d.ts +0 -24
- package/build/lib/types/CustomCharacteristicType.d.ts +0 -6
- package/build/lib/types/HAPHostConfigType.d.ts +0 -22
- package/build/lib/types/HAPHostNodeType.d.ts +0 -14
- package/build/lib/types/HAPService2ConfigType.d.ts +0 -6
- package/build/lib/types/HAPService2NodeType.d.ts +0 -7
- package/build/lib/types/HAPServiceConfigType.d.ts +0 -26
- package/build/lib/types/HAPServiceNodeType.d.ts +0 -38
- package/build/lib/types/HAPStatusConfigType.d.ts +0 -5
- package/build/lib/types/HAPStatusNodeType.d.ts +0 -12
- package/build/lib/types/HostType.d.ts +0 -5
- package/build/lib/types/NodeType.d.ts +0 -3
- package/build/lib/types/PublishTimersType.d.ts +0 -4
- package/build/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.d.ts +0 -5
- package/build/lib/types/hap-nodejs/HapCategories.d.ts +0 -41
- package/build/lib/types/storage/SerializedHostType.d.ts +0 -5
- package/build/lib/types/storage/StorageType.d.ts +0 -8
- package/build/lib/utils/AccessoryUtils.d.ts +0 -1
- package/build/lib/utils/BridgeUtils.d.ts +0 -1
- package/build/lib/utils/CharacteristicUtils.d.ts +0 -1
- package/build/lib/utils/CharacteristicUtils2.d.ts +0 -1
- package/build/lib/utils/NodeStatusUtils.d.ts +0 -17
- package/build/lib/utils/ServiceUtils.d.ts +0 -1
- package/build/lib/utils/ServiceUtils2.d.ts +0 -1
- package/build/lib/utils/index.d.ts +0 -1
- package/build/nodes/bridge.d.ts +0 -1
- package/build/nodes/nrchkb.d.ts +0 -1
- package/build/nodes/service.d.ts +0 -1
- package/build/nodes/service2.d.ts +0 -1
- package/build/nodes/standalone.d.ts +0 -1
- package/build/nodes/status.d.ts +0 -1
package/build/nodes/service.html
CHANGED
|
@@ -1,322 +1,330 @@
|
|
|
1
1
|
<!--suppress EqualityComparisonWithCoercionJS -->
|
|
2
2
|
<script data-template-name="homekit-service" type="text/x-red">
|
|
3
|
-
<div class="
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<div class="form-row">
|
|
12
|
-
<label for="node-input-serviceName">
|
|
13
|
-
<i class="fa fa-cog"></i>
|
|
14
|
-
Service</label>
|
|
15
|
-
<select id="node-input-serviceName" style="width: 70%">
|
|
16
|
-
<option value="">Choose...</option>
|
|
17
|
-
</select>
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
<div id="isParent">
|
|
21
|
-
<div class="form-row">
|
|
22
|
-
<label for="node-config-input-hostType"><i class="fa fa-tasks"></i> Host Type</label>
|
|
23
|
-
<select id="node-config-input-hostType" style="width: 70%">
|
|
24
|
-
<option value="0" selected="selected">Bridge</option>
|
|
25
|
-
<option value="1">Accessory</option>
|
|
26
|
-
</select>
|
|
27
|
-
</div>
|
|
28
|
-
<div id="isOnBridge">
|
|
29
|
-
<div id="isBridgeInSubflow" class="alert alert-warning" role="alert">
|
|
30
|
-
Read more <b><a href="#" id="bridgeInSubflowNotice">here</a></b> about adding Bridge in a Subflow.
|
|
31
|
-
</div>
|
|
32
|
-
<div class="form-row" style="height: 34px;">
|
|
33
|
-
<label for="node-input-bridge">
|
|
34
|
-
<i class="fa fa-rocket"></i>
|
|
35
|
-
Bridge</label>
|
|
36
|
-
<input id="node-input-bridge">
|
|
37
|
-
</div>
|
|
38
|
-
<div class="form-row">
|
|
39
|
-
<label for="node-input-manufacturer"><i class="fa fa-wrench"></i> Manufacturer</label>
|
|
40
|
-
<input type="text" id="node-input-manufacturer" placeholder="Manufacturer">
|
|
3
|
+
<div class="nrchkb-editor">
|
|
4
|
+
<div class="alert alert-warning nrchkb-warning" role="alert">
|
|
5
|
+
<strong>Deprecated:</strong> homekit-service will be disabled soon. Migrate this node to homekit-service2 to keep it working in NRCHKB 2.x.
|
|
6
|
+
<div style="margin-top: 8px;">
|
|
7
|
+
<button type="button" class="red-ui-button" id="nrchkb-migrate-service2">
|
|
8
|
+
<i class="fa fa-exchange"></i> Migrate this node
|
|
9
|
+
</button>
|
|
41
10
|
</div>
|
|
42
|
-
<div class="
|
|
43
|
-
|
|
44
|
-
|
|
11
|
+
<div id="nrchkb-migration-result" class="alert alert-info nrchkb-info" role="alert" style="display: none; margin-top: 8px;"></div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<details class="nrchkb-section" open>
|
|
15
|
+
<summary><i class="fa fa-sliders"></i> Essentials</summary>
|
|
16
|
+
<div class="nrchkb-section-body">
|
|
17
|
+
<div class="form-row">
|
|
18
|
+
<label for="node-config-input-isParent"><i class="fa fa-sitemap"></i> Service Hierarchy</label>
|
|
19
|
+
<select id="node-config-input-isParent">
|
|
20
|
+
<option value="true" selected="selected">Parent</option>
|
|
21
|
+
<option value="false">Linked</option>
|
|
22
|
+
</select>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="form-row">
|
|
26
|
+
<label for="node-input-serviceName">
|
|
27
|
+
<i class="fa fa-puzzle-piece"></i>
|
|
28
|
+
Service
|
|
29
|
+
</label>
|
|
30
|
+
<select id="node-input-serviceName">
|
|
31
|
+
<option value="">Choose...</option>
|
|
32
|
+
</select>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div class="form-row">
|
|
36
|
+
<label for="node-input-name">
|
|
37
|
+
<i class="fa fa-tag"></i>
|
|
38
|
+
Name
|
|
39
|
+
</label>
|
|
40
|
+
<input type="text" id="node-input-name" placeholder="Name">
|
|
41
|
+
</div>
|
|
45
42
|
</div>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
</details>
|
|
44
|
+
|
|
45
|
+
<details class="nrchkb-section" open>
|
|
46
|
+
<summary><i class="fa fa-map-marker"></i> Placement</summary>
|
|
47
|
+
<div class="nrchkb-section-body">
|
|
48
|
+
<div id="isParent">
|
|
49
|
+
<div class="form-row">
|
|
50
|
+
<label for="node-config-input-hostType"><i class="fa fa-server"></i> Host Type</label>
|
|
51
|
+
<select id="node-config-input-hostType">
|
|
52
|
+
<option value="0" selected="selected">Bridge</option>
|
|
53
|
+
<option value="1">Accessory</option>
|
|
54
|
+
</select>
|
|
55
|
+
</div>
|
|
56
|
+
<div id="isOnBridge">
|
|
57
|
+
<div id="isBridgeInSubflow" class="alert alert-warning nrchkb-warning" role="alert">
|
|
58
|
+
Read more <b><a href="#" id="bridgeInSubflowNotice">here</a></b> about adding Bridge in a Subflow.
|
|
59
|
+
</div>
|
|
60
|
+
<div class="form-row">
|
|
61
|
+
<label for="node-input-bridge">
|
|
62
|
+
<i class="fa fa-link"></i>
|
|
63
|
+
Bridge
|
|
64
|
+
</label>
|
|
65
|
+
<input id="node-input-bridge">
|
|
66
|
+
</div>
|
|
67
|
+
<details class="nrchkb-section">
|
|
68
|
+
<summary><i class="fa fa-id-card-o"></i> Accessory Metadata</summary>
|
|
69
|
+
<div class="nrchkb-section-body">
|
|
70
|
+
<div class="form-row">
|
|
71
|
+
<label for="node-input-manufacturer"><i class="fa fa-industry"></i> Manufacturer</label>
|
|
72
|
+
<input type="text" id="node-input-manufacturer" placeholder="Manufacturer">
|
|
73
|
+
</div>
|
|
74
|
+
<div class="form-row">
|
|
75
|
+
<label for="node-input-serialNo"><i class="fa fa-barcode"></i> Serial Number</label>
|
|
76
|
+
<input type="text" id="node-input-serialNo" placeholder="Serial Number">
|
|
77
|
+
</div>
|
|
78
|
+
<div class="form-row">
|
|
79
|
+
<label for="node-input-model"><i class="fa fa-cube"></i> Model</label>
|
|
80
|
+
<input type="text" id="node-input-model" placeholder="Model">
|
|
81
|
+
</div>
|
|
82
|
+
<div class="form-row">
|
|
83
|
+
<label for="node-input-firmwareRev"><i class="fa fa-microchip"></i> Firmware Revision</label>
|
|
84
|
+
<input type="text" id="node-input-firmwareRev" placeholder="Firmware Revision">
|
|
85
|
+
</div>
|
|
86
|
+
<div class="form-row">
|
|
87
|
+
<label for="node-input-hardwareRev"><i class="fa fa-hdd-o"></i> Hardware Revision</label>
|
|
88
|
+
<input type="text" id="node-input-hardwareRev" placeholder="Hardware Revision">
|
|
89
|
+
</div>
|
|
90
|
+
<div class="form-row">
|
|
91
|
+
<label for="node-input-softwareRev"><i class="fa fa-code"></i> Software Revision</label>
|
|
92
|
+
<input type="text" id="node-input-softwareRev" placeholder="Software Revision">
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</details>
|
|
96
|
+
</div>
|
|
97
|
+
<div id="isAccessory">
|
|
98
|
+
<div class="form-row">
|
|
99
|
+
<label for="node-input-accessoryId">
|
|
100
|
+
<i class="fa fa-home"></i>
|
|
101
|
+
Accessory
|
|
102
|
+
</label>
|
|
103
|
+
<input id="node-input-accessoryId">
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div id="isLinked" style="display: none;">
|
|
109
|
+
<div class="form-row">
|
|
110
|
+
<label for="node-input-parentService">
|
|
111
|
+
<i class="fa fa-level-up"></i>
|
|
112
|
+
Parent Service
|
|
113
|
+
</label>
|
|
114
|
+
<select id="node-input-parentService">
|
|
115
|
+
<option value="">Choose...</option>
|
|
116
|
+
</select>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
49
119
|
</div>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
120
|
+
</details>
|
|
121
|
+
|
|
122
|
+
<details class="nrchkb-section" open>
|
|
123
|
+
<summary><i class="fa fa-exchange"></i> Message Routing</summary>
|
|
124
|
+
<div class="nrchkb-section-body">
|
|
125
|
+
<div class="form-row">
|
|
126
|
+
<label for="node-input-topic"><i class="fa fa-comment-o"></i> Topic</label>
|
|
127
|
+
<input type="text" id="node-input-topic" placeholder="Topic">
|
|
128
|
+
</div>
|
|
129
|
+
<div class="form-row nrchkb-checkbox-row">
|
|
130
|
+
<label class="nrchkb-checkbox-label" for="node-input-filter">
|
|
131
|
+
<input type="checkbox" id="node-input-filter">
|
|
132
|
+
<span><i class="fa fa-filter"></i> Filter on Topic</span>
|
|
133
|
+
</label>
|
|
134
|
+
</div>
|
|
53
135
|
</div>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
136
|
+
</details>
|
|
137
|
+
|
|
138
|
+
<details id="camera-configuration" class="nrchkb-section" open style="display: none;">
|
|
139
|
+
<summary><i class="fa fa-video-camera"></i> Camera Configuration</summary>
|
|
140
|
+
<div class="nrchkb-section-body">
|
|
141
|
+
<div class="form-row">
|
|
142
|
+
<label for="node-input-cameraConfigVideoProcessor"><i class="fa fa-terminal"></i> Video Processor</label>
|
|
143
|
+
<input type="text" id="node-input-cameraConfigVideoProcessor" placeholder="ffmpeg">
|
|
144
|
+
</div>
|
|
145
|
+
<div class="form-row">
|
|
146
|
+
<label for="node-input-cameraConfigSource"><i class="fa fa-sign-in"></i> Source</label>
|
|
147
|
+
<input type="text" id="node-input-cameraConfigSource" placeholder="">
|
|
148
|
+
</div>
|
|
149
|
+
<div class="form-row">
|
|
150
|
+
<label for="node-input-cameraConfigStillImageSource"><i class="fa fa-picture-o"></i> Still Image Source</label>
|
|
151
|
+
<input type="text" id="node-input-cameraConfigStillImageSource" placeholder="">
|
|
152
|
+
</div>
|
|
153
|
+
<div class="form-row">
|
|
154
|
+
<label for="node-input-cameraConfigMaxStreams"><i class="fa fa-random"></i> Max Streams</label>
|
|
155
|
+
<input type="text" id="node-input-cameraConfigMaxStreams" placeholder="">
|
|
156
|
+
</div>
|
|
157
|
+
<div class="form-row">
|
|
158
|
+
<label for="node-input-cameraConfigMaxWidth"><i class="fa fa-arrows-h"></i> Max Width</label>
|
|
159
|
+
<input type="text" id="node-input-cameraConfigMaxWidth" placeholder="">
|
|
160
|
+
</div>
|
|
161
|
+
<div class="form-row">
|
|
162
|
+
<label for="node-input-cameraConfigMaxHeight"><i class="fa fa-arrows-v"></i> Max Height</label>
|
|
163
|
+
<input type="text" id="node-input-cameraConfigMaxHeight" placeholder="">
|
|
164
|
+
</div>
|
|
165
|
+
<div class="form-row">
|
|
166
|
+
<label for="node-input-cameraConfigMaxFPS"><i class="fa fa-clock-o"></i> Max FPS</label>
|
|
167
|
+
<input type="text" id="node-input-cameraConfigMaxFPS" placeholder="">
|
|
168
|
+
</div>
|
|
169
|
+
<div class="form-row">
|
|
170
|
+
<label for="node-input-cameraConfigMaxBitrate"><i class="fa fa-tachometer"></i> Max Bitrate</label>
|
|
171
|
+
<input type="text" id="node-input-cameraConfigMaxBitrate" placeholder="">
|
|
172
|
+
</div>
|
|
173
|
+
<div class="form-row">
|
|
174
|
+
<label for="node-input-cameraConfigVideoCodec"><i class="fa fa-film"></i> Video Codec</label>
|
|
175
|
+
<input type="text" id="node-input-cameraConfigVideoCodec" placeholder="">
|
|
176
|
+
</div>
|
|
177
|
+
<div class="form-row">
|
|
178
|
+
<label for="node-input-cameraConfigAudioCodec"><i class="fa fa-volume-up"></i> Audio Codec</label>
|
|
179
|
+
<input type="text" id="node-input-cameraConfigAudioCodec" placeholder="">
|
|
180
|
+
</div>
|
|
181
|
+
<div class="form-row nrchkb-checkbox-row">
|
|
182
|
+
<label class="nrchkb-checkbox-label" for="node-input-cameraConfigAudio">
|
|
183
|
+
<input type="checkbox" id="node-input-cameraConfigAudio">
|
|
184
|
+
<span><i class="fa fa-headphones"></i> Audio</span>
|
|
185
|
+
</label>
|
|
186
|
+
</div>
|
|
187
|
+
<div class="form-row">
|
|
188
|
+
<label for="node-input-cameraConfigPacketSize"><i class="fa fa-archive"></i> Packet Size</label>
|
|
189
|
+
<input type="text" id="node-input-cameraConfigPacketSize" placeholder="">
|
|
190
|
+
</div>
|
|
191
|
+
<div class="form-row nrchkb-checkbox-row">
|
|
192
|
+
<label class="nrchkb-checkbox-label" for="node-input-cameraConfigVerticalFlip">
|
|
193
|
+
<input type="checkbox" id="node-input-cameraConfigVerticalFlip">
|
|
194
|
+
<span><i class="fa fa-arrows-v"></i> Vertical Flip</span>
|
|
195
|
+
</label>
|
|
196
|
+
</div>
|
|
197
|
+
<div class="form-row nrchkb-checkbox-row">
|
|
198
|
+
<label class="nrchkb-checkbox-label" for="node-input-cameraConfigHorizontalFlip">
|
|
199
|
+
<input type="checkbox" id="node-input-cameraConfigHorizontalFlip">
|
|
200
|
+
<span><i class="fa fa-arrows-h"></i> Horizontal Flip</span>
|
|
201
|
+
</label>
|
|
202
|
+
</div>
|
|
203
|
+
<div class="form-row">
|
|
204
|
+
<label for="node-input-cameraConfigMapVideo"><i class="fa fa-film"></i> Map Video</label>
|
|
205
|
+
<input type="text" id="node-input-cameraConfigMapVideo" placeholder="">
|
|
206
|
+
</div>
|
|
207
|
+
<div class="form-row">
|
|
208
|
+
<label for="node-input-cameraConfigMapAudio"><i class="fa fa-volume-up"></i> Map Audio</label>
|
|
209
|
+
<input type="text" id="node-input-cameraConfigMapAudio" placeholder="">
|
|
210
|
+
</div>
|
|
211
|
+
<div class="form-row">
|
|
212
|
+
<label for="node-input-cameraConfigVideoFilter"><i class="fa fa-filter"></i> Video Filter</label>
|
|
213
|
+
<input type="text" id="node-input-cameraConfigVideoFilter" placeholder="">
|
|
214
|
+
</div>
|
|
215
|
+
<div class="form-row">
|
|
216
|
+
<label for="node-input-cameraConfigAdditionalCommandLine"><i class="fa fa-terminal"></i> Additional Command Line</label>
|
|
217
|
+
<input type="text" id="node-input-cameraConfigAdditionalCommandLine" placeholder="">
|
|
218
|
+
</div>
|
|
219
|
+
<div class="form-row nrchkb-checkbox-row">
|
|
220
|
+
<label class="nrchkb-checkbox-label" for="node-input-cameraConfigDebug">
|
|
221
|
+
<input type="checkbox" id="node-input-cameraConfigDebug">
|
|
222
|
+
<span><i class="fa fa-bug"></i> Debug</span>
|
|
223
|
+
</label>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<div class="form-row">
|
|
227
|
+
<label for="node-input-cameraConfigSnapshotOutput"><i class="fa fa-camera"></i> Snapshot output</label>
|
|
228
|
+
<select id="node-input-cameraConfigSnapshotOutput">
|
|
229
|
+
<option value="disabled" selected="selected">Disabled</option>
|
|
230
|
+
<option value="path">Path</option>
|
|
231
|
+
<option value="content">Content</option>
|
|
232
|
+
</select>
|
|
233
|
+
</div>
|
|
234
|
+
|
|
235
|
+
<div class="form-row">
|
|
236
|
+
<label for="node-input-cameraConfigInterfaceName"><i class="fa fa-sitemap"></i> Interface Name</label>
|
|
237
|
+
<input type="text" id="node-input-cameraConfigInterfaceName" placeholder="">
|
|
238
|
+
</div>
|
|
57
239
|
</div>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
240
|
+
</details>
|
|
241
|
+
|
|
242
|
+
<details id="adaptive-lightning-configuration" class="nrchkb-section" open style="display: none;">
|
|
243
|
+
<summary><i class="fa fa-sun-o"></i> Adaptive Lighting Configuration</summary>
|
|
244
|
+
<div class="nrchkb-section-body">
|
|
245
|
+
<div class="form-row nrchkb-checkbox-row">
|
|
246
|
+
<label class="nrchkb-checkbox-label" for="node-input-adaptiveLightingOptionsEnable">
|
|
247
|
+
<input type="checkbox" id="node-input-adaptiveLightingOptionsEnable">
|
|
248
|
+
<span><i class="fa fa-toggle-on"></i> Enable</span>
|
|
249
|
+
</label>
|
|
250
|
+
</div>
|
|
251
|
+
<div class="form-row">
|
|
252
|
+
<label for="node-input-adaptiveLightingOptionsMode"><i class="fa fa-magic"></i> Mode</label>
|
|
253
|
+
<select id="node-input-adaptiveLightingOptionsMode">
|
|
254
|
+
<option value="" selected hidden disabled>AUTOMATIC</option>
|
|
255
|
+
<option value="1">AUTOMATIC</option>
|
|
256
|
+
<option value="2">MANUAL</option>
|
|
257
|
+
</select>
|
|
258
|
+
</div>
|
|
259
|
+
<div class="form-row">
|
|
260
|
+
<label for="node-input-adaptiveLightingOptionsCustomTemperatureAdjustment"><i class="fa fa-thermometer-half"></i> Custom Temperature Adjustment</label>
|
|
261
|
+
<input type="number" id="node-input-adaptiveLightingOptionsCustomTemperatureAdjustment" placeholder="0">
|
|
262
|
+
</div>
|
|
61
263
|
</div>
|
|
62
|
-
</
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
264
|
+
</details>
|
|
265
|
+
|
|
266
|
+
<details class="nrchkb-section">
|
|
267
|
+
<summary><i class="fa fa-sliders"></i> Advanced Behavior</summary>
|
|
268
|
+
<div class="nrchkb-section-body">
|
|
269
|
+
<div class="form-row">
|
|
270
|
+
<label for="node-input-characteristicProperties"><i class="fa fa-list-alt"></i> Characteristic Properties</label>
|
|
271
|
+
<input type="text" id="node-input-characteristicProperties">
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
<div class="form-row nrchkb-checkbox-row">
|
|
275
|
+
<label class="nrchkb-checkbox-label" for="node-input-waitForSetupMsg">
|
|
276
|
+
<input type="checkbox" id="node-input-waitForSetupMsg">
|
|
277
|
+
<span><i class="fa fa-hourglass-half"></i> Wait for Setup message</span>
|
|
278
|
+
</label>
|
|
279
|
+
</div>
|
|
69
280
|
</div>
|
|
70
|
-
</
|
|
281
|
+
</details>
|
|
71
282
|
</div>
|
|
283
|
+
</script>
|
|
72
284
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<label for="node-input-parentService">
|
|
76
|
-
<i class="fa fa-cog"></i>
|
|
77
|
-
Parent Service</label>
|
|
78
|
-
<select id="node-input-parentService">
|
|
79
|
-
<option value="">Choose...</option>
|
|
80
|
-
</select>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
285
|
+
<script data-help-name="homekit-service" type="text/markdown">
|
|
286
|
+
# HomeKit Service
|
|
83
287
|
|
|
84
|
-
|
|
85
|
-
<label for="node-input-topic"><i class="fa fa-tasks"></i> Topic</label>
|
|
86
|
-
<input type="text" id="node-input-topic" placeholder="Topic">
|
|
87
|
-
</div>
|
|
88
|
-
<div class="form-row">
|
|
89
|
-
<label class="visibleDesktop"> </label>
|
|
90
|
-
<div style="display: inline;">
|
|
91
|
-
<input type="checkbox" id="node-input-filter" style="display: inline-block; width: auto; vertical-align: top;">
|
|
92
|
-
<label for="node-input-filter" style="width: 120px;"> <i class="fa fa-filter"></i> Filter on Topic</label>
|
|
93
|
-
</div>
|
|
94
|
-
</div>
|
|
288
|
+
Represents one legacy HomeKit service. It receives Node-RED messages to update HomeKit characteristics and emits messages when HomeKit changes those characteristics.
|
|
95
289
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<i class="fa fa-tag"></i>
|
|
99
|
-
Name</label>
|
|
100
|
-
<input type="text" id="node-input-name" placeholder="Name">
|
|
101
|
-
</div>
|
|
290
|
+
> [!WARNING]
|
|
291
|
+
> `homekit-service` is deprecated and kept for existing flows. Use `homekit-service2` for new work.
|
|
102
292
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<div class="form-row">
|
|
106
|
-
<label for="node-input-cameraConfigVideoProcessor"><i class="fa fa-cog"></i> Video Processor</label>
|
|
107
|
-
<input type="text" id="node-input-cameraConfigVideoProcessor" placeholder="ffmpeg">
|
|
108
|
-
</div>
|
|
109
|
-
<div class="form-row">
|
|
110
|
-
<label for="node-input-cameraConfigSource"><i class="fa fa-tint"></i> Source</label>
|
|
111
|
-
<input type="text" id="node-input-cameraConfigSource" placeholder="">
|
|
112
|
-
</div>
|
|
113
|
-
<div class="form-row">
|
|
114
|
-
<label for="node-input-cameraConfigStillImageSource"><i class="fa fa-picture-o"></i> Still Image Source</label>
|
|
115
|
-
<input type="text" id="node-input-cameraConfigStillImageSource" placeholder="">
|
|
116
|
-
</div>
|
|
117
|
-
<div class="form-row">
|
|
118
|
-
<label for="node-input-cameraConfigMaxStreams"><i class="fa fa-tint"></i> Max Streams</label>
|
|
119
|
-
<input type="text" id="node-input-cameraConfigMaxStreams" placeholder="">
|
|
120
|
-
</div>
|
|
121
|
-
<div class="form-row">
|
|
122
|
-
<label for="node-input-cameraConfigMaxWidth"><i class="fa fa-text-width"></i> Max Width</label>
|
|
123
|
-
<input type="text" id="node-input-cameraConfigMaxWidth" placeholder="">
|
|
124
|
-
</div>
|
|
125
|
-
<div class="form-row">
|
|
126
|
-
<label for="node-input-cameraConfigMaxHeight"><i class="fa fa-text-height"></i> Max Height</label>
|
|
127
|
-
<input type="text" id="node-input-cameraConfigMaxHeight" placeholder="">
|
|
128
|
-
</div>
|
|
129
|
-
<div class="form-row">
|
|
130
|
-
<label for="node-input-cameraConfigMaxFPS"><i class="fa fa-clock-o"></i> Max FPS</label>
|
|
131
|
-
<input type="text" id="node-input-cameraConfigMaxFPS" placeholder="">
|
|
132
|
-
</div>
|
|
133
|
-
<div class="form-row">
|
|
134
|
-
<label for="node-input-cameraConfigMaxBitrate"><i class="fa fa-clock-o"></i> Max Bitrate</label>
|
|
135
|
-
<input type="text" id="node-input-cameraConfigMaxBitrate" placeholder="">
|
|
136
|
-
</div>
|
|
137
|
-
<div class="form-row">
|
|
138
|
-
<label for="node-input-cameraConfigVideoCodec"><i class="fa fa-video-camera"></i> Video Codec</label>
|
|
139
|
-
<input type="text" id="node-input-cameraConfigVideoCodec" placeholder="">
|
|
140
|
-
</div>
|
|
141
|
-
<div class="form-row">
|
|
142
|
-
<label for="node-input-cameraConfigAudioCodec"><i class="fa fa-video-camera"></i> Audio Codec</label>
|
|
143
|
-
<input type="text" id="node-input-cameraConfigAudioCodec" placeholder="">
|
|
144
|
-
</div>
|
|
145
|
-
<div class="form-row">
|
|
146
|
-
<label for="node-input-cameraConfigAudio"><i class="fa fa-headphones"></i> Audio</label>
|
|
147
|
-
<input type="checkbox" id="node-input-cameraConfigAudio">
|
|
148
|
-
</div>
|
|
149
|
-
<div class="form-row">
|
|
150
|
-
<label for="node-input-cameraConfigPacketSize"><i class="fa fa-get-pocket"></i> Packet Size</label>
|
|
151
|
-
<input type="text" id="node-input-cameraConfigPacketSize" placeholder="">
|
|
152
|
-
</div>
|
|
153
|
-
<div class="form-row">
|
|
154
|
-
<label for="node-input-cameraConfigVerticalFlip"><i class="fa fa-undo"></i> Vertical Flip</label>
|
|
155
|
-
<input type="checkbox" id="node-input-cameraConfigVerticalFlip">
|
|
156
|
-
</div>
|
|
157
|
-
<div class="form-row">
|
|
158
|
-
<label for="node-input-cameraConfigHorizontalFlip"><i class="fa fa-undo"></i> Horizontal Flip</label>
|
|
159
|
-
<input type="checkbox" id="node-input-cameraConfigHorizontalFlip">
|
|
160
|
-
</div>
|
|
161
|
-
<div class="form-row">
|
|
162
|
-
<label for="node-input-cameraConfigMapVideo"><i class="fa fa-video-camera"></i> Map Video</label>
|
|
163
|
-
<input type="text" id="node-input-cameraConfigMapVideo" placeholder="">
|
|
164
|
-
</div>
|
|
165
|
-
<div class="form-row">
|
|
166
|
-
<label for="node-input-cameraConfigMapAudio"><i class="fa fa-headphones"></i> Map Audio</label>
|
|
167
|
-
<input type="text" id="node-input-cameraConfigMapAudio" placeholder="">
|
|
168
|
-
</div>
|
|
169
|
-
<div class="form-row">
|
|
170
|
-
<label for="node-input-cameraConfigVideoFilter"><i class="fa fa-filter"></i> Video Filter</label>
|
|
171
|
-
<input type="text" id="node-input-cameraConfigVideoFilter" placeholder="">
|
|
172
|
-
</div>
|
|
173
|
-
<div class="form-row">
|
|
174
|
-
<label for="node-input-cameraConfigAdditionalCommandLine"><i class="fa fa-plus"></i> Additional Command Line</label>
|
|
175
|
-
<input type="text" id="node-input-cameraConfigAdditionalCommandLine" placeholder="">
|
|
176
|
-
</div>
|
|
177
|
-
<div class="form-row">
|
|
178
|
-
<label for="node-input-cameraConfigDebug"><i class="fa fa-bug"></i> Debug</label>
|
|
179
|
-
<input type="checkbox" id="node-input-cameraConfigDebug">
|
|
180
|
-
</div>
|
|
293
|
+
> [!IMPORTANT]
|
|
294
|
+
> The migration button prepares an editor-side change. Click **Done** and then **Deploy** to commit the migration.
|
|
181
295
|
|
|
182
|
-
|
|
183
|
-
<label for="node-input-cameraConfigSnapshotOutput"><i class="fa fa-picture-o"></i> Snapshot output</label>
|
|
184
|
-
<select id="node-input-cameraConfigSnapshotOutput">
|
|
185
|
-
<option value="disabled" selected="selected">Disabled</option>
|
|
186
|
-
<option value="path">Path</option>
|
|
187
|
-
<option value="content">Content</option>
|
|
188
|
-
</select>
|
|
189
|
-
</div>
|
|
296
|
+
## Message Format
|
|
190
297
|
|
|
191
|
-
|
|
192
|
-
<label for="node-input-cameraConfigInterfaceName"><i class="fa fa-smile-o"></i> Interface Name</label>
|
|
193
|
-
<input type="text" id="node-input-cameraConfigInterfaceName" placeholder="">
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
298
|
+
Send a `msg.payload` object whose keys are HomeKit characteristic names.
|
|
196
299
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
<div class="form-row">
|
|
204
|
-
<label for="node-input-adaptiveLightingOptionsMode"><i class="fa fa-hand-o-up"></i> Mode</label>
|
|
205
|
-
<select id="node-input-adaptiveLightingOptionsMode">
|
|
206
|
-
<option value="" selected hidden disabled>AUTOMATIC</option>
|
|
207
|
-
<option value="1">AUTOMATIC</option>
|
|
208
|
-
<option value="2">MANUAL</option>
|
|
209
|
-
</select>
|
|
210
|
-
</div>
|
|
211
|
-
<div class="form-row">
|
|
212
|
-
<label for="node-input-adaptiveLightingOptionsCustomTemperatureAdjustment"><i class="fa fa-thermometer-quarter"></i> Custom Temperature Adjustment</label>
|
|
213
|
-
<input type="number" id="node-input-adaptiveLightingOptionsCustomTemperatureAdjustment" placeholder="0">
|
|
214
|
-
</div>
|
|
215
|
-
</div>
|
|
300
|
+
```json
|
|
301
|
+
{
|
|
302
|
+
"On": true,
|
|
303
|
+
"OutletInUse": true
|
|
304
|
+
}
|
|
305
|
+
```
|
|
216
306
|
|
|
217
|
-
|
|
218
|
-
<label for="node-input-characteristicProperties"><i class="fa fa-wrench"></i> Characteristic Properties</label>
|
|
219
|
-
<input type="text" id="node-input-characteristicProperties" style="width: 70%">
|
|
220
|
-
</div>
|
|
307
|
+
## Placement
|
|
221
308
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
</script>
|
|
309
|
+
- **Host Type**: Publish a parent service behind a shared **Bridge** or behind a standalone **Accessory**.
|
|
310
|
+
- **Bridge**: HomeKit bridge configuration that hosts this service.
|
|
311
|
+
- **Accessory**: Standalone accessory configuration that hosts this service.
|
|
312
|
+
- **Parent Service**: Parent service used by linked services.
|
|
227
313
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
<ul>
|
|
233
|
-
<li><strong>Service Hierarchy</strong>: Choose if this Service is Parent or Linked</li>
|
|
234
|
-
<ul>
|
|
235
|
-
<li>Parent has <strong>Bridge</strong> and <strong>Accessory Category</strong>: On what Bridge to host this Service and its Accessory and what kind of category is this Accessory, default <em>OTHER</em></li>
|
|
236
|
-
<li>Linked has <strong>Parent Service</strong>: On what Parent Service link this Service.</li>
|
|
237
|
-
</ul>
|
|
238
|
-
<li><strong>Topic</strong>: An optional property that can be configured in the node or, if left blank, can be set by <code>msg.topic</code>. If <em>Filter on Topic</em> is selected <code>msg.topic</code> of incoming messages must match the configured
|
|
239
|
-
value for the message to be accepted. If <em>Filter on Topic</em> is selected and no <em>Topic</em> is set on the node, then <code>msg.topic</code> must match the nodes <em>Name</em>
|
|
240
|
-
</li>
|
|
241
|
-
<li><strong>Manufacturer, Model, Serial Number</strong>: Can be anything you want.</li>
|
|
242
|
-
<li><strong>Firmware Revision</strong>: Should be a version number string in the form of <em>MAJOR.MINOR.REVISION</em> e.g. <em>1.2.0</em>. Other types of strings are ignored and won't be displayed.</li>
|
|
243
|
-
<li><strong>Hardware Revision</strong>: Should be a version number string in the form of <em>MAJOR.MINOR.REVISION</em> e.g. <em>1.2.0</em>. Other types of strings are ignored and won't be displayed.</li>
|
|
244
|
-
<li><strong>Software Revision</strong>: Should be a version number string in the form of <em>MAJOR.MINOR.REVISION</em> e.g. <em>1.2.0</em>. Other types of strings are ignored and won't be displayed.</li>
|
|
245
|
-
<li><strong>Service</strong>: Choose the type of Service from the list.</li>
|
|
246
|
-
<li><strong>Name</strong>: <em>optional</em></li>
|
|
247
|
-
<li><strong>Camera Configuration</strong>: Additional configuration for CameraControl service.</li>
|
|
248
|
-
<ul>
|
|
249
|
-
<li><strong>Video Processor</strong>: Video processor used for Camera. Default is <em>ffmpeg</em>.</li>
|
|
250
|
-
<li><strong>Source</strong>: Camera source used for video processor. Example for ffmpeg <em>-re -i rtsp://192.168.0.227:8554/unicast</em></li>
|
|
251
|
-
<li><strong>Still Image Source</strong>: Camera snapshot source used for video processor. Example for ffmpeg <em>-i http://faster_still_image_grab_url/this_is_optional.jpg</em></li>
|
|
252
|
-
<li><strong>Max Streams</strong>: Maximum number of streams that will be generated for this camera, default <em>2</em>.</li>
|
|
253
|
-
<li><strong>Max Width</strong>: Maximum width reported to HomeKit, default <em>1280</em>.</li>
|
|
254
|
-
<li><strong>Max Height</strong>: Maximum height reported to HomeKit, default <em>720</em>.</li>
|
|
255
|
-
<li><strong>Max FPS</strong>: Maximum frame rate of the stream, default <em>10</em>.</li>
|
|
256
|
-
<li><strong>Max Bitrate</strong>: Maximum bit rate of the stream in kbit/s, default <em>300</em>.</li>
|
|
257
|
-
<li><strong>Video Codec</strong>: If you're running on a RPi with the omx version of ffmpeg installed, you can change to the hardware accelerated video codec with this option, default <em>libx264</em>.</li>
|
|
258
|
-
<li><strong>Audio Codec</strong>: If you're running on a RPi with the omx version of ffmpeg installed, you can change to the hardware accelerated audio codec with this option, default <em>libfdk_aac</em>.</li>
|
|
259
|
-
<li><strong>Audio</strong>: Can be set to true to enable audio streaming from camera. To use audio ffmpeg must be compiled with --enable-libfdk-aac, default <em>false</em>.</li>
|
|
260
|
-
<li><strong>Packet Size</strong>: If audio or video is choppy try a smaller value, set to a multiple of 188, default <em>1316</em>.</li>
|
|
261
|
-
<li><strong>Vertical Flip</strong>: Flips the stream vertically, default <em>false</em>.</li>
|
|
262
|
-
<li><strong>Horizontal Flip</strong>: Flips the stream horizontally, default <em>false</em>.</li>
|
|
263
|
-
<li><strong>Map Video</strong>: Select the stream used for video, default <em>0:0</em>.</li>
|
|
264
|
-
<li><strong>Map Audio</strong>: Select the stream used for audio, default <em>0:1</em>.</li>
|
|
265
|
-
<li><strong>Video Filter</strong>: Allows a custom video filter to be passed to FFmpeg via -vf, defaults to <em>scale=1280:720</em> but is optional.</li>
|
|
266
|
-
<li><strong>Additional Command Line</strong>: Allows additional of extra command line options to FFmpeg, default <em>-tune zerolatency</em> but is optional.</li>
|
|
267
|
-
<li><strong>Debug</strong>: Show the output of ffmpeg in the log, default <em>false</em>.</li>
|
|
268
|
-
<li><strong>Snapshot output</strong>: Choose how to output camera snapshot</li>
|
|
269
|
-
<ul>
|
|
270
|
-
<li><strong>Disabled</strong>: there will be no output</li>
|
|
271
|
-
<li><strong>Path</strong>: file will be saved and path will be send to output, <em>msg.payload.cameraSnapshot</em> contains path value stored as a string.</li>
|
|
272
|
-
<li><strong>Content</strong>: file content will be send to output, <em>msg.payload.cameraSnapshot</em> contains Buffer object {"type":"Buffer","data":[]}.</li>
|
|
273
|
-
</ul>
|
|
274
|
-
<li><strong>Interface Name</strong>: Selects the IP address of a given network interface.</li>
|
|
275
|
-
</ul>
|
|
276
|
-
<li><strong>Characteristic Properties</strong>: Customize the properties of characteristics.</li>
|
|
277
|
-
<li><strong>Wait for Setup message</strong>: If yes then Service node will wait for a input message with appropriate payload.</li>
|
|
278
|
-
</ul>
|
|
279
|
-
<h2 id="toc_6">Input Messages</h2>
|
|
280
|
-
<p>Input messages can be used to update any <em>Characteristic</em> that the selected <em>Service</em> provides. Simply pass the values-to-update as <code>msg.payload</code> object. </p>
|
|
281
|
-
<p><strong>Example</strong>: to signal that an <em>Outlet</em> is turned on and in use, send the following payload</p>
|
|
282
|
-
<div>
|
|
283
|
-
<pre><code class="language-javascript">
|
|
284
|
-
{
|
|
285
|
-
"On": 1,
|
|
286
|
-
"OutletInUse": 1
|
|
287
|
-
}
|
|
288
|
-
</code></pre>
|
|
289
|
-
</div>
|
|
290
|
-
<p><strong>Hint</strong>: to find out what <em>Characteristics</em> you can address, just send <code>{"foo":"bar"}</code> and watch the debug tab ;)</p>
|
|
291
|
-
<h2 id="toc_7">Output Messages</h2>
|
|
292
|
-
<p>Output messages are in the same format as input messages. They are emitted from the node when it receives <em>Characteristics</em> updates from a paired iOS device.</p>
|
|
293
|
-
<h2 id="toc_8">Characteristic Properties</h2>
|
|
294
|
-
<p><strong>Example</strong>: allow temperatures below 0°C</p>
|
|
295
|
-
<div>
|
|
296
|
-
<pre><code class="language-json">
|
|
297
|
-
{
|
|
298
|
-
"CurrentTemperature": {
|
|
299
|
-
"minValue": -100
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
</code></pre>
|
|
303
|
-
<p><strong>Example</strong>: limit fan speed multiples of 25%</p>
|
|
304
|
-
<div>
|
|
305
|
-
<pre><code class="language-json">
|
|
306
|
-
{
|
|
307
|
-
"RotationSpeed": {
|
|
308
|
-
"minStep": 25
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
</code></pre>
|
|
312
|
-
</div>
|
|
314
|
+
## Advanced Behavior
|
|
315
|
+
|
|
316
|
+
> [!CAUTION]
|
|
317
|
+
> **Wait for Setup message** delays service setup until the node receives the required setup payload. The service will not be published until that message arrives.
|
|
313
318
|
|
|
319
|
+
- **Characteristic Properties**: JSON object that overrides HAP characteristic metadata such as `minValue`, `maxValue`, or `minStep`.
|
|
320
|
+
- **Camera Configuration**: Shown for camera services and describes FFmpeg streaming and snapshot settings.
|
|
314
321
|
</script>
|
|
315
322
|
|
|
316
323
|
<script type="text/javascript">
|
|
317
324
|
RED.nodes.registerType('homekit-service', {
|
|
318
325
|
category: "Apple HomeKit",
|
|
319
326
|
paletteLabel: 'service',
|
|
327
|
+
nrchkbPreventNewInstances: true,
|
|
320
328
|
defaults: {
|
|
321
329
|
isParent: {
|
|
322
330
|
value: 'false',
|
|
@@ -481,8 +489,7 @@
|
|
|
481
489
|
|
|
482
490
|
try {
|
|
483
491
|
JSON.parse(value)
|
|
484
|
-
} catch (
|
|
485
|
-
console.log(e, value)
|
|
492
|
+
} catch (_) {
|
|
486
493
|
return false
|
|
487
494
|
}
|
|
488
495
|
|
|
@@ -530,6 +537,9 @@
|
|
|
530
537
|
labelStyle: function () {
|
|
531
538
|
return this.name ? 'node_label_italic' : ''
|
|
532
539
|
},
|
|
540
|
+
onadd: function () {
|
|
541
|
+
applyDefaultNodeDocumentation(this, 'homekit-service')
|
|
542
|
+
},
|
|
533
543
|
oneditprepare: function () {
|
|
534
544
|
let node = this
|
|
535
545
|
let isParentToggle = $('#node-config-input-isParent')
|
|
@@ -540,6 +550,151 @@
|
|
|
540
550
|
isParentToggle.val('true')
|
|
541
551
|
}
|
|
542
552
|
|
|
553
|
+
const toSerializableValue = function (value) {
|
|
554
|
+
if (value === undefined || value === null) {
|
|
555
|
+
return value
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (typeof value !== 'object') {
|
|
559
|
+
return value
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
try {
|
|
563
|
+
return JSON.parse(JSON.stringify(value))
|
|
564
|
+
} catch (_) {
|
|
565
|
+
return undefined
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
const readCurrentNodeConfig = function () {
|
|
570
|
+
const config = {
|
|
571
|
+
id: node.id,
|
|
572
|
+
type: node.type,
|
|
573
|
+
z: node.z,
|
|
574
|
+
g: node.g,
|
|
575
|
+
wires: toSerializableValue(node.wires),
|
|
576
|
+
outputs: node.outputs
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
Object.keys((node._def && node._def.defaults) || {}).forEach(function (key) {
|
|
580
|
+
const value = toSerializableValue(node[key])
|
|
581
|
+
|
|
582
|
+
if (value !== undefined) {
|
|
583
|
+
config[key] = value
|
|
584
|
+
}
|
|
585
|
+
})
|
|
586
|
+
|
|
587
|
+
return $.extend(config, {
|
|
588
|
+
name: $('#node-input-name').val(),
|
|
589
|
+
serviceName:
|
|
590
|
+
$('#node-input-serviceName').val() ||
|
|
591
|
+
$('#node-input-serviceName option:selected').attr('value') ||
|
|
592
|
+
node.serviceName,
|
|
593
|
+
manufacturer: $('#node-input-manufacturer').val(),
|
|
594
|
+
model: $('#node-input-model').val(),
|
|
595
|
+
serialNo: $('#node-input-serialNo').val(),
|
|
596
|
+
firmwareRev: $('#node-input-firmwareRev').val(),
|
|
597
|
+
cameraConfigVideoProcessor: $('#node-input-cameraConfigVideoProcessor').val(),
|
|
598
|
+
cameraConfigSource: $('#node-input-cameraConfigSource').val(),
|
|
599
|
+
cameraConfigStillImageSource: $('#node-input-cameraConfigStillImageSource').val(),
|
|
600
|
+
cameraConfigMaxStreams: $('#node-input-cameraConfigMaxStreams').val(),
|
|
601
|
+
cameraConfigMaxWidth: $('#node-input-cameraConfigMaxWidth').val(),
|
|
602
|
+
cameraConfigMaxHeight: $('#node-input-cameraConfigMaxHeight').val(),
|
|
603
|
+
cameraConfigMaxFPS: $('#node-input-cameraConfigMaxFPS').val(),
|
|
604
|
+
cameraConfigMaxBitrate: $('#node-input-cameraConfigMaxBitrate').val(),
|
|
605
|
+
cameraConfigVideoCodec: $('#node-input-cameraConfigVideoCodec').val(),
|
|
606
|
+
cameraConfigAudio: $('#node-input-cameraConfigAudio').is(':checked'),
|
|
607
|
+
cameraConfigPacketSize: $('#node-input-cameraConfigPacketSize').val(),
|
|
608
|
+
cameraConfigMapVideo: $('#node-input-cameraConfigMapVideo').val(),
|
|
609
|
+
cameraConfigMapAudio: $('#node-input-cameraConfigMapAudio').val(),
|
|
610
|
+
cameraConfigVideoFilter: $('#node-input-cameraConfigVideoFilter').val(),
|
|
611
|
+
cameraConfigAdditionalCommandLine: $('#node-input-cameraConfigAdditionalCommandLine').val(),
|
|
612
|
+
cameraConfigDebug: $('#node-input-cameraConfigDebug').is(':checked')
|
|
613
|
+
})
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const showMigrationPrepared = function (result) {
|
|
617
|
+
if (
|
|
618
|
+
result.node.serviceName &&
|
|
619
|
+
$('#node-input-serviceName option[value="' + result.node.serviceName + '"]').length === 0
|
|
620
|
+
) {
|
|
621
|
+
$('#node-input-serviceName').append(
|
|
622
|
+
$('<option></option>')
|
|
623
|
+
.val(result.node.serviceName)
|
|
624
|
+
.text(result.node.serviceName)
|
|
625
|
+
)
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
if (result.node.serviceName) {
|
|
629
|
+
$('#node-input-serviceName')
|
|
630
|
+
.val(result.node.serviceName)
|
|
631
|
+
.trigger('change')
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
$('#nrchkb-migration-result')
|
|
635
|
+
.html(
|
|
636
|
+
'<strong>Migration prepared.</strong> Service is now <code>' +
|
|
637
|
+
$('<div>').text(result.node.serviceName || '').html() +
|
|
638
|
+
'</code>. Click <strong>Done</strong> to commit this editor change, then <strong>Deploy</strong>.'
|
|
639
|
+
)
|
|
640
|
+
.show()
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
$('#nrchkb-migrate-service2').on('click', function () {
|
|
644
|
+
$('<div>')
|
|
645
|
+
.html('<p>This will prepare this node for conversion to <strong>homekit-service2</strong> in legacy output mode and preserve existing wires.</p><p>CameraControl nodes will become the new <strong>Camera</strong> service with the embedded Homebridge Camera FFmpeg plugin.</p><p>After migration is prepared, click <strong>Done</strong> in this node editor to commit the change, then <strong>Deploy</strong>.</p>')
|
|
646
|
+
.dialog({
|
|
647
|
+
modal: true,
|
|
648
|
+
resizable: false,
|
|
649
|
+
width: 420,
|
|
650
|
+
title: 'Migrate Service Node',
|
|
651
|
+
buttons: {
|
|
652
|
+
Migrate: function () {
|
|
653
|
+
const dialog = this
|
|
654
|
+
|
|
655
|
+
$.ajax({
|
|
656
|
+
url: 'nrchkb/migration/node',
|
|
657
|
+
type: 'POST',
|
|
658
|
+
contentType: 'application/json',
|
|
659
|
+
data: JSON.stringify(readCurrentNodeConfig())
|
|
660
|
+
}).done(function (result) {
|
|
661
|
+
if (!result || !result.migrated || !result.node) {
|
|
662
|
+
RED.notify('This node could not be migrated.', 'warning')
|
|
663
|
+
return
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
node._nrchkbPendingMigration = result.node
|
|
667
|
+
showMigrationPrepared(result)
|
|
668
|
+
|
|
669
|
+
RED.nodes.dirty(true)
|
|
670
|
+
|
|
671
|
+
if (RED.view && RED.view.redraw) {
|
|
672
|
+
RED.view.redraw(true)
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
RED.notify(
|
|
676
|
+
result.cameraMigrated
|
|
677
|
+
? 'Migration prepared: CameraControl will become homekit-service2 Camera. Click Done, then Deploy.'
|
|
678
|
+
: 'Migration prepared. Click Done, then Deploy.',
|
|
679
|
+
'success'
|
|
680
|
+
)
|
|
681
|
+
|
|
682
|
+
$(dialog).dialog('destroy')
|
|
683
|
+
$('.ui-dialog-content').dialog('close')
|
|
684
|
+
}).fail(function (xhr) {
|
|
685
|
+
const message = xhr.responseJSON && xhr.responseJSON.error
|
|
686
|
+
? xhr.responseJSON.error
|
|
687
|
+
: 'Migration failed.'
|
|
688
|
+
RED.notify(message, 'error')
|
|
689
|
+
})
|
|
690
|
+
},
|
|
691
|
+
Cancel: function () {
|
|
692
|
+
$(this).dialog('destroy')
|
|
693
|
+
},
|
|
694
|
+
},
|
|
695
|
+
})
|
|
696
|
+
})
|
|
697
|
+
|
|
543
698
|
let isLinkedDiv = $('#isLinked')
|
|
544
699
|
let isParentDiv = $('#isParent')
|
|
545
700
|
|
|
@@ -622,6 +777,7 @@
|
|
|
622
777
|
selectServiceName
|
|
623
778
|
.change(function () {
|
|
624
779
|
if (this.value === 'CameraControl') {
|
|
780
|
+
cameraConfiguration.prop('open', true)
|
|
625
781
|
cameraConfiguration.fadeIn('fast')
|
|
626
782
|
node.outputs = 3
|
|
627
783
|
} else {
|
|
@@ -634,6 +790,7 @@
|
|
|
634
790
|
selectServiceName
|
|
635
791
|
.change(function () {
|
|
636
792
|
if (this.value === 'Lightbulb') {
|
|
793
|
+
adaptiveLightningConfiguration.prop('open', true)
|
|
637
794
|
adaptiveLightningConfiguration.fadeIn('fast')
|
|
638
795
|
} else {
|
|
639
796
|
adaptiveLightningConfiguration.fadeOut('fast')
|
|
@@ -657,6 +814,8 @@
|
|
|
657
814
|
})
|
|
658
815
|
]
|
|
659
816
|
|
|
817
|
+
const parentServiceOptions = []
|
|
818
|
+
|
|
660
819
|
candidateNodes.forEach(function (n) {
|
|
661
820
|
if (!n.name || n.name.length < 1 || !n.isParent) {
|
|
662
821
|
return
|
|
@@ -689,14 +848,17 @@
|
|
|
689
848
|
const text = n.name + ' (' + sublabel + ')'
|
|
690
849
|
const hostType = n.hostType
|
|
691
850
|
|
|
692
|
-
|
|
693
|
-
|
|
851
|
+
parentServiceOptions.push({
|
|
852
|
+
text,
|
|
853
|
+
element: $('<option></option>')
|
|
694
854
|
.val(value)
|
|
695
855
|
.text(text)
|
|
696
|
-
.attr("hostType", hostType)
|
|
697
|
-
)
|
|
856
|
+
.attr("hostType", hostType)
|
|
857
|
+
})
|
|
698
858
|
})
|
|
699
859
|
|
|
860
|
+
sortSelectOptionsByLabel(selectParentService, parentServiceOptions)
|
|
861
|
+
|
|
700
862
|
selectParentService
|
|
701
863
|
.find('option')
|
|
702
864
|
.filter(function () {
|
|
@@ -753,9 +915,27 @@
|
|
|
753
915
|
})
|
|
754
916
|
})
|
|
755
917
|
},
|
|
918
|
+
oneditcancel: function () {
|
|
919
|
+
delete this._nrchkbPendingMigration
|
|
920
|
+
},
|
|
756
921
|
oneditsave: function () {
|
|
757
922
|
let node = this
|
|
758
923
|
|
|
924
|
+
if (node._nrchkbPendingMigration) {
|
|
925
|
+
const migratedNode = node._nrchkbPendingMigration
|
|
926
|
+
|
|
927
|
+
Object.keys(migratedNode).forEach(function (key) {
|
|
928
|
+
node[key] = migratedNode[key]
|
|
929
|
+
})
|
|
930
|
+
|
|
931
|
+
if (RED.nodes.getType(migratedNode.type)) {
|
|
932
|
+
node._def = RED.nodes.getType(migratedNode.type)
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
delete node._nrchkbPendingMigration
|
|
936
|
+
return true
|
|
937
|
+
}
|
|
938
|
+
|
|
759
939
|
node.isParent = $('#node-config-input-isParent').val() === 'true'
|
|
760
940
|
node.hostType = $('#node-config-input-hostType').val()
|
|
761
941
|
|
|
@@ -771,5 +951,43 @@
|
|
|
771
951
|
).val()
|
|
772
952
|
},
|
|
773
953
|
})
|
|
774
|
-
</script>
|
|
775
954
|
|
|
955
|
+
;(function () {
|
|
956
|
+
const legacyServiceType = 'homekit-service'
|
|
957
|
+
const registry = RED.nodes.registry
|
|
958
|
+
const legacyServiceDefinition = RED.nodes.getType(legacyServiceType)
|
|
959
|
+
|
|
960
|
+
if (legacyServiceDefinition) {
|
|
961
|
+
legacyServiceDefinition.nrchkbPreventNewInstances = true
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
if (registry && !registry._nrchkbPreventNewInstancesPatch) {
|
|
965
|
+
const originalGetNodeTypes = registry.getNodeTypes
|
|
966
|
+
|
|
967
|
+
registry.getNodeTypes = function () {
|
|
968
|
+
return originalGetNodeTypes.call(registry).filter(function (type) {
|
|
969
|
+
const definition = RED.nodes.getType(type)
|
|
970
|
+
return !definition || definition.nrchkbPreventNewInstances !== true
|
|
971
|
+
})
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
registry._nrchkbPreventNewInstancesPatch = true
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
const removeLegacyPaletteNode = function () {
|
|
978
|
+
$('.red-ui-palette-node[data-palette-type="' + legacyServiceType + '"]').remove()
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
if (registry && RED.events && RED.events.on && !registry._nrchkbLegacyServicePaletteHandler) {
|
|
982
|
+
RED.events.on('registry:node-type-added', function (type) {
|
|
983
|
+
if (type === legacyServiceType) {
|
|
984
|
+
removeLegacyPaletteNode()
|
|
985
|
+
}
|
|
986
|
+
})
|
|
987
|
+
registry._nrchkbLegacyServicePaletteHandler = true
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
removeLegacyPaletteNode()
|
|
991
|
+
setTimeout(removeLegacyPaletteNode, 0)
|
|
992
|
+
})()
|
|
993
|
+
</script>
|