@smarthome.exchange/integrations 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +49 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/core/classes.configstore.d.ts +2 -0
- package/dist_ts/core/classes.configstore.js +84 -27
- package/dist_ts/core/classes.nativehomeadmission.d.ts +19 -0
- package/dist_ts/core/classes.nativehomeadmission.js +84 -0
- package/dist_ts/core/classes.nativeintegrationowner.d.ts +79 -0
- package/dist_ts/core/classes.nativeintegrationowner.js +269 -0
- package/dist_ts/core/index.d.ts +2 -0
- package/dist_ts/core/index.js +3 -1
- package/dist_ts/core/types.d.ts +14 -0
- package/dist_ts/integrations/braviatv/braviatv.classes.client.d.ts +23 -72
- package/dist_ts/integrations/braviatv/braviatv.classes.client.js +265 -625
- package/dist_ts/integrations/braviatv/braviatv.classes.configflow.d.ts +7 -7
- package/dist_ts/integrations/braviatv/braviatv.classes.configflow.js +51 -68
- package/dist_ts/integrations/braviatv/braviatv.classes.integration.d.ts +8 -11
- package/dist_ts/integrations/braviatv/braviatv.classes.integration.js +186 -135
- package/dist_ts/integrations/braviatv/braviatv.discovery.js +12 -11
- package/dist_ts/integrations/braviatv/braviatv.mapper.d.ts +6 -14
- package/dist_ts/integrations/braviatv/braviatv.mapper.js +37 -131
- package/dist_ts/integrations/braviatv/braviatv.types.d.ts +55 -133
- package/dist_ts/integrations/braviatv/braviatv.validation.d.ts +7 -0
- package/dist_ts/integrations/braviatv/braviatv.validation.js +72 -0
- package/dist_ts/integrations/broadlink/broadlink.actions.d.ts +2 -0
- package/dist_ts/integrations/broadlink/broadlink.actions.js +36 -0
- package/dist_ts/integrations/broadlink/broadlink.classes.client.d.ts +21 -19
- package/dist_ts/integrations/broadlink/broadlink.classes.client.js +185 -124
- package/dist_ts/integrations/broadlink/broadlink.classes.configflow.d.ts +5 -4
- package/dist_ts/integrations/broadlink/broadlink.classes.configflow.js +64 -83
- package/dist_ts/integrations/broadlink/broadlink.classes.integration.d.ts +16 -19
- package/dist_ts/integrations/broadlink/broadlink.classes.integration.js +114 -59
- package/dist_ts/integrations/broadlink/broadlink.mapper.d.ts +3 -2
- package/dist_ts/integrations/broadlink/broadlink.mapper.js +2 -1
- package/dist_ts/integrations/broadlink/broadlink.selected.mapper.d.ts +10 -0
- package/dist_ts/integrations/broadlink/broadlink.selected.mapper.js +41 -0
- package/dist_ts/integrations/broadlink/broadlink.types.d.ts +43 -7
- package/dist_ts/integrations/broadlink/broadlink.validation.d.ts +7 -0
- package/dist_ts/integrations/broadlink/broadlink.validation.js +63 -0
- package/dist_ts/integrations/daikin/daikin.classes.client.d.ts +10 -52
- package/dist_ts/integrations/daikin/daikin.classes.client.js +55 -614
- package/dist_ts/integrations/daikin/daikin.classes.configflow.d.ts +8 -12
- package/dist_ts/integrations/daikin/daikin.classes.configflow.js +77 -138
- package/dist_ts/integrations/daikin/daikin.classes.integration.d.ts +7 -24
- package/dist_ts/integrations/daikin/daikin.classes.integration.js +175 -67
- package/dist_ts/integrations/daikin/daikin.discovery.d.ts +11 -24
- package/dist_ts/integrations/daikin/daikin.discovery.js +98 -305
- package/dist_ts/integrations/daikin/daikin.mapper.d.ts +6 -7
- package/dist_ts/integrations/daikin/daikin.mapper.js +95 -155
- package/dist_ts/integrations/daikin/daikin.types.d.ts +24 -44
- package/dist_ts/integrations/daikin/daikin.types.js +1 -1
- package/dist_ts/integrations/daikin/daikin.validation.d.ts +5 -0
- package/dist_ts/integrations/daikin/daikin.validation.js +53 -0
- package/dist_ts/integrations/denonavr/denonavr.classes.client.d.ts +31 -40
- package/dist_ts/integrations/denonavr/denonavr.classes.client.js +149 -404
- package/dist_ts/integrations/denonavr/denonavr.classes.configflow.d.ts +7 -2
- package/dist_ts/integrations/denonavr/denonavr.classes.configflow.js +44 -36
- package/dist_ts/integrations/denonavr/denonavr.classes.integration.d.ts +6 -11
- package/dist_ts/integrations/denonavr/denonavr.classes.integration.js +192 -113
- package/dist_ts/integrations/denonavr/denonavr.discovery.d.ts +10 -18
- package/dist_ts/integrations/denonavr/denonavr.discovery.js +71 -193
- package/dist_ts/integrations/denonavr/denonavr.mapper.d.ts +5 -13
- package/dist_ts/integrations/denonavr/denonavr.mapper.js +35 -159
- package/dist_ts/integrations/denonavr/denonavr.types.d.ts +55 -90
- package/dist_ts/integrations/denonavr/denonavr.validation.d.ts +10 -0
- package/dist_ts/integrations/denonavr/denonavr.validation.js +86 -0
- package/dist_ts/integrations/kodi/kodi.classes.client.d.ts +11 -45
- package/dist_ts/integrations/kodi/kodi.classes.client.js +84 -310
- package/dist_ts/integrations/kodi/kodi.classes.configflow.d.ts +9 -8
- package/dist_ts/integrations/kodi/kodi.classes.configflow.js +53 -48
- package/dist_ts/integrations/kodi/kodi.classes.integration.d.ts +11 -11
- package/dist_ts/integrations/kodi/kodi.classes.integration.js +114 -171
- package/dist_ts/integrations/kodi/kodi.discovery.js +53 -29
- package/dist_ts/integrations/kodi/kodi.mapper.d.ts +7 -2
- package/dist_ts/integrations/kodi/kodi.mapper.js +48 -10
- package/dist_ts/integrations/kodi/kodi.types.d.ts +32 -28
- package/dist_ts/integrations/kodi/kodi.validation.d.ts +9 -0
- package/dist_ts/integrations/kodi/kodi.validation.js +62 -0
- package/dist_ts/integrations/modbus/modbus.classes.client.d.ts +15 -61
- package/dist_ts/integrations/modbus/modbus.classes.client.js +117 -776
- package/dist_ts/integrations/modbus/modbus.classes.configflow.d.ts +9 -5
- package/dist_ts/integrations/modbus/modbus.classes.configflow.js +70 -38
- package/dist_ts/integrations/modbus/modbus.classes.integration.d.ts +6 -17
- package/dist_ts/integrations/modbus/modbus.classes.integration.js +133 -57
- package/dist_ts/integrations/modbus/modbus.discovery.d.ts +5 -8
- package/dist_ts/integrations/modbus/modbus.discovery.js +38 -93
- package/dist_ts/integrations/modbus/modbus.mapper.d.ts +8 -32
- package/dist_ts/integrations/modbus/modbus.mapper.js +71 -431
- package/dist_ts/integrations/modbus/modbus.types.d.ts +82 -332
- package/dist_ts/integrations/modbus/modbus.validation.d.ts +10 -0
- package/dist_ts/integrations/modbus/modbus.validation.js +128 -0
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.d.ts +12 -34
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.js +143 -231
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.d.ts +6 -1
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.js +105 -18
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.d.ts +8 -8
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.js +141 -155
- package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.d.ts +9 -0
- package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.js +35 -0
- package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.d.ts +6 -18
- package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.js +45 -220
- package/dist_ts/integrations/nanoleaf/nanoleaf.types.d.ts +33 -147
- package/dist_ts/integrations/nanoleaf/nanoleaf.validation.d.ts +6 -0
- package/dist_ts/integrations/nanoleaf/nanoleaf.validation.js +82 -0
- package/dist_ts/integrations/onkyo/onkyo.classes.client.d.ts +15 -20
- package/dist_ts/integrations/onkyo/onkyo.classes.client.js +161 -404
- package/dist_ts/integrations/onkyo/onkyo.classes.configflow.d.ts +9 -4
- package/dist_ts/integrations/onkyo/onkyo.classes.configflow.js +51 -6
- package/dist_ts/integrations/onkyo/onkyo.classes.integration.d.ts +22 -6
- package/dist_ts/integrations/onkyo/onkyo.classes.integration.js +144 -11
- package/dist_ts/integrations/onkyo/onkyo.discovery.d.ts +6 -1
- package/dist_ts/integrations/onkyo/onkyo.discovery.js +40 -4
- package/dist_ts/integrations/onkyo/onkyo.mapper.d.ts +7 -8
- package/dist_ts/integrations/onkyo/onkyo.mapper.js +45 -12
- package/dist_ts/integrations/onkyo/onkyo.types.d.ts +58 -8
- package/dist_ts/integrations/onkyo/onkyo.types.js +13 -102
- package/dist_ts/integrations/onkyo/onkyo.validation.d.ts +16 -0
- package/dist_ts/integrations/onkyo/onkyo.validation.js +77 -0
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.d.ts +25 -25
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.js +116 -360
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.d.ts +11 -3
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.js +76 -6
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.d.ts +26 -4
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.js +142 -9
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.d.ts +2 -1
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.js +31 -4
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.d.ts +9 -9
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.js +31 -149
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.d.ts +51 -11
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.js +22 -87
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.d.ts +6 -0
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.js +56 -0
- package/dist_ts/integrations/pioneer/pioneer.classes.client.d.ts +31 -16
- package/dist_ts/integrations/pioneer/pioneer.classes.client.js +167 -409
- package/dist_ts/integrations/pioneer/pioneer.classes.configflow.d.ts +10 -3
- package/dist_ts/integrations/pioneer/pioneer.classes.configflow.js +66 -6
- package/dist_ts/integrations/pioneer/pioneer.classes.integration.d.ts +13 -5
- package/dist_ts/integrations/pioneer/pioneer.classes.integration.js +239 -11
- package/dist_ts/integrations/pioneer/pioneer.discovery.d.ts +14 -1
- package/dist_ts/integrations/pioneer/pioneer.discovery.js +51 -4
- package/dist_ts/integrations/pioneer/pioneer.mapper.d.ts +14 -8
- package/dist_ts/integrations/pioneer/pioneer.mapper.js +54 -12
- package/dist_ts/integrations/pioneer/pioneer.types.d.ts +79 -12
- package/dist_ts/integrations/pioneer/pioneer.types.js +12 -76
- package/dist_ts/integrations/pioneer/pioneer.validation.d.ts +10 -0
- package/dist_ts/integrations/pioneer/pioneer.validation.js +85 -0
- package/dist_ts/integrations/soundtouch/soundtouch.classes.client.d.ts +13 -36
- package/dist_ts/integrations/soundtouch/soundtouch.classes.client.js +179 -502
- package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.d.ts +6 -1
- package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.js +50 -40
- package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.d.ts +14 -15
- package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.js +108 -128
- package/dist_ts/integrations/soundtouch/soundtouch.discovery.d.ts +2 -20
- package/dist_ts/integrations/soundtouch/soundtouch.discovery.js +23 -113
- package/dist_ts/integrations/soundtouch/soundtouch.mapper.d.ts +3 -12
- package/dist_ts/integrations/soundtouch/soundtouch.mapper.js +35 -189
- package/dist_ts/integrations/soundtouch/soundtouch.types.d.ts +57 -142
- package/dist_ts/integrations/soundtouch/soundtouch.types.js +18 -3
- package/dist_ts/integrations/soundtouch/soundtouch.validation.d.ts +22 -0
- package/dist_ts/integrations/soundtouch/soundtouch.validation.js +65 -0
- package/dist_ts/integrations/wiz/index.d.ts +1 -0
- package/dist_ts/integrations/wiz/index.js +2 -1
- package/dist_ts/integrations/wiz/wiz.classes.client.d.ts +14 -28
- package/dist_ts/integrations/wiz/wiz.classes.client.js +93 -229
- package/dist_ts/integrations/wiz/wiz.classes.configflow.d.ts +6 -4
- package/dist_ts/integrations/wiz/wiz.classes.configflow.js +38 -67
- package/dist_ts/integrations/wiz/wiz.classes.integration.d.ts +10 -21
- package/dist_ts/integrations/wiz/wiz.classes.integration.js +204 -44
- package/dist_ts/integrations/wiz/wiz.discovery.d.ts +10 -31
- package/dist_ts/integrations/wiz/wiz.discovery.js +48 -249
- package/dist_ts/integrations/wiz/wiz.mapper.d.ts +7 -51
- package/dist_ts/integrations/wiz/wiz.mapper.js +82 -668
- package/dist_ts/integrations/wiz/wiz.types.d.ts +34 -208
- package/dist_ts/integrations/wiz/wiz.validation.d.ts +8 -0
- package/dist_ts/integrations/wiz/wiz.validation.js +72 -0
- package/dist_ts/integrations/yamaha/index.d.ts +1 -0
- package/dist_ts/integrations/yamaha/index.js +2 -1
- package/dist_ts/integrations/yamaha/yamaha.classes.client.d.ts +30 -4
- package/dist_ts/integrations/yamaha/yamaha.classes.client.js +162 -6
- package/dist_ts/integrations/yamaha/yamaha.classes.configflow.d.ts +10 -3
- package/dist_ts/integrations/yamaha/yamaha.classes.configflow.js +106 -6
- package/dist_ts/integrations/yamaha/yamaha.classes.integration.d.ts +22 -4
- package/dist_ts/integrations/yamaha/yamaha.classes.integration.js +243 -8
- package/dist_ts/integrations/yamaha/yamaha.discovery.d.ts +13 -1
- package/dist_ts/integrations/yamaha/yamaha.discovery.js +57 -4
- package/dist_ts/integrations/yamaha/yamaha.mapper.d.ts +16 -8
- package/dist_ts/integrations/yamaha/yamaha.mapper.js +58 -12
- package/dist_ts/integrations/yamaha/yamaha.types.d.ts +73 -6
- package/dist_ts/integrations/yamaha/yamaha.types.js +8 -94
- package/dist_ts/integrations/yamaha/yamaha.validation.d.ts +12 -0
- package/dist_ts/integrations/yamaha/yamaha.validation.js +89 -0
- package/package.json +3 -3
- package/readme.md +514 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/classes.configstore.ts +84 -27
- package/ts/core/classes.nativehomeadmission.ts +96 -0
- package/ts/core/classes.nativeintegrationowner.ts +297 -0
- package/ts/core/index.ts +2 -0
- package/ts/core/types.ts +16 -0
- package/ts/integrations/braviatv/braviatv.classes.client.ts +245 -709
- package/ts/integrations/braviatv/braviatv.classes.configflow.ts +47 -76
- package/ts/integrations/braviatv/braviatv.classes.integration.ts +167 -147
- package/ts/integrations/braviatv/braviatv.discovery.ts +11 -10
- package/ts/integrations/braviatv/braviatv.mapper.ts +39 -142
- package/ts/integrations/braviatv/braviatv.types.ts +53 -173
- package/ts/integrations/braviatv/braviatv.validation.ts +68 -0
- package/ts/integrations/broadlink/broadlink.actions.ts +31 -0
- package/ts/integrations/broadlink/broadlink.classes.client.ts +170 -144
- package/ts/integrations/broadlink/broadlink.classes.configflow.ts +59 -89
- package/ts/integrations/broadlink/broadlink.classes.integration.ts +110 -64
- package/ts/integrations/broadlink/broadlink.mapper.ts +5 -4
- package/ts/integrations/broadlink/broadlink.selected.mapper.ts +46 -0
- package/ts/integrations/broadlink/broadlink.types.ts +48 -8
- package/ts/integrations/broadlink/broadlink.validation.ts +66 -0
- package/ts/integrations/daikin/daikin.classes.client.ts +52 -661
- package/ts/integrations/daikin/daikin.classes.configflow.ts +72 -152
- package/ts/integrations/daikin/daikin.classes.integration.ts +166 -71
- package/ts/integrations/daikin/daikin.discovery.ts +94 -346
- package/ts/integrations/daikin/daikin.mapper.ts +83 -166
- package/ts/integrations/daikin/daikin.types.ts +27 -48
- package/ts/integrations/daikin/daikin.validation.ts +51 -0
- package/ts/integrations/daikin/readme.md +83 -0
- package/ts/integrations/denonavr/denonavr.classes.client.ts +132 -421
- package/ts/integrations/denonavr/denonavr.classes.configflow.ts +44 -37
- package/ts/integrations/denonavr/denonavr.classes.integration.ts +171 -117
- package/ts/integrations/denonavr/denonavr.discovery.ts +67 -220
- package/ts/integrations/denonavr/denonavr.mapper.ts +36 -182
- package/ts/integrations/denonavr/denonavr.types.ts +48 -111
- package/ts/integrations/denonavr/denonavr.validation.ts +87 -0
- package/ts/integrations/kodi/kodi.classes.client.ts +72 -352
- package/ts/integrations/kodi/kodi.classes.configflow.ts +52 -55
- package/ts/integrations/kodi/kodi.classes.integration.ts +97 -178
- package/ts/integrations/kodi/kodi.discovery.ts +49 -28
- package/ts/integrations/kodi/kodi.mapper.ts +52 -10
- package/ts/integrations/kodi/kodi.types.ts +33 -58
- package/ts/integrations/kodi/kodi.validation.ts +60 -0
- package/ts/integrations/modbus/modbus.classes.client.ts +100 -842
- package/ts/integrations/modbus/modbus.classes.configflow.ts +70 -41
- package/ts/integrations/modbus/modbus.classes.integration.ts +115 -60
- package/ts/integrations/modbus/modbus.discovery.ts +38 -106
- package/ts/integrations/modbus/modbus.mapper.ts +64 -467
- package/ts/integrations/modbus/modbus.types.ts +64 -381
- package/ts/integrations/modbus/modbus.validation.ts +119 -0
- package/ts/integrations/nanoleaf/nanoleaf.classes.client.ts +115 -249
- package/ts/integrations/nanoleaf/nanoleaf.classes.configflow.ts +90 -19
- package/ts/integrations/nanoleaf/nanoleaf.classes.integration.ts +130 -181
- package/ts/integrations/nanoleaf/nanoleaf.credentials.ts +39 -0
- package/ts/integrations/nanoleaf/nanoleaf.mapper.ts +47 -260
- package/ts/integrations/nanoleaf/nanoleaf.types.ts +29 -147
- package/ts/integrations/nanoleaf/nanoleaf.validation.ts +77 -0
- package/ts/integrations/onkyo/onkyo.classes.client.ts +148 -457
- package/ts/integrations/onkyo/onkyo.classes.configflow.ts +52 -6
- package/ts/integrations/onkyo/onkyo.classes.integration.ts +121 -12
- package/ts/integrations/onkyo/onkyo.discovery.ts +41 -3
- package/ts/integrations/onkyo/onkyo.mapper.ts +46 -19
- package/ts/integrations/onkyo/onkyo.types.ts +55 -110
- package/ts/integrations/onkyo/onkyo.validation.ts +85 -0
- package/ts/integrations/onkyo/readme.md +126 -0
- package/ts/integrations/panasonic_viera/panasonic_viera.classes.client.ts +101 -398
- package/ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.ts +69 -5
- package/ts/integrations/panasonic_viera/panasonic_viera.classes.integration.ts +141 -9
- package/ts/integrations/panasonic_viera/panasonic_viera.discovery.ts +32 -3
- package/ts/integrations/panasonic_viera/panasonic_viera.mapper.ts +34 -161
- package/ts/integrations/panasonic_viera/panasonic_viera.types.ts +52 -96
- package/ts/integrations/panasonic_viera/panasonic_viera.validation.ts +56 -0
- package/ts/integrations/pioneer/pioneer.classes.client.ts +132 -428
- package/ts/integrations/pioneer/pioneer.classes.configflow.ts +67 -5
- package/ts/integrations/pioneer/pioneer.classes.integration.ts +225 -11
- package/ts/integrations/pioneer/pioneer.discovery.ts +45 -3
- package/ts/integrations/pioneer/pioneer.mapper.ts +57 -13
- package/ts/integrations/pioneer/pioneer.types.ts +87 -85
- package/ts/integrations/pioneer/pioneer.validation.ts +84 -0
- package/ts/integrations/soundtouch/soundtouch.classes.client.ts +152 -571
- package/ts/integrations/soundtouch/soundtouch.classes.configflow.ts +47 -42
- package/ts/integrations/soundtouch/soundtouch.classes.integration.ts +95 -150
- package/ts/integrations/soundtouch/soundtouch.discovery.ts +21 -133
- package/ts/integrations/soundtouch/soundtouch.mapper.ts +36 -207
- package/ts/integrations/soundtouch/soundtouch.types.ts +50 -195
- package/ts/integrations/soundtouch/soundtouch.validation.ts +60 -0
- package/ts/integrations/wiz/index.ts +1 -0
- package/ts/integrations/wiz/wiz.classes.client.ts +84 -254
- package/ts/integrations/wiz/wiz.classes.configflow.ts +39 -70
- package/ts/integrations/wiz/wiz.classes.integration.ts +189 -45
- package/ts/integrations/wiz/wiz.discovery.ts +48 -291
- package/ts/integrations/wiz/wiz.mapper.ts +81 -754
- package/ts/integrations/wiz/wiz.types.ts +24 -224
- package/ts/integrations/wiz/wiz.validation.ts +73 -0
- package/ts/integrations/yamaha/index.ts +1 -0
- package/ts/integrations/yamaha/yamaha.classes.client.ts +150 -6
- package/ts/integrations/yamaha/yamaha.classes.configflow.ts +100 -5
- package/ts/integrations/yamaha/yamaha.classes.integration.ts +236 -8
- package/ts/integrations/yamaha/yamaha.discovery.ts +52 -3
- package/ts/integrations/yamaha/yamaha.mapper.ts +65 -13
- package/ts/integrations/yamaha/yamaha.types.ts +77 -97
- package/ts/integrations/yamaha/yamaha.validation.ts +86 -0
|
@@ -1,380 +1,128 @@
|
|
|
1
1
|
import { DiscoveryDescriptor } from '../../core/classes.discoverydescriptor.js';
|
|
2
|
-
import type {
|
|
3
|
-
IDiscoveryCandidate,
|
|
4
|
-
IDiscoveryContext,
|
|
5
|
-
IDiscoveryMatch,
|
|
6
|
-
IDiscoveryMatcher,
|
|
7
|
-
IDiscoveryProbe,
|
|
8
|
-
IDiscoveryProbeResult,
|
|
9
|
-
IDiscoveryValidator,
|
|
10
|
-
} from '../../core/types.js';
|
|
2
|
+
import type { IDiscoveryCandidate, IDiscoveryMatch, IDiscoveryMatcher, IDiscoveryValidator } from '../../core/types.js';
|
|
11
3
|
import { DaikinMapper } from './daikin.mapper.js';
|
|
12
|
-
import type { IDaikinHttpCandidateRecord, IDaikinManualEntry, IDaikinMdnsRecord,
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const closeSocket = () => {
|
|
41
|
-
clearTimeout(timer);
|
|
42
|
-
try {
|
|
43
|
-
socket.close();
|
|
44
|
-
} catch {
|
|
45
|
-
// Discovery sockets may already be closed after timeout or OS errors.
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
socket.on('message', async (dataArg, remoteArg) => {
|
|
50
|
-
const match = await matcher.matches({ host: remoteArg.address, port: remoteArg.port, data: dataArg.toString('utf8') });
|
|
51
|
-
if (match.matched && match.candidate && !candidates.some((candidateArg) => candidateArg.id === match.candidate?.id || candidateArg.host === match.candidate?.host)) {
|
|
52
|
-
candidates.push(match.candidate);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
socket.on('error', () => {
|
|
56
|
-
closeSocket();
|
|
57
|
-
resolve(candidates);
|
|
58
|
-
});
|
|
59
|
-
socket.bind(daikinUdpSourcePort, () => {
|
|
60
|
-
socket.setBroadcast(true);
|
|
61
|
-
socket.send(message, daikinUdpDiscoveryPort, '255.255.255.255');
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
}
|
|
4
|
+
import type { IDaikinHttpCandidateRecord, IDaikinManualEntry, IDaikinMdnsRecord, IDaikinUdpDiscoveryRecord } from './daikin.types.js';
|
|
5
|
+
import { daikinDisplayName, daikinDomain, daikinZeroconfType } from './daikin.types.js';
|
|
6
|
+
import { daikinObject } from './daikin.validation.js';
|
|
7
|
+
|
|
8
|
+
const hint = (valueArg: unknown, maximumArg = 256): string | undefined =>
|
|
9
|
+
typeof valueArg === 'string' && valueArg.length > 0 && valueArg.length <= maximumArg && !/[\p{Cc}\p{Cs}]/u.test(valueArg) ? valueArg : undefined;
|
|
10
|
+
const hints = (valueArg: unknown): Record<string, unknown> => {
|
|
11
|
+
if (valueArg === undefined) return {};
|
|
12
|
+
const value = daikinObject(valueArg, 'Daikin discovery hints');
|
|
13
|
+
if (Object.keys(value).length > 64) throw new TypeError('Daikin discovery hints exceed their limit.');
|
|
14
|
+
return value;
|
|
15
|
+
};
|
|
16
|
+
const noMatch = (): IDiscoveryMatch => ({ matched: false, confidence: 'low', reason: 'No bounded Daikin endpoint hints were observed.' });
|
|
17
|
+
const result = (sourceArg: IDiscoveryCandidate['source'], hostArg: unknown, portArg: unknown, macArg: unknown,
|
|
18
|
+
nameArg: unknown, modelArg: unknown, protocolArg: string): IDiscoveryMatch => {
|
|
19
|
+
const host = hint(hostArg, 64);
|
|
20
|
+
if (!host) return noMatch();
|
|
21
|
+
if (portArg !== undefined && (typeof portArg !== 'number' || !Number.isSafeInteger(portArg) || portArg < 1 || portArg > 65535)) return noMatch();
|
|
22
|
+
const mac = DaikinMapper.normalizeMac(hint(macArg, 32));
|
|
23
|
+
const port = typeof portArg === 'number' ? portArg : 80;
|
|
24
|
+
return { matched: true, confidence: 'medium', reason: 'Passive Daikin endpoint hints require independent selected BRP069 verification.',
|
|
25
|
+
normalizedDeviceId: mac ?? `${host}:${port}`, candidate: {
|
|
26
|
+
source: sourceArg, integrationDomain: daikinDomain, id: mac ?? `${host}:${port}`, host, port,
|
|
27
|
+
name: hint(nameArg) ?? daikinDisplayName, manufacturer: 'Daikin', model: hint(modelArg), macAddress: mac,
|
|
28
|
+
metadata: { daikin: true, discoveryProtocol: protocolArg },
|
|
29
|
+
} };
|
|
30
|
+
};
|
|
66
31
|
|
|
67
32
|
export class DaikinZeroconfMatcher implements IDiscoveryMatcher<IDaikinMdnsRecord> {
|
|
68
|
-
public id = 'daikin-zeroconf-match';
|
|
69
|
-
public source = 'mdns' as const;
|
|
70
|
-
public description = 'Recognize Daikin _dkapi._tcp.local zeroconf advertisements from the Home Assistant manifest.';
|
|
71
|
-
|
|
33
|
+
public readonly id = 'daikin-zeroconf-match';
|
|
34
|
+
public readonly source = 'mdns' as const;
|
|
72
35
|
public async matches(recordArg: IDaikinMdnsRecord): Promise<IDiscoveryMatch> {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
matched: true,
|
|
84
|
-
confidence: host && mac ? 'certain' : host ? 'high' : 'medium',
|
|
85
|
-
reason: 'mDNS service matches _dkapi._tcp.local.',
|
|
86
|
-
normalizedDeviceId: mac || recordArg.name || host,
|
|
87
|
-
candidate: {
|
|
88
|
-
source: 'mdns',
|
|
89
|
-
integrationDomain: daikinDomain,
|
|
90
|
-
id: mac || recordArg.name || host,
|
|
91
|
-
host,
|
|
92
|
-
port: recordArg.port || daikinDefaultHttpPort,
|
|
93
|
-
name,
|
|
94
|
-
manufacturer: 'Daikin',
|
|
95
|
-
model: txt.model || txt.type || 'Daikin AC',
|
|
96
|
-
macAddress: mac,
|
|
97
|
-
metadata: {
|
|
98
|
-
...recordArg.metadata,
|
|
99
|
-
daikin: true,
|
|
100
|
-
discoveryProtocol: 'zeroconf',
|
|
101
|
-
mdnsType: type,
|
|
102
|
-
mdnsName: recordArg.name,
|
|
103
|
-
txt,
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
};
|
|
36
|
+
try {
|
|
37
|
+
const record = hints(recordArg);
|
|
38
|
+
if (hint(record.type ?? record.serviceType)?.replace(/\.$/, '').toLowerCase() !== daikinZeroconfType.replace(/\.$/, '')) return noMatch();
|
|
39
|
+
const txt = { ...hints(record.txt), ...hints(record.properties) };
|
|
40
|
+
const address = firstAddress(record.addresses);
|
|
41
|
+
return result('mdns', record.host ?? record.hostname ?? address, record.port, txt.mac ?? txt.macaddress,
|
|
42
|
+
txt.name ?? hint(record.name)?.replace(/\._.*$/, ''), txt.model, 'zeroconf');
|
|
43
|
+
} catch { return noMatch(); }
|
|
107
44
|
}
|
|
108
45
|
}
|
|
109
46
|
|
|
110
47
|
export class DaikinUdpMatcher implements IDiscoveryMatcher<IDaikinUdpDiscoveryRecord> {
|
|
111
|
-
public id = 'daikin-udp-match';
|
|
112
|
-
public source = 'custom' as const;
|
|
113
|
-
public description = 'Recognize pydaikin DAIKIN_UDP/basic_info discovery responses.';
|
|
114
|
-
|
|
48
|
+
public readonly id = 'daikin-udp-match';
|
|
49
|
+
public readonly source = 'custom' as const;
|
|
115
50
|
public async matches(recordArg: IDaikinUdpDiscoveryRecord): Promise<IDiscoveryMatch> {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
matched: true,
|
|
126
|
-
confidence: host && mac ? 'certain' : host ? 'high' : 'medium',
|
|
127
|
-
reason: mac ? 'UDP response contains a Daikin MAC address.' : 'UDP response contains Daikin adapter metadata.',
|
|
128
|
-
normalizedDeviceId: mac || host,
|
|
129
|
-
candidate: {
|
|
130
|
-
source: 'custom',
|
|
131
|
-
integrationDomain: daikinDomain,
|
|
132
|
-
id: mac || host,
|
|
133
|
-
host,
|
|
134
|
-
port: daikinDefaultHttpPort,
|
|
135
|
-
name,
|
|
136
|
-
manufacturer: 'Daikin',
|
|
137
|
-
model: values.model || values.type || 'Daikin AC',
|
|
138
|
-
macAddress: mac,
|
|
139
|
-
metadata: {
|
|
140
|
-
...recordArg.metadata,
|
|
141
|
-
daikin: true,
|
|
142
|
-
discoveryProtocol: 'udp',
|
|
143
|
-
discoveryPort: recordArg.port,
|
|
144
|
-
values,
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
private values(recordArg: IDaikinUdpDiscoveryRecord): IDaikinValueMap {
|
|
151
|
-
const raw = recordArg.values || recordArg.response || recordArg.data || {};
|
|
152
|
-
if (typeof raw === 'string') {
|
|
153
|
-
try {
|
|
154
|
-
return DaikinMapper.parseKeyValueResponse(raw);
|
|
155
|
-
} catch {
|
|
156
|
-
return {};
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return raw;
|
|
51
|
+
try {
|
|
52
|
+
const record = hints(recordArg);
|
|
53
|
+
const raw = record.values ?? record.response ?? record.data;
|
|
54
|
+
const values = typeof raw === 'string' ? discoveryBody(raw) : hints(raw);
|
|
55
|
+
if (values.type !== 'aircon' || !DaikinMapper.normalizeMac(hint(values.mac, 32))) return noMatch();
|
|
56
|
+
return result('custom', record.host ?? record.address ?? record.ip, 80, values.mac, values.name, values.model, 'received-udp');
|
|
57
|
+
} catch { return noMatch(); }
|
|
160
58
|
}
|
|
161
59
|
}
|
|
162
60
|
|
|
163
61
|
export class DaikinHttpMatcher implements IDiscoveryMatcher<IDaikinHttpCandidateRecord> {
|
|
164
|
-
public id = 'daikin-http-match';
|
|
165
|
-
public source = 'http' as const;
|
|
166
|
-
public description = 'Recognize local HTTP candidates that look like Daikin common/aircon, SkyFi, or dsiot endpoints.';
|
|
167
|
-
|
|
62
|
+
public readonly id = 'daikin-http-match';
|
|
63
|
+
public readonly source = 'http' as const;
|
|
168
64
|
public async matches(recordArg: IDaikinHttpCandidateRecord): Promise<IDiscoveryMatch> {
|
|
169
|
-
const parsed = parseEndpoint(recordArg.url || recordArg.location);
|
|
170
|
-
const headers = normalizeKeys(recordArg.headers || {});
|
|
171
|
-
const path = recordArg.path || parsed?.path || '';
|
|
172
|
-
const body = recordArg.body || recordArg.responseText || '';
|
|
173
|
-
const text = [recordArg.url, recordArg.location, path, body, headers.server, recordArg.name, recordArg.manufacturer, recordArg.model].filter(Boolean).join(' ').toLowerCase();
|
|
174
|
-
const values = this.parseBody(body);
|
|
175
|
-
const mac = DaikinMapper.normalizeMac(values.mac);
|
|
176
|
-
const matched = Boolean(recordArg.metadata?.daikin)
|
|
177
|
-
|| path.includes('/common/basic_info')
|
|
178
|
-
|| path.includes('/aircon/')
|
|
179
|
-
|| path.includes('/skyfi/')
|
|
180
|
-
|| path.includes('/dsiot/')
|
|
181
|
-
|| text.includes('daikin')
|
|
182
|
-
|| Boolean(mac && values.type === 'aircon');
|
|
183
|
-
if (!matched) {
|
|
184
|
-
return { matched: false, confidence: 'low', reason: 'HTTP candidate does not look like a Daikin local API.' };
|
|
185
|
-
}
|
|
186
|
-
const host = recordArg.host || parsed?.host;
|
|
187
|
-
const port = recordArg.port || parsed?.port || daikinDefaultHttpPort;
|
|
188
|
-
return {
|
|
189
|
-
matched: true,
|
|
190
|
-
confidence: host && (mac || path.includes('/common/basic_info')) ? 'high' : host ? 'medium' : 'low',
|
|
191
|
-
reason: 'HTTP candidate has Daikin API path, body, or metadata hints.',
|
|
192
|
-
normalizedDeviceId: mac || (host ? `${host}:${port}` : undefined),
|
|
193
|
-
candidate: {
|
|
194
|
-
source: 'http',
|
|
195
|
-
integrationDomain: daikinDomain,
|
|
196
|
-
id: mac || (host ? `${host}:${port}` : undefined),
|
|
197
|
-
host,
|
|
198
|
-
port,
|
|
199
|
-
name: safeDecode(values.name) || recordArg.name || daikinDisplayName,
|
|
200
|
-
manufacturer: recordArg.manufacturer || 'Daikin',
|
|
201
|
-
model: recordArg.model || values.model || 'Daikin AC',
|
|
202
|
-
macAddress: mac,
|
|
203
|
-
metadata: {
|
|
204
|
-
...recordArg.metadata,
|
|
205
|
-
daikin: true,
|
|
206
|
-
url: recordArg.url || recordArg.location,
|
|
207
|
-
ssl: recordArg.ssl ?? parsed?.ssl ?? false,
|
|
208
|
-
values: Object.keys(values).length ? values : undefined,
|
|
209
|
-
headers,
|
|
210
|
-
},
|
|
211
|
-
},
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
private parseBody(valueArg: string): IDaikinValueMap {
|
|
216
|
-
if (!valueArg.trim()) {
|
|
217
|
-
return {};
|
|
218
|
-
}
|
|
219
65
|
try {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
66
|
+
const record = hints(recordArg);
|
|
67
|
+
const location = hint(record.url ?? record.location, 2048);
|
|
68
|
+
const url = location === undefined ? undefined : new URL(location);
|
|
69
|
+
if (url && (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash)) return noMatch();
|
|
70
|
+
const path = hint(record.path, 256) ?? url?.pathname;
|
|
71
|
+
const body = record.body ?? record.responseText;
|
|
72
|
+
const values = body === undefined ? {} : typeof body === 'string' ? discoveryBody(body) : {};
|
|
73
|
+
if (!['/common/basic_info', '/aircon/get_control_info', '/aircon/get_model_info'].includes(path ?? '') && values.type !== 'aircon') return noMatch();
|
|
74
|
+
return result('http', record.host ?? url?.hostname, record.port ?? (url?.port ? Number(url.port) : undefined),
|
|
75
|
+
values.mac, record.name ?? values.name, record.model ?? values.model, 'received-http');
|
|
76
|
+
} catch { return noMatch(); }
|
|
224
77
|
}
|
|
225
78
|
}
|
|
226
79
|
|
|
227
80
|
export class DaikinManualMatcher implements IDiscoveryMatcher<IDaikinManualEntry> {
|
|
228
|
-
public id = 'daikin-manual-match';
|
|
229
|
-
public source = 'manual' as const;
|
|
230
|
-
public description = 'Recognize manual Daikin host, API key/password, snapshot, client, and raw-data setup entries.';
|
|
231
|
-
|
|
81
|
+
public readonly id = 'daikin-manual-match';
|
|
82
|
+
public readonly source = 'manual' as const;
|
|
232
83
|
public async matches(inputArg: IDaikinManualEntry): Promise<IDiscoveryMatch> {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (!matched) {
|
|
241
|
-
return { matched: false, confidence: 'low', reason: 'Manual entry does not contain Daikin setup hints.' };
|
|
242
|
-
}
|
|
243
|
-
const host = parsed?.host || (inputArg.url ? undefined : inputArg.host) || snapshot?.device.host;
|
|
244
|
-
const port = inputArg.port || parsed?.port || snapshot?.device.port || (inputArg.apiVariant === 'skyfi' || inputArg.password ? 2000 : daikinDefaultHttpPort);
|
|
245
|
-
const id = inputArg.id || inputArg.uniqueId || snapshot?.device.id || snapshot?.device.macAddress || (host ? `${host}:${port}` : undefined);
|
|
246
|
-
return {
|
|
247
|
-
matched: true,
|
|
248
|
-
confidence: host || hasManualData ? 'high' : 'medium',
|
|
249
|
-
reason: 'Manual entry can start Daikin setup.',
|
|
250
|
-
normalizedDeviceId: id,
|
|
251
|
-
candidate: {
|
|
252
|
-
source: 'manual',
|
|
253
|
-
integrationDomain: daikinDomain,
|
|
254
|
-
id,
|
|
255
|
-
host,
|
|
256
|
-
port,
|
|
257
|
-
name: inputArg.name || snapshot?.device.name || daikinDisplayName,
|
|
258
|
-
manufacturer: inputArg.manufacturer || snapshot?.device.manufacturer || 'Daikin',
|
|
259
|
-
model: inputArg.model || snapshot?.device.model,
|
|
260
|
-
macAddress: inputArg.macAddress || snapshot?.device.macAddress,
|
|
261
|
-
metadata: {
|
|
262
|
-
...metadata,
|
|
263
|
-
daikin: true,
|
|
264
|
-
discoveryProtocol: 'manual',
|
|
265
|
-
ssl: inputArg.ssl ?? inputArg.tls ?? parsed?.ssl ?? metadata.ssl,
|
|
266
|
-
apiVariant: inputArg.apiVariant || metadata.apiVariant,
|
|
267
|
-
apiKey: inputArg.apiKey || metadata.apiKey,
|
|
268
|
-
uuid: inputArg.uuid || metadata.uuid,
|
|
269
|
-
password: inputArg.password || metadata.password,
|
|
270
|
-
snapshot,
|
|
271
|
-
rawData,
|
|
272
|
-
values: inputArg.values || metadata.values,
|
|
273
|
-
client: inputArg.client || metadata.client,
|
|
274
|
-
commandExecutor: inputArg.commandExecutor || metadata.commandExecutor,
|
|
275
|
-
},
|
|
276
|
-
},
|
|
277
|
-
};
|
|
84
|
+
try {
|
|
85
|
+
const input = hints(inputArg);
|
|
86
|
+
const metadata = hints(input.metadata);
|
|
87
|
+
const vendor = [hint(input.name), hint(input.manufacturer), hint(input.model)].filter(Boolean).join(' ').toLowerCase();
|
|
88
|
+
if (metadata.daikin !== true && input.apiVariant !== 'brp069' && !vendor.includes('daikin')) return noMatch();
|
|
89
|
+
return result('manual', input.host, input.port, input.macAddress ?? metadata.expectedMac, input.name, input.model, 'manual');
|
|
90
|
+
} catch { return noMatch(); }
|
|
278
91
|
}
|
|
279
92
|
}
|
|
280
93
|
|
|
281
94
|
export class DaikinCandidateValidator implements IDiscoveryValidator {
|
|
282
|
-
public id = 'daikin-candidate-validator';
|
|
283
|
-
public description = 'Validate Daikin candidates from zeroconf, UDP, HTTP, and manual setup.';
|
|
284
|
-
|
|
95
|
+
public readonly id = 'daikin-candidate-validator';
|
|
285
96
|
public async validate(candidateArg: IDiscoveryCandidate): Promise<IDiscoveryMatch> {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const text = [candidateArg.integrationDomain, candidateArg.name, candidateArg.manufacturer, candidateArg.model, mdnsType].filter(Boolean).join(' ').toLowerCase();
|
|
292
|
-
const matched = candidateArg.integrationDomain === daikinDomain
|
|
293
|
-
|| metadata.daikin === true
|
|
294
|
-
|| text.includes('daikin')
|
|
295
|
-
|| mdnsType.includes('_dkapi')
|
|
296
|
-
|| discoveryProtocol === 'udp';
|
|
297
|
-
const hasUsableSource = Boolean(candidateArg.host || snapshot || rawData || metadata.values || metadata.client);
|
|
298
|
-
const normalizedDeviceId = DaikinMapper.normalizeMac(candidateArg.macAddress) || candidateArg.id || snapshot?.device.macAddress || (candidateArg.host ? `${candidateArg.host}:${candidateArg.port || daikinDefaultHttpPort}` : undefined);
|
|
299
|
-
if (!matched || !hasUsableSource) {
|
|
300
|
-
return {
|
|
301
|
-
matched: false,
|
|
302
|
-
confidence: matched ? 'medium' : 'low',
|
|
303
|
-
reason: matched ? 'Daikin candidate lacks a host, injected client, snapshot, or manual data.' : 'Candidate is not Daikin.',
|
|
304
|
-
normalizedDeviceId,
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
return {
|
|
308
|
-
matched: true,
|
|
309
|
-
confidence: candidateArg.host && normalizedDeviceId ? 'certain' : candidateArg.host ? 'high' : 'medium',
|
|
310
|
-
reason: 'Candidate has Daikin metadata and a usable local endpoint, client, snapshot, or manual data.',
|
|
311
|
-
normalizedDeviceId,
|
|
312
|
-
candidate: {
|
|
313
|
-
...candidateArg,
|
|
314
|
-
integrationDomain: daikinDomain,
|
|
315
|
-
port: candidateArg.port || daikinDefaultHttpPort,
|
|
316
|
-
manufacturer: candidateArg.manufacturer || 'Daikin',
|
|
317
|
-
},
|
|
318
|
-
};
|
|
97
|
+
try {
|
|
98
|
+
const candidate = hints(candidateArg);
|
|
99
|
+
if (candidate.integrationDomain !== daikinDomain) return noMatch();
|
|
100
|
+
return result(candidateArg.source, candidate.host, candidate.port, candidate.macAddress, candidate.name, candidate.model, 'validated-hint');
|
|
101
|
+
} catch { return noMatch(); }
|
|
319
102
|
}
|
|
320
103
|
}
|
|
321
104
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
.addMatcher(new DaikinZeroconfMatcher())
|
|
326
|
-
.addMatcher(new
|
|
327
|
-
.addMatcher(new DaikinHttpMatcher())
|
|
328
|
-
.addMatcher(new DaikinManualMatcher())
|
|
329
|
-
.addValidator(new DaikinCandidateValidator());
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
const normalizeMdnsType = (valueArg: string): string => valueArg.toLowerCase().replace(/\.$/, '');
|
|
105
|
+
/** Passive record matching only; setup independently validates the explicitly selected controller. */
|
|
106
|
+
export const createDaikinDiscoveryDescriptor = (): DiscoveryDescriptor =>
|
|
107
|
+
new DiscoveryDescriptor({ integrationDomain: daikinDomain, displayName: daikinDisplayName })
|
|
108
|
+
.addMatcher(new DaikinZeroconfMatcher()).addMatcher(new DaikinUdpMatcher())
|
|
109
|
+
.addMatcher(new DaikinHttpMatcher()).addMatcher(new DaikinManualMatcher()).addValidator(new DaikinCandidateValidator());
|
|
333
110
|
|
|
334
|
-
const
|
|
335
|
-
if (
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
return valueArg.replace(/\._.*$/u, '').replace(/\.local\.?$/i, '').trim() || undefined;
|
|
111
|
+
const discoveryBody = (bodyArg: string): Record<string, unknown> => {
|
|
112
|
+
if (bodyArg.length > 16384) throw new TypeError('Daikin discovery payload exceeds its limit.');
|
|
113
|
+
const parsed = DaikinMapper.parseKeyValueResponse(bodyArg);
|
|
114
|
+
return { type: hint(parsed.type), mac: hint(parsed.mac, 32), name: hint(parsed.name), model: hint(parsed.model) };
|
|
339
115
|
};
|
|
340
116
|
|
|
341
|
-
const
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
const normalizeKeys = (recordArg: Record<string, string | undefined>): Record<string, string | undefined> => {
|
|
354
|
-
const normalized: Record<string, string | undefined> = {};
|
|
355
|
-
for (const [key, value] of Object.entries(recordArg)) {
|
|
356
|
-
normalized[key.toLowerCase()] = value;
|
|
357
|
-
}
|
|
358
|
-
return normalized;
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
const stringValue = (valueArg: unknown): string | undefined => typeof valueArg === 'string' && valueArg.trim() ? valueArg.trim() : undefined;
|
|
362
|
-
|
|
363
|
-
const safeDecode = (valueArg: string | undefined): string | undefined => {
|
|
364
|
-
if (valueArg === undefined) {
|
|
365
|
-
return undefined;
|
|
366
|
-
}
|
|
367
|
-
try {
|
|
368
|
-
return decodeURIComponent(valueArg.replace(/\+/g, '%20'));
|
|
369
|
-
} catch {
|
|
370
|
-
return valueArg;
|
|
117
|
+
const firstAddress = (valueArg: unknown): unknown => {
|
|
118
|
+
if (valueArg === undefined) return undefined;
|
|
119
|
+
if (!Array.isArray(valueArg) || valueArg.length > 16) throw new TypeError('Daikin advertised addresses must be a bounded array.');
|
|
120
|
+
for (const key of Reflect.ownKeys(valueArg)) {
|
|
121
|
+
if (key === 'length') continue;
|
|
122
|
+
const descriptor = Object.getOwnPropertyDescriptor(valueArg, key);
|
|
123
|
+
if (typeof key !== 'string' || !/^(0|[1-9]\d*)$/.test(key) || !descriptor || !('value' in descriptor) || !descriptor.enumerable) {
|
|
124
|
+
throw new TypeError('Daikin advertised addresses must contain own data fields.');
|
|
125
|
+
}
|
|
371
126
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
const snapshotValue = (valueArg: unknown): IDaikinSnapshot | undefined => {
|
|
375
|
-
return valueArg && typeof valueArg === 'object' && 'device' in valueArg && 'climate' in valueArg ? valueArg as IDaikinSnapshot : undefined;
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
const rawDataValue = (valueArg: unknown): Partial<IDaikinRawData> | undefined => {
|
|
379
|
-
return valueArg && typeof valueArg === 'object' && !Array.isArray(valueArg) ? valueArg as Partial<IDaikinRawData> : undefined;
|
|
127
|
+
return Object.getOwnPropertyDescriptor(valueArg, '0')?.value;
|
|
380
128
|
};
|