homebridge-http-advanced-platform 2.0.0-alpha.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.
Files changed (56) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +175 -0
  3. package/config.schema.json +449 -0
  4. package/dist/accessory.d.ts +27 -0
  5. package/dist/accessory.js +164 -0
  6. package/dist/accessory.js.map +1 -0
  7. package/dist/actions.d.ts +8 -0
  8. package/dist/actions.js +47 -0
  9. package/dist/actions.js.map +1 -0
  10. package/dist/compatibility.d.ts +3 -0
  11. package/dist/compatibility.js +26 -0
  12. package/dist/compatibility.js.map +1 -0
  13. package/dist/config.d.ts +2 -0
  14. package/dist/config.js +81 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/coordinator.d.ts +51 -0
  17. package/dist/coordinator.js +145 -0
  18. package/dist/coordinator.js.map +1 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +8 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/mappers.d.ts +3 -0
  23. package/dist/mappers.js +116 -0
  24. package/dist/mappers.js.map +1 -0
  25. package/dist/metadata.d.ts +5 -0
  26. package/dist/metadata.js +8 -0
  27. package/dist/metadata.js.map +1 -0
  28. package/dist/platform.d.ts +18 -0
  29. package/dist/platform.js +129 -0
  30. package/dist/platform.js.map +1 -0
  31. package/dist/runtime.d.ts +54 -0
  32. package/dist/runtime.js +376 -0
  33. package/dist/runtime.js.map +1 -0
  34. package/dist/settings.d.ts +21 -0
  35. package/dist/settings.js +51 -0
  36. package/dist/settings.js.map +1 -0
  37. package/dist/transport.d.ts +25 -0
  38. package/dist/transport.js +139 -0
  39. package/dist/transport.js.map +1 -0
  40. package/dist/types.d.ts +106 -0
  41. package/dist/types.js +10 -0
  42. package/dist/types.js.map +1 -0
  43. package/dist/ui-config.d.ts +27 -0
  44. package/dist/ui-config.js +208 -0
  45. package/dist/ui-config.js.map +1 -0
  46. package/docs/alpha-release-notes.md +19 -0
  47. package/docs/legacy-reference.md +678 -0
  48. package/docs/migration.md +43 -0
  49. package/docs/modernization.md +211 -0
  50. package/docs/performance.md +37 -0
  51. package/docs/service-support.md +47 -0
  52. package/homebridge-ui/public/index.html +74 -0
  53. package/homebridge-ui/public/settings.js +132 -0
  54. package/homebridge-ui/server.js +17 -0
  55. package/package.json +83 -0
  56. package/sample-config.json +39 -0
@@ -0,0 +1,678 @@
1
+ > Historical 1.3.0 feature reference and examples. For Alpha installation, runtime requirements, cache behavior and corrected documentation, use the root README. Examples are retained as compatibility reference; this document does not override Alpha guidance.
2
+
3
+ # homebridge http advanced accessory
4
+
5
+ Homebridge plugin that can turn virtually any device which exposes HTTP APIs into an HomeKit-compatible Service.
6
+ Its purpose is to connect any device that can be controlled via HTTP command to Homekit. It creates a Homebridge accessory which uses HTTP calls to *change* and *check* its state via [Actions](#actions).
7
+
8
+ This plugin is a fork of HttpAccessory and has merged many features (mainly mappers) from the [homebridge-http-securitysystem](<https://www.npmjs.com/package/homebridge-http-securitysystem>).
9
+
10
+ ## Installation
11
+
12
+ 1. Install homebridge using: npm install -g homebridge
13
+ 2. Install this plugin using: npm install -g homebridge-http-advanced-accessory
14
+ 3. Update your configuration file. See sample-config.json in this repository for a sample.
15
+
16
+ ## Features
17
+
18
+ The main function of the module is to proxy HomeKit queries to an arbitrary web API to retrieve and set the status of the accessory. Main features include:
19
+
20
+ - Configurable HTTP endpoints to use for getting/setting the state, including passing parameters in for of GET or in POST body
21
+ - Support for basic HTTP authentication
22
+ - Configurable mapping of API response data to HomeKit Accessory status to allow custom responses
23
+ - Configurable mapping of url and body request data to HomeKit Accessory status to allow custom requests
24
+ - Interval polling of the current state to enable real-time notifications even if the Accessory has been enabled without the use of HomeKit
25
+
26
+ ## Configuration
27
+
28
+ Configuration sample:
29
+
30
+ ```json
31
+ {
32
+ "bridge": {
33
+ "name": "Homebridge",
34
+ "username": "C1:38:5A:AC:39:30",
35
+ "port": 51826,
36
+ "pin": "123-45-678"
37
+ },
38
+ "description": "This is an example configuration for the Everything Homebridge plugin",
39
+ "accessories": [
40
+ {
41
+ "accessory": "HttpAdvancedAccessory",
42
+ "service": "ContactSensor",
43
+ "name": "Terrace Sensor",
44
+ "forceRefreshDelay": 5,
45
+ "username": "admin",
46
+ "password": "admin",
47
+ "debug" : false,
48
+ "optionCharacteristic" :[],
49
+ "urls":{
50
+ "getContactSensorState": {
51
+ "url" : "http://remoteserver/xml/zones/zonesStatus48IP.xml",
52
+ "mappers" : [
53
+ {
54
+ "type": "xpath",
55
+ "parameters": {
56
+ "xpath": "//status[1]/text()"
57
+ }
58
+ },
59
+ {
60
+ "type": "static",
61
+ "parameters": {
62
+ "mapping": {
63
+ "ALARM": "1",
64
+ "NORMAL":"0"
65
+ }
66
+ }
67
+ }
68
+ ]
69
+ }
70
+ }
71
+ },
72
+ {
73
+ "accessory": "HttpAdvancedAccessory",
74
+ "service": "SecuritySystem",
75
+ "name": "Btcino Security",
76
+ "forceRefreshDelay": 5,
77
+ "username": "admin",
78
+ "password": "admin",
79
+ "debug" : false,
80
+ "setterDelay" : 1000,
81
+ "urls":{
82
+ "getSecuritySystemTargetState": {
83
+ "url" : "http://remoteserver/xml/state/virtualKeypad.xml",
84
+ "mappers" : [
85
+ { "type": "xpath", "parameters": { "xpath": "//generic/text()" } },
86
+ { "type": "static", "parameters": { "mapping": { "0": "3", "1": "1", "2": "2", "3": "0" } } }
87
+ ]
88
+ },
89
+ "getSecuritySystemCurrentState": {
90
+ "url" : "http://remoteserver/xml/partitions/partitionsStatus48IP.xml",
91
+ "mappers" : [
92
+ { "type": "regex", "parameters": { "regexp" : "(ALARM)", "capture": "1" } },
93
+ { "type": "regex", "parameters": { "regexp" : ">(ARMED)", "capture": "1" } },
94
+ { "type": "regex", "parameters": { "regexp" : "(DISARMED)", "capture": "1" } },
95
+ { "type": "static", "parameters": { "mapping": { "ALARM": "4", "ARMED":"inconclusive", "DISARMED": "3"} } }
96
+ ],
97
+ "inconclusive" : {
98
+ "url" : "http://remoteserver/xml/state/virtualKeypad.xml",
99
+ "mappers" : [
100
+ { "type": "xpath", "parameters": { "xpath": "//generic/text()" } },
101
+ { "type": "static", "parameters": { "mapping": { "0": "3", "1": "1", "2": "2", "3": "0" } } }
102
+ ]
103
+ }
104
+ },
105
+ "setSecuritySystemTargetState": {
106
+ "url" : "http://remoteserver/xml/cmd/cmdOk.xml?cmd=setMacro&macroId={value}&redirectPage=/xml/cmd/cmdError.xml",
107
+ "mappers" : [
108
+ { "type": "static", "parameters": { "mapping": { "0": "3", "1": "1", "2": "2", "3": "0" } } }
109
+ ]
110
+ }
111
+ }
112
+ }
113
+ ],
114
+
115
+ "platforms": []
116
+ }
117
+ ```
118
+
119
+ - The **name** parameter determines the name of the accessory you will see in HomeKit.
120
+ - The **service** parameter determines the kind of Service\Accessory you will see in HomeKit.
121
+ - The **username/password** configuration can be used to specify the username and password if the remote webserver requires HTTP authentication.
122
+ - A **debug** turns on debug messages. The important bit is that it reports the mapping process so that it's easier to debug.
123
+ - The **optionCharacteristic** is an array of optional Characteristics of the service that you want to expose to HomeKit. The full list of mandatory and optional Characteristics types that HomeKit supports are exposed as a separate subclass in [HomeKitTypes](https://github.com/homebridge/HAP-NodeJS/blob/master/src/lib/gen/HomeKit.ts).
124
+ - The **urls section** configures the URLs that are to be called on certain events. It contains a key-value map of actions that can be executed. The key is name of the action and the value is a configuration JSON object for that action. See the [Actions](#actions) section below.
125
+ - The **polling** is a boolean that specifies if the current state should be pulled on regular intervals or not. Defaults to false.
126
+ - **forceRefreshDelay** is a number which defines the poll interval in seconds. Defaults to 0.
127
+ - **setterDelay** is a number which defines the number of milliseconds to wait before executing a "set" action request. If more than one request is received during this interval, only the last one is executed. Defaults to 0 - disabled.
128
+ - **uriCallsDelay** number of milliseconds to add a short delay between URI calls for devices that can't handle many URI calls at the same time. Defaults to 0 - disabled.
129
+
130
+ ## Actions
131
+
132
+ The action is a key-value map that configures the URLs to be called to perform a read or a write on a particular Characteristic. In fact, there are two kind of actions, getters and setters: actions for getter keys begin with word "get", actions for the setters begin with "set".
133
+ So the key name is composed of two parts:
134
+
135
+ - The kind of action: "get" or "set"
136
+ - The name of the HomeKit Characteristics for that Service. All known built-in Service and Characteristic types that HomeKit supports are exposed as a separate subclass in [HomeKitTypes](https://github.com/homebridge/HAP-NodeJS/blob/master/src/lib/gen/HomeKit.ts).
137
+
138
+ For example, to get the value of the SecuritySystemTargetState Characteristic, the key value would be "getSecuritySystemTargetState"—while to set it, "setSecuritySystemTargetState"
139
+
140
+ ### Getter Action
141
+
142
+ The value object has the following JSON format for a **getter** action:
143
+
144
+ ```json
145
+ "getTargetTemperature" : {
146
+ "url":"http://",
147
+ "httpMethod":"",
148
+ "body" : "",
149
+ "mappers" : [],
150
+ "inconclusive" : {
151
+ "url":"",
152
+ "httpMethods":"",
153
+ "mappers": [],
154
+ "inconclusive":{}
155
+ }
156
+ }
157
+ ```
158
+
159
+ Where:
160
+
161
+ - The **url** parameter is the url to be called for that action.
162
+ - The **httpMethod** (OPTIONAL) parameter is one of "GET" or "POST". Defaults to "GET".
163
+ - The **body** (OPTIONAL) parameter is the body of the HTTP POST call.
164
+ - The **mappers** (OPTIONAL) are a chain of blocks that have the purpose to parse the response received, see [Mapping](#mapping)
165
+ - The **inconclusive** (OPTIONAL) parameter is another action that will be invoked if the result of the previous mapping chain is the word "inconclusive"
166
+ - The **resultOnError** (OPTIONAL) parameter, if specified, will be result if the HTTP request encounters an error. This is helpful for HTTP health checks, where failure to connect can be mapped to a (valid) failing value rather than passed through as an error.
167
+
168
+ ### Setter Action
169
+
170
+ The value object has the following JSON format for a **setter** action:
171
+
172
+ ```json
173
+ "setTargetTemperature" : {
174
+ "url":"http://remoteserver/setTemperature?stemp={value}",
175
+ "httpMethod":"",
176
+ "body" : "{value}",
177
+ "mappers" : []
178
+ }
179
+ ```
180
+
181
+ Where:
182
+
183
+ - The **url** parameter is the URL to be called for that action. If the string contains the "{value}" placeholder, it will be replaced by the value that HomeKit wants to set, after being changed parsed by mappers. The url can also be a string template, see [URL Template](#url-template)
184
+ - The **httpMethod** (OPTIONAL) parameter is one of "GET" or "POST". Defaults to "GET".
185
+ - The **body** (OPTIONAL) parameter is the body of the HTTP POST call.
186
+ - The **mappers** (OPTIONAL) are a chain of blocks that have the purpose of changing the value that HomeKit wants to set to something that is valid for your device, see [Mapping](#mapping)
187
+
188
+ ### URL Template
189
+
190
+ The URL can be a [string template](<http://exploringjs.com/es6/ch_template-literals.html>) so you can use expressions like *$(state.getCurrentTemperature)* that will be replaced by the current value of the Characteristic CurrentTemperature.
191
+ The *state* variable contains all the values of the Characteristics of the Service, plus the *value* variable contains the value HK wants to set for the Characteristic being set.
192
+ For example, suppose that when setting the Active state of a HeatingCooling system it also needs to set the TargetTemperature in Fahrenheit—you may have something like this:
193
+
194
+ ```json
195
+ "setActive" : {
196
+ "url":"http://remoteserver/setActive?${value}&stemp=${state.getTargetTemperature * 9/5 +32}"
197
+ }
198
+ ```
199
+
200
+
201
+
202
+ ### Mapping
203
+
204
+ The mappings block of the configuration may contain any number of mapper definitions. The mappers are chained after each other—the result of a mapper is fed into the input of the next mapper. The purpose of this whole chain is to somehow boil down the response received from the API to a single value which is expected by HomeKit.
205
+
206
+ Each mapper has the following JSON format:
207
+
208
+ ```json
209
+ {
210
+ "type": "<type of the mapper>",
211
+ "parameters": { <parameters to be passed to the mapper> }
212
+ }
213
+ ```
214
+
215
+ There are 3 kinds of mappers implemented at the moment.
216
+
217
+ #### Static mapper
218
+
219
+ The static mapper can be used to define a key => value dictionary. It will simply look up the input in the dictionary and if it is found, it returns the corresponding value. It's great for mapping string responses like "ARMED" to their actual number.
220
+
221
+ Configuration is as follows:
222
+
223
+ ```json
224
+ {
225
+ "type": "static",
226
+ "parameters": {
227
+ "mapping": {
228
+ "STAY": "0",
229
+ "AWAY": "1",
230
+ "whataever you don't like": "whatever you like more"
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+ This configuration would map STAY to 0, AWAY to 1 and "whatever you don't like" to "whatever you like more". If the mapping does not have an entry which corresponds to input, it returns the full input.
237
+
238
+ #### Regexp mapper
239
+
240
+ The regexp mapper can be used to define a regular expression to run on the input, capture some substring of it and return it. It's great for mapping string responses which may change around but have a certain part that's always there and which is the part you are interested in.
241
+
242
+ Configuration is as follows:
243
+
244
+ ```json
245
+ {
246
+ "type": "regex",
247
+ "parameters": {
248
+ "regexp": "^The system is currently (ARMED|DISARMED), yo!$",
249
+ "capture": "1"
250
+ }
251
+ }
252
+ ```
253
+
254
+ This configuration will run the regular expression defined by the ***regexp*** parameter against the input and return the first capture group (as defined by ***capture***). So, in this case, if the input is "The system is currenty ARMED, yo!", the mapper will map this to "ARMED".
255
+
256
+ If the regexp does not match the input, the mapper returns the full input.
257
+
258
+ #### XPath mapper
259
+
260
+ The XPath mapper can be used to extract data from an XML document. It allows the definition of an XPath which will then be applied to the input and returns whatever the query selects.
261
+
262
+ When using this mapper, make sure that you select text elements and not entire nodes or node lists, otherwise it will fail horribly.
263
+
264
+ Configuration is as follows:
265
+
266
+ ```json
267
+ {
268
+ "type": "xpath",
269
+ "parameters": {
270
+ "xpath": "//partition[3]/text()",
271
+ "index": 0
272
+ }
273
+ }
274
+ ```
275
+
276
+ Let's assume this mapper gets the following input:
277
+
278
+ ```xml
279
+ <?xml version="1.0" encoding="ISO-8859-1"?>
280
+ <partitionsStatus>
281
+ <partition>ARMED</partition>
282
+ <partition>ARMED</partition>
283
+ <partition>ARMED_IMMEDIATE</partition>
284
+ </partitionsStatus>
285
+ ```
286
+
287
+ In this case this mapper will return "ARMED_IMMEDIATE". The ***index*** parameter can be used to specify which element to return if the xpath selects multiple elements. In the example above it is completely redundant as partition[3] already makes sure that a single partition is selected.
288
+
289
+ #### JSONPath mapper
290
+
291
+ The JSONPath mapper can be used to extract data from a JSON object. See https://www.npmjs.com/package/JSONPath#syntax-through-examples for syntax and more examples.
292
+
293
+ When using this mapper, make sure that you select text elements or arrays and not entire objects.
294
+
295
+ Configuration is as follows:
296
+
297
+ ```json
298
+ {
299
+ "type": "jpath",
300
+ "parameters": {
301
+ "jpath": "$.partitionsStatus.partition[2]",
302
+ "index": 0
303
+ }
304
+ }
305
+ ```
306
+
307
+ Let's assume this mapper gets the following input:
308
+
309
+ ```json
310
+ {
311
+ "partitionsStatus": {
312
+ "partition": [
313
+ "ARMED",
314
+ "ARMED",
315
+ "ARMED_IMMEDIATE",
316
+ ]
317
+ }
318
+ }
319
+ ```
320
+
321
+ In this case this mapper will return "ARMED_IMMEDIATE". The ***index*** parameter can be used to specify which element to return if the JSONPath selects multiple elements. In the example above it is completely redundant as partition[2] already makes sure that a single partition is selected.
322
+
323
+ #### Eval mapper
324
+
325
+ The eval mapper can be used to run any JavaScript code, which will be interpreted when the event is called. Use `value` to use the set/read value in your code.
326
+
327
+ Configuration is as follows:
328
+
329
+ ```json
330
+ {
331
+ "type": "eval",
332
+ "parameters": {
333
+ "expression": "value === \"OK\" ? 1 : 0"
334
+ }
335
+ }
336
+ ```
337
+
338
+ In this example, if the mapper receives the string `OK` it will return `1`, for anything else it will return `0`.
339
+ Be careful with the code you write, this mapper can be very flexible but it can also blow up quite easily.
340
+
341
+ ## Supported services
342
+
343
+ AccessoryInformation
344
+ AirQualitySensor
345
+ BatteryService
346
+ BridgeConfiguration
347
+ BridgingState
348
+ CameraControl
349
+ CameraRTPStreamManagement
350
+ CarbonDioxideSensor
351
+ CarbonMonoxideSensor
352
+ ContactSensor
353
+ Door
354
+ Doorbell
355
+ Fan
356
+ GarageDoorOpener
357
+ HumiditySensor
358
+ LeakSensor
359
+ LightSensor
360
+ Lightbulb
361
+ LockManagement
362
+ LockMechanism
363
+ Microphone
364
+ MotionSensor
365
+ OccupancySensor
366
+ Outlet
367
+ Pairing
368
+ ProtocolInformation
369
+ Relay
370
+ SecuritySystem
371
+ SmokeSensor
372
+ Speaker
373
+ StatefulProgrammableSwitch
374
+ StatelessProgrammableSwitch
375
+ Switch
376
+ TemperatureSensor
377
+ Thermostat
378
+ TimeInformation
379
+ TunneledBTLEAccessoryService
380
+ Window
381
+ WindowCovering
382
+
383
+ ## Configuration Examples
384
+
385
+ The purpose of this section is collect as many configuration examples as possible.
386
+
387
+ ### Bticino "Nuovo antifurto filare"
388
+
389
+ This first example is to configure a Bticino (BT-4200, 4201, 4202) as a HomeKit SecuritySystem
390
+
391
+ ```json
392
+ {
393
+ "accessory": "HttpAdvancedAccessory",
394
+ "service": "SecuritySystem",
395
+ "name": "Btcino Security",
396
+ "forceRefreshDelay": 5,
397
+ "username": "admin",
398
+ "password": "admin",
399
+ "debug" : false,
400
+ "urls":{
401
+ "getSecuritySystemTargetState": {
402
+ "url" : "http://remoteserver/xml/state/virtualKeypad.xml",
403
+ "mappers" : [
404
+ { "type": "xpath", "parameters": { "xpath": "//generic/text()" } },
405
+ { "type": "static", "parameters": { "mapping": { "0": "3", "1": "1", "2": "2", "3": "0" } } }
406
+ ]
407
+ },
408
+ "getSecuritySystemCurrentState": {
409
+ "url" : "http://remoteserver/xml/partitions/partitionsStatus48IP.xml",
410
+ "mappers" : [
411
+ { "type": "regex", "parameters": { "regexp" : "(ALARM)", "capture": "1" } },
412
+ { "type": "regex", "parameters": { "regexp" : ">(ARMED)", "capture": "1" } },
413
+ { "type": "regex", "parameters": { "regexp" : "(DISARMED)", "capture": "1" } },
414
+ { "type": "static", "parameters": { "mapping": { "ALARM": "4", "ARMED":"inconclusive", "DISARMED": "3"} } }
415
+ ],
416
+ "inconclusive" : {
417
+ "url" : "http://remoteserver/xml/state/virtualKeypad.xml",
418
+ "mappers" : [
419
+ { "type": "xpath", "parameters": { "xpath": "//generic/text()" } },
420
+ { "type": "static", "parameters": { "mapping": { "0": "3", "1": "1", "2": "2", "3": "0" } } }
421
+ ]
422
+ }
423
+ },
424
+ "setSecuritySystemTargetState": {
425
+ "url" : "http://remoteserver/xml/cmd/cmdOk.xml?cmd=setMacro&macroId={value}&redirectPage=/xml/cmd/cmdError.xml",
426
+ "mappers" : [
427
+ { "type": "static", "parameters": { "mapping": { "0": "3", "1": "1", "2": "2", "3": "0" } } }
428
+ ]
429
+ }
430
+ }
431
+ }
432
+ ```
433
+
434
+ ### Bticino "Nuovo antifurto filare" Zones as ContactSensor
435
+
436
+ ```json
437
+ {
438
+ "accessory": "HttpAdvancedAccessory",
439
+ "service": "ContactSensor",
440
+ "name": "Terrace Sensor",
441
+ "forceRefreshDelay": 5,
442
+ "username": "admin",
443
+ "password": "admin",
444
+ "debug" : false,
445
+ "urls":{
446
+ "getContactSensorState": {
447
+ "url" : "http://remoteserver/xml/zones/zonesStatus48IP.xml",
448
+ "mappers" : [
449
+ {
450
+ "type": "xpath",
451
+ "parameters": {
452
+ "xpath": "//status[1]/text()"
453
+ }
454
+ },
455
+ {
456
+ "type": "static",
457
+ "parameters": {
458
+ "mapping": {
459
+ "ALARM": "1",
460
+ "NORMAL":"0"
461
+ }
462
+ }
463
+ }
464
+ ]
465
+ }
466
+ }
467
+ }
468
+ ```
469
+
470
+ ### Daikin as HeaterCooler
471
+
472
+ This is still incomplete but the unofficial [Daikin documentation](https://github.com/ael-code/daikin-control) can help you to complete it.
473
+
474
+ ```json
475
+ {
476
+ "accessory": "HttpAdvancedAccessory",
477
+ "service": "HeaterCooler",
478
+ "name": "Condizionatore Soggiorno",
479
+ "forceRefreshDelay": 5,
480
+ "debug" : false,
481
+ "urls":{
482
+ "getCurrentHeaterCoolerState": {
483
+ "url" : "http://192.168.x.x/aircon/get_control_info",
484
+ "mappers" : [
485
+ {"type": "regex", "parameters": {"regexp": "(pow=0)","capture": "1"} },
486
+ {"type": "regex", "parameters": { "regexp": "mode=(\\d)", "capture": "1"} },
487
+ {"type": "static", "parameters": { "mapping": { "pow=0": "0", "3":"3", "4":"2"} } }
488
+ ]
489
+ },
490
+ "getTargetHeaterCoolerState":{
491
+ "url" : "http://192.168.x.x/aircon/get_control_info",
492
+ "mappers" : [
493
+ {"type": "regex", "parameters": {"regexp": "(pow=0)","capture": "1"} },
494
+ {"type": "regex", "parameters": { "regexp": "mode=(\\d)", "capture": "1"} },
495
+ {"type": "static", "parameters": { "mapping": { "pow=0": "0", "3":"3", "4":"2", "0":"3", "1":"3", "7":"3", "2":"3"} } }
496
+ ]
497
+ },
498
+ "setTargetHeaterCoolerState":{
499
+ "url" : "http://192.168.x.x/aircon/set_control_info/{value}",
500
+ "mappers" : [
501
+ {"type": "static", "parameters": { "mapping": { "0": "?mode=0", "1":"?mode=4", "2":"?mode=3"} } }
502
+ ]
503
+ },
504
+ "getActive":{
505
+ "url" : "http://192.168.x.x/aircon/get_control_info",
506
+ "mappers" : [
507
+ {"type": "regex", "parameters": {"regexp": "pow=(\\d)","capture": "1"} }
508
+ ]
509
+ },
510
+ "setActive":{
511
+ "url" : "http://192.168.x.x/aircon/set_control_info/{value}",
512
+ "mappers" : [
513
+ {"type": "static", "parameters": { "mapping": { "0": "?pow=0", "1":"?pow=1"} } }
514
+ ]
515
+ }
516
+
517
+ }
518
+ }
519
+
520
+ ```
521
+
522
+ ### Yamaha Musiccast WX-010 as Switch
523
+
524
+ ```json
525
+ {
526
+ "accessory": "HttpAdvancedAccessory",
527
+ "service": "Switch",
528
+ "name": "Bedroom speaker",
529
+ "forceRefreshDelay": 5,
530
+ "debug" : false,
531
+ "urls":{
532
+ "getOn":{
533
+ "url" : "http://192.168.x.x/YamahaExtendedControl/v1/main/getStatus",
534
+ "mappers" : [
535
+ {
536
+ "type": "jpath",
537
+ "parameters": {
538
+ "jpath": "$..power",
539
+ "index": "0"
540
+ }
541
+ },
542
+ {
543
+ "type": "static",
544
+ "parameters": {
545
+ "mapping": {
546
+ "on": "1",
547
+ "standby": "0"
548
+ }
549
+ }
550
+ }
551
+ ]
552
+ },
553
+ "setOn":{
554
+ "url" : "http://192.168.x.x/YamahaExtendedControl/v1/main/setPower?power=${value==1?\"on\":\"standby\"}"
555
+ }
556
+
557
+ }
558
+ }
559
+
560
+ ```
561
+
562
+ ### Generic Web API as Lightbulb
563
+
564
+ ```json
565
+ {
566
+ "accessory": "HttpAdvancedAccessory",
567
+ "service": "Lightbulb",
568
+ "name": "Pool Light",
569
+ "manufacturer": "Custom",
570
+ "model": "Virtual Device",
571
+ "debug": false,
572
+ "optionCharacteristic": [
573
+ "Hue",
574
+ "Saturation",
575
+ "Brightness"
576
+ ],
577
+ "urls": {
578
+ "setOn": {
579
+ "httpMethod": "POST",
580
+ "body": "%7B%22c%22%3A%22pool%20i%20{value}%22%7D",
581
+ "url": "http://127.0.0.1/control.php",
582
+ "mappers": [
583
+ {
584
+ "type": "static",
585
+ "parameters": {
586
+ "mapping": {
587
+ "true": "on",
588
+ "false": "off"
589
+ }
590
+ }
591
+ }
592
+ ]
593
+ },
594
+ "getOn": {
595
+ "httpMethod": "POST",
596
+ "body": "%7B%22c%22%3A%22update%20pool-on%22%7D",
597
+ "url": "http://127.0.0.1/control.php",
598
+ "mappers": [
599
+ {
600
+ "type": "jpath",
601
+ "parameters": {
602
+ "jpath": "$.u",
603
+ "index": 0
604
+ }
605
+ }
606
+ ]
607
+ },
608
+ "setHue": {
609
+ "httpMethod": "POST",
610
+ "url": "http://127.0.0.1/control.php",
611
+ "body": "%7B%22c%22%3A%22pool%20hue%20{value}%22%7D",
612
+ "mappers": []
613
+ },
614
+ "getHue": {
615
+ "httpMethod": "POST",
616
+ "url": "http://127.0.0.1/control.php",
617
+ "body": "%7B%22c%22%3A%22value%20pool-h%22%7D",
618
+ "mappers": [
619
+ {
620
+ "type": "jpath",
621
+ "parameters": {
622
+ "jpath": "$.u",
623
+ "index": 0
624
+ }
625
+ }
626
+ ]
627
+ },
628
+ "setSaturation": {
629
+ "httpMethod": "POST",
630
+ "url": "http://127.0.0.1/control.php",
631
+ "body": "%7B%22c%22%3A%22pool%20saturation%20{value}%22%7D",
632
+ "mappers": []
633
+ },
634
+ "getSaturation": {
635
+ "httpMethod": "POST",
636
+ "url": "http://127.0.0.1/control.php",
637
+ "body": "%7B%22c%22%3A%22value%20pool-s%22%7D",
638
+ "mappers": [
639
+ {
640
+ "type": "jpath",
641
+ "parameters": {
642
+ "jpath": "$.u",
643
+ "index": 0
644
+ }
645
+ }
646
+ ]
647
+ },
648
+ "setBrightness": {
649
+ "httpMethod": "POST",
650
+ "url": "http://127.0.0.1/control.php",
651
+ "body": "%7B%22c%22%3A%22pool%20brightness%20{value}%22%7D",
652
+ "mappers": []
653
+ },
654
+ "getBrightness": {
655
+ "httpMethod": "POST",
656
+ "url": "http://127.0.0.1/control.php",
657
+ "body": "%7B%22c%22%3A%22value%20pool-b%22%7D",
658
+ "mappers": [
659
+ {
660
+ "type": "jpath",
661
+ "parameters": {
662
+ "jpath": "$.u",
663
+ "index": 0
664
+ }
665
+ }
666
+ ]
667
+ }
668
+ }
669
+ }
670
+ ```
671
+
672
+ ## Plugin Development
673
+
674
+ To aid in testing and developing this plugin further I have provided a sample homebridge config. This will allow you to spin a homebridge instance for development that has this plugin already installed.
675
+ Install homebridge, checkout this repo and run:
676
+ ```sh
677
+ $ homebridge --debug --user-storage-path .homebridge-dev --plugin-path ./
678
+ ```