@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,8 +1,8 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
|
-
import type { IIntegrationEntity, IServiceCallRequest, TEntityPlatform } from '../../core/types.js';
|
|
2
|
+
import type { IDeviceFeatureWriteRequest, IIntegrationEntity, IServiceCallRequest, TEntityPlatform } from '../../core/types.js';
|
|
3
3
|
import type {
|
|
4
|
-
IDaikinCommandRequest,
|
|
5
4
|
IDaikinConfig,
|
|
5
|
+
IDaikinNativeConfig,
|
|
6
6
|
IDaikinDeviceSnapshotInfo,
|
|
7
7
|
IDaikinEnergySnapshot,
|
|
8
8
|
IDaikinRawData,
|
|
@@ -10,11 +10,11 @@ import type {
|
|
|
10
10
|
IDaikinValueMap,
|
|
11
11
|
IDaikinZoneSnapshot,
|
|
12
12
|
TDaikinApiVariant,
|
|
13
|
-
TDaikinHvacAction,
|
|
14
13
|
TDaikinHvacMode,
|
|
15
14
|
TDaikinPresetMode,
|
|
16
15
|
TDaikinSnapshotSource,
|
|
17
16
|
} from './daikin.types.js';
|
|
17
|
+
import { daikinKeys, daikinObject } from './daikin.validation.js';
|
|
18
18
|
import { daikinDefaultHttpPort, daikinDisplayName, daikinDomain, daikinSkyFiPort } from './daikin.types.js';
|
|
19
19
|
|
|
20
20
|
interface IDaikinSnapshotOptions {
|
|
@@ -201,6 +201,61 @@ const sensorDefinitions: Array<{ key: string; name: string; unit?: string; devic
|
|
|
201
201
|
];
|
|
202
202
|
|
|
203
203
|
export class DaikinMapper {
|
|
204
|
+
/** Maps only fields supplied by a fresh public-protocol observation. */
|
|
205
|
+
public static fromState(configArg: Readonly<IDaikinNativeConfig>, stateArg: plugins.ecobridgeDeviceManager.IDaikinState): IDaikinSnapshot {
|
|
206
|
+
return {
|
|
207
|
+
device: { id: stateArg.mac, homeId: configArg.homeId, name: configArg.name ?? `Daikin ${stateArg.mac}`,
|
|
208
|
+
manufacturer: 'Daikin', model: stateArg.model, firmware: stateArg.firmwareVersion,
|
|
209
|
+
host: configArg.host, port: configArg.port ?? 80, ssl: false, macAddress: this.normalizeMac(stateArg.mac), apiVariant: 'brp069' },
|
|
210
|
+
climate: { power: stateArg.power, hvacMode: stateArg.power ? stateArg.mode === 'fan' ? 'fan_only' : stateArg.mode : 'off',
|
|
211
|
+
hvacAction: stateArg.power ? 'unknown' : 'off', rawDaikinMode: stateArg.modeCode, rawPower: stateArg.power ? '1' : '0',
|
|
212
|
+
targetTemperature: stateArg.targetTemperatureCelsius,
|
|
213
|
+
targetHumidity: /^\d+$/.test(stateArg.targetHumidity) ? Number(stateArg.targetHumidity) : undefined,
|
|
214
|
+
fanMode: stateArg.fanRate, swingMode: stateArg.fanDirection, presetMode: 'none',
|
|
215
|
+
fanModes: [], swingModes: [], presetModes: [], temperatureUnit: 'C', targetTemperatureStep: 1 },
|
|
216
|
+
energy: {}, zones: [], capabilities: { localControl: stateArg.capabilities.power,
|
|
217
|
+
fanRate: stateArg.fanRate !== undefined, swingMode: stateArg.fanDirection !== undefined,
|
|
218
|
+
awayMode: false, advancedModes: false, streamer: false, outsideTemperature: false, humidity: false,
|
|
219
|
+
compressorFrequency: false, energyConsumption: false, zones: false, zoneTemperatureControl: false },
|
|
220
|
+
online: true, updatedAt: stateArg.observedAt, source: 'http', nativeState: stateArg,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public static controlForService(snapshotArg: IDaikinSnapshot, requestArg: IServiceCallRequest): plugins.ecobridgeDeviceManager.IDaikinControl | 'snapshot' {
|
|
225
|
+
const request = daikinObject(requestArg, 'Daikin service request');
|
|
226
|
+
daikinKeys(request, ['domain', 'service', 'target', 'data']);
|
|
227
|
+
const target = daikinObject(request.target, 'Daikin service target');
|
|
228
|
+
daikinKeys(target, ['entityId', 'deviceId']);
|
|
229
|
+
const data = request.data === undefined ? {} : daikinObject(request.data, 'Daikin service data');
|
|
230
|
+
const entities = this.toEntities(snapshotArg);
|
|
231
|
+
const selected = target.entityId === undefined ? undefined : entities.find((entityArg) => entityArg.id === target.entityId);
|
|
232
|
+
if ((!selected && target.entityId !== undefined) || (target.deviceId !== undefined && target.deviceId !== this.deviceId(snapshotArg))
|
|
233
|
+
|| (target.entityId === undefined && target.deviceId === undefined)) throw new TypeError('Daikin service requires an exact owned entity or device target.');
|
|
234
|
+
if (request.domain === 'daikin' && request.service === 'refresh') { daikinKeys(data, []); return 'snapshot'; }
|
|
235
|
+
if (request.domain !== 'climate' && request.domain !== 'switch') throw new TypeError('Unsupported Daikin service domain.');
|
|
236
|
+
if (selected && (selected.platform !== request.domain || !['climate', 'power'].includes(String(selected.attributes?.key)))) throw new TypeError('Daikin service does not match the selected entity.');
|
|
237
|
+
if (request.service === 'turn_on' || request.service === 'turn_off') { daikinKeys(data, []); return { power: request.service === 'turn_on' }; }
|
|
238
|
+
if (request.domain === 'climate' && request.service === 'set_temperature') {
|
|
239
|
+
daikinKeys(data, ['temperature']);
|
|
240
|
+
if (typeof data.temperature !== 'number' || !Number.isSafeInteger(data.temperature)) throw new TypeError('Daikin target must be an explicit integer Celsius number.');
|
|
241
|
+
return { targetTemperatureCelsius: data.temperature };
|
|
242
|
+
}
|
|
243
|
+
throw new TypeError('Unsupported Daikin service.');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
public static controlForFeature(snapshotArg: IDaikinSnapshot, requestArg: IDeviceFeatureWriteRequest): plugins.ecobridgeDeviceManager.IDaikinControl {
|
|
247
|
+
const request = daikinObject(requestArg, 'Daikin feature request');
|
|
248
|
+
daikinKeys(request, ['device', 'feature', 'value']);
|
|
249
|
+
const device = daikinObject(request.device, 'Daikin device target');
|
|
250
|
+
const feature = daikinObject(request.feature, 'Daikin feature target');
|
|
251
|
+
daikinKeys(feature, ['id', 'capability', 'name', 'readable', 'writable', 'unit']);
|
|
252
|
+
if (device.id !== this.deviceId(snapshotArg) || device.integrationDomain !== daikinDomain) throw new TypeError('Daikin feature requires an exact owned device.');
|
|
253
|
+
if (feature.id === 'power' && feature.capability === 'switch' && typeof request.value === 'boolean') return { power: request.value };
|
|
254
|
+
if (feature.id === 'target_temperature' && feature.capability === 'climate' && feature.unit === 'C'
|
|
255
|
+
&& typeof request.value === 'number' && Number.isSafeInteger(request.value)) return { targetTemperatureCelsius: request.value };
|
|
256
|
+
throw new TypeError('Unsupported Daikin feature or nonexplicit value.');
|
|
257
|
+
}
|
|
258
|
+
|
|
204
259
|
public static toSnapshot(optionsArg: IDaikinSnapshotOptions): IDaikinSnapshot {
|
|
205
260
|
if (optionsArg.config.snapshot && !optionsArg.rawData) {
|
|
206
261
|
return this.normalizeSnapshot(this.clone(optionsArg.config.snapshot), optionsArg.config, optionsArg.source || 'snapshot');
|
|
@@ -214,7 +269,7 @@ export class DaikinMapper {
|
|
|
214
269
|
const climate = this.climate(values, variant);
|
|
215
270
|
const energy = this.energy(values);
|
|
216
271
|
const capabilities = {
|
|
217
|
-
localControl:
|
|
272
|
+
localControl: false,
|
|
218
273
|
fanRate: values.f_rate !== undefined,
|
|
219
274
|
swingMode: values.f_dir !== undefined || values.f_dir_ud !== undefined || values.f_dir_lr !== undefined,
|
|
220
275
|
awayMode: values.en_hol !== undefined,
|
|
@@ -245,11 +300,13 @@ export class DaikinMapper {
|
|
|
245
300
|
public static toDevices(snapshotArg: IDaikinSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
|
|
246
301
|
const updatedAt = snapshotArg.updatedAt || new Date().toISOString();
|
|
247
302
|
const features: plugins.shxInterfaces.data.IDeviceFeature[] = [
|
|
248
|
-
{ id: 'power', capability: 'switch', name: 'Power', readable: true, writable: snapshotArg.capabilities.
|
|
249
|
-
{ id: 'hvac_mode', capability: 'climate', name: 'HVAC mode', readable: true, writable:
|
|
250
|
-
{ id: 'target_temperature', capability: 'climate', name: 'Target temperature', readable: true, writable: snapshotArg.capabilities.
|
|
251
|
-
{ id: 'inside_temperature', capability: 'sensor', name: 'Inside temperature', readable: true, writable: false, unit: 'C' },
|
|
303
|
+
{ id: 'power', capability: 'switch', name: 'Power', readable: true, writable: snapshotArg.nativeState?.capabilities.power === true },
|
|
304
|
+
{ id: 'hvac_mode', capability: 'climate', name: 'HVAC mode', readable: true, writable: false },
|
|
305
|
+
{ id: 'target_temperature', capability: 'climate', name: 'Target temperature', readable: true, writable: snapshotArg.nativeState?.capabilities.targetTemperature === true, unit: 'C' },
|
|
252
306
|
];
|
|
307
|
+
if (snapshotArg.climate.insideTemperature !== undefined) {
|
|
308
|
+
features.push({ id: 'inside_temperature', capability: 'sensor', name: 'Inside temperature', readable: true, writable: false, unit: 'C' });
|
|
309
|
+
}
|
|
253
310
|
if (snapshotArg.capabilities.outsideTemperature) {
|
|
254
311
|
features.push({ id: 'outside_temperature', capability: 'sensor', name: 'Outside temperature', readable: true, writable: false, unit: 'C' });
|
|
255
312
|
}
|
|
@@ -257,24 +314,24 @@ export class DaikinMapper {
|
|
|
257
314
|
features.push({ id: 'humidity', capability: 'sensor', name: 'Humidity', readable: true, writable: false, unit: '%' });
|
|
258
315
|
}
|
|
259
316
|
if (snapshotArg.capabilities.fanRate) {
|
|
260
|
-
features.push({ id: 'fan_mode', capability: 'fan', name: 'Fan mode', readable: true, writable:
|
|
317
|
+
features.push({ id: 'fan_mode', capability: 'fan', name: 'Fan mode', readable: true, writable: false });
|
|
261
318
|
}
|
|
262
319
|
if (snapshotArg.capabilities.swingMode) {
|
|
263
|
-
features.push({ id: 'swing_mode', capability: 'fan', name: 'Swing mode', readable: true, writable:
|
|
320
|
+
features.push({ id: 'swing_mode', capability: 'fan', name: 'Swing mode', readable: true, writable: false });
|
|
264
321
|
}
|
|
265
322
|
if (snapshotArg.capabilities.energyConsumption) {
|
|
266
323
|
features.push({ id: 'energy_today', capability: 'sensor', name: 'Energy today', readable: true, writable: false, unit: 'kWh' });
|
|
267
324
|
}
|
|
268
325
|
for (const zone of snapshotArg.zones) {
|
|
269
|
-
features.push({ id: `zone_${zone.id}`, capability: 'switch', name: `${zone.name} zone`, readable: true, writable:
|
|
326
|
+
features.push({ id: `zone_${zone.id}`, capability: 'switch', name: `${zone.name} zone`, readable: true, writable: false });
|
|
270
327
|
}
|
|
271
328
|
|
|
272
329
|
const state: plugins.shxInterfaces.data.IDeviceState[] = [
|
|
273
330
|
{ featureId: 'power', value: snapshotArg.climate.power, updatedAt },
|
|
274
331
|
{ featureId: 'hvac_mode', value: snapshotArg.climate.hvacMode, updatedAt },
|
|
275
332
|
{ featureId: 'target_temperature', value: snapshotArg.climate.targetTemperature ?? null, updatedAt },
|
|
276
|
-
{ featureId: 'inside_temperature', value: snapshotArg.climate.insideTemperature ?? null, updatedAt },
|
|
277
333
|
];
|
|
334
|
+
if (snapshotArg.climate.insideTemperature !== undefined) state.push({ featureId: 'inside_temperature', value: snapshotArg.climate.insideTemperature, updatedAt });
|
|
278
335
|
if (snapshotArg.capabilities.outsideTemperature) {
|
|
279
336
|
state.push({ featureId: 'outside_temperature', value: snapshotArg.climate.outsideTemperature ?? null, updatedAt });
|
|
280
337
|
}
|
|
@@ -313,6 +370,7 @@ export class DaikinMapper {
|
|
|
313
370
|
apiVariant: snapshotArg.device.apiVariant,
|
|
314
371
|
source: snapshotArg.source,
|
|
315
372
|
error: snapshotArg.error,
|
|
373
|
+
homeId: snapshotArg.device.homeId,
|
|
316
374
|
}),
|
|
317
375
|
}];
|
|
318
376
|
}
|
|
@@ -332,7 +390,7 @@ export class DaikinMapper {
|
|
|
332
390
|
currentTemperature: snapshotArg.climate.insideTemperature,
|
|
333
391
|
targetTemperature: snapshotArg.climate.targetTemperature,
|
|
334
392
|
hvacAction: snapshotArg.climate.hvacAction,
|
|
335
|
-
hvacModes: [
|
|
393
|
+
hvacModes: [],
|
|
336
394
|
fanMode: snapshotArg.climate.fanMode,
|
|
337
395
|
fanModes: snapshotArg.climate.fanModes,
|
|
338
396
|
swingMode: snapshotArg.climate.swingMode,
|
|
@@ -410,83 +468,6 @@ export class DaikinMapper {
|
|
|
410
468
|
return entities;
|
|
411
469
|
}
|
|
412
470
|
|
|
413
|
-
public static commandForService(snapshotArg: IDaikinSnapshot, requestArg: IServiceCallRequest): IDaikinCommandRequest | undefined {
|
|
414
|
-
if (requestArg.domain === daikinDomain && requestArg.service === 'refresh') {
|
|
415
|
-
return { action: 'refresh', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
if (requestArg.domain === 'climate') {
|
|
419
|
-
if (requestArg.service === 'turn_on') {
|
|
420
|
-
return this.controlCommand(snapshotArg, {}, requestArg);
|
|
421
|
-
}
|
|
422
|
-
if (requestArg.service === 'turn_off') {
|
|
423
|
-
return this.controlCommand(snapshotArg, { mode: 'off' }, requestArg);
|
|
424
|
-
}
|
|
425
|
-
if (requestArg.service === 'set_temperature') {
|
|
426
|
-
const temperature = this.numberValue(requestArg.data?.temperature);
|
|
427
|
-
if (temperature === undefined) {
|
|
428
|
-
return undefined;
|
|
429
|
-
}
|
|
430
|
-
const hvacMode = this.stringValue(requestArg.data?.hvac_mode ?? requestArg.data?.hvacMode);
|
|
431
|
-
return this.controlCommand(snapshotArg, {
|
|
432
|
-
stemp: this.formatTargetTemperature(temperature),
|
|
433
|
-
mode: hvacMode ? this.hvacToDaikinMode(hvacMode) : undefined,
|
|
434
|
-
}, requestArg);
|
|
435
|
-
}
|
|
436
|
-
if (requestArg.service === 'set_hvac_mode') {
|
|
437
|
-
const hvacMode = this.stringValue(requestArg.data?.hvac_mode ?? requestArg.data?.hvacMode);
|
|
438
|
-
return hvacMode ? this.controlCommand(snapshotArg, { mode: this.hvacToDaikinMode(hvacMode) }, requestArg) : undefined;
|
|
439
|
-
}
|
|
440
|
-
if (requestArg.service === 'set_fan_mode') {
|
|
441
|
-
const fanMode = this.stringValue(requestArg.data?.fan_mode ?? requestArg.data?.fanMode);
|
|
442
|
-
return fanMode ? this.controlCommand(snapshotArg, { f_rate: fanMode.toLowerCase() }, requestArg) : undefined;
|
|
443
|
-
}
|
|
444
|
-
if (requestArg.service === 'set_swing_mode') {
|
|
445
|
-
const swingMode = this.stringValue(requestArg.data?.swing_mode ?? requestArg.data?.swingMode);
|
|
446
|
-
return swingMode ? this.controlCommand(snapshotArg, { f_dir: swingMode.toLowerCase() }, requestArg) : undefined;
|
|
447
|
-
}
|
|
448
|
-
if (requestArg.service === 'set_preset_mode') {
|
|
449
|
-
return this.presetCommand(snapshotArg, this.stringValue(requestArg.data?.preset_mode ?? requestArg.data?.presetMode), requestArg);
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
if (requestArg.domain === 'switch') {
|
|
454
|
-
const enabled = requestArg.service === 'turn_on' ? true : requestArg.service === 'turn_off' ? false : undefined;
|
|
455
|
-
if (enabled === undefined) {
|
|
456
|
-
return undefined;
|
|
457
|
-
}
|
|
458
|
-
const target = `${requestArg.target.entityId || ''} ${requestArg.target.deviceId || ''}`.toLowerCase();
|
|
459
|
-
const zoneMatch = target.match(/(?:zone[_\-. ]?)(\d+)/);
|
|
460
|
-
if (zoneMatch) {
|
|
461
|
-
return { action: 'set_zone', protocol: snapshotArg.device.apiVariant, zoneId: Number(zoneMatch[1]), zoneKey: 'zone_onoff', zoneValue: enabled ? '1' : '0', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
462
|
-
}
|
|
463
|
-
if (target.includes('streamer')) {
|
|
464
|
-
return { action: 'set_streamer', protocol: snapshotArg.device.apiVariant, enabled, mode: enabled ? 'on' : 'off', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
465
|
-
}
|
|
466
|
-
return this.controlCommand(snapshotArg, { mode: enabled ? undefined : 'off' }, requestArg);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
if (requestArg.domain === daikinDomain && requestArg.service === 'set_zone') {
|
|
470
|
-
const zoneId = this.numberValue(requestArg.data?.zone_id ?? requestArg.data?.zoneId);
|
|
471
|
-
const value = requestArg.data?.value ?? requestArg.data?.enabled ?? requestArg.data?.on;
|
|
472
|
-
if (zoneId === undefined) {
|
|
473
|
-
return undefined;
|
|
474
|
-
}
|
|
475
|
-
return {
|
|
476
|
-
action: 'set_zone',
|
|
477
|
-
protocol: snapshotArg.device.apiVariant,
|
|
478
|
-
zoneId,
|
|
479
|
-
zoneKey: this.stringValue(requestArg.data?.key) || 'zone_onoff',
|
|
480
|
-
zoneValue: typeof value === 'boolean' ? value ? '1' : '0' : String(value ?? '1'),
|
|
481
|
-
service: requestArg.service,
|
|
482
|
-
target: requestArg.target,
|
|
483
|
-
data: requestArg.data,
|
|
484
|
-
};
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
return undefined;
|
|
488
|
-
}
|
|
489
|
-
|
|
490
471
|
public static deviceId(snapshotArg: IDaikinSnapshot): string {
|
|
491
472
|
return `${daikinDomain}.ac.${this.uniqueBase(snapshotArg)}`;
|
|
492
473
|
}
|
|
@@ -496,6 +477,7 @@ export class DaikinMapper {
|
|
|
496
477
|
}
|
|
497
478
|
|
|
498
479
|
public static uniqueBase(snapshotArg: IDaikinSnapshot): string {
|
|
480
|
+
if (snapshotArg.device.homeId !== undefined) return `${Buffer.from(snapshotArg.device.homeId, 'utf8').toString('base64url')}.${this.compactMac(snapshotArg.device.macAddress)}`;
|
|
499
481
|
return this.slug(snapshotArg.device.macAddress || snapshotArg.device.id || snapshotArg.device.host || snapshotArg.device.name || daikinDomain);
|
|
500
482
|
}
|
|
501
483
|
|
|
@@ -508,7 +490,7 @@ export class DaikinMapper {
|
|
|
508
490
|
return undefined;
|
|
509
491
|
}
|
|
510
492
|
const compact = valueArg.replace(/[^a-fA-F0-9]/g, '').toLowerCase();
|
|
511
|
-
return compact.length === 12 ? compact.match(/.{1,2}/g)?.join(':') :
|
|
493
|
+
return compact.length === 12 && /^[a-fA-F0-9:.-]+$/.test(valueArg) ? compact.match(/.{1,2}/g)?.join(':') : undefined;
|
|
512
494
|
}
|
|
513
495
|
|
|
514
496
|
public static compactMac(valueArg?: string): string | undefined {
|
|
@@ -625,7 +607,8 @@ export class DaikinMapper {
|
|
|
625
607
|
device: { ...derived.device, ...snapshotArg.device },
|
|
626
608
|
climate: { ...derived.climate, ...snapshotArg.climate },
|
|
627
609
|
energy: { ...derived.energy, ...snapshotArg.energy },
|
|
628
|
-
capabilities: { ...derived.capabilities, ...snapshotArg.capabilities },
|
|
610
|
+
capabilities: { ...derived.capabilities, ...snapshotArg.capabilities, localControl: false },
|
|
611
|
+
nativeState: undefined,
|
|
629
612
|
zones: snapshotArg.zones?.length ? snapshotArg.zones : derived.zones,
|
|
630
613
|
rawData: Object.keys(rawData).length ? rawData : snapshotArg.rawData,
|
|
631
614
|
source: snapshotArg.source || sourceArg,
|
|
@@ -675,7 +658,7 @@ export class DaikinMapper {
|
|
|
675
658
|
return {
|
|
676
659
|
power: hvacMode !== 'off' && rawPower !== '0',
|
|
677
660
|
hvacMode,
|
|
678
|
-
hvacAction:
|
|
661
|
+
hvacAction: hvacMode === 'off' ? 'off' : 'unknown',
|
|
679
662
|
rawDaikinMode: daikinMode,
|
|
680
663
|
rawPower,
|
|
681
664
|
targetTemperature: this.numberValue(valuesArg.stemp),
|
|
@@ -763,7 +746,7 @@ export class DaikinMapper {
|
|
|
763
746
|
private static entity(snapshotArg: IDaikinSnapshot, definitionArg: IDaikinEntityDefinition, deviceIdArg: string, uniqueBaseArg: string): IIntegrationEntity {
|
|
764
747
|
const platform = definitionArg.platform || 'sensor';
|
|
765
748
|
return {
|
|
766
|
-
id: `${platform}.${this.slug(definitionArg.name)}`,
|
|
749
|
+
id: snapshotArg.device.homeId === undefined ? `${platform}.${this.slug(definitionArg.name)}` : `${platform}.daikin.${uniqueBaseArg}.${definitionArg.key}`,
|
|
767
750
|
uniqueId: `${daikinDomain}_${uniqueBaseArg}_${this.slug(definitionArg.key)}`,
|
|
768
751
|
integrationDomain: daikinDomain,
|
|
769
752
|
deviceId: deviceIdArg,
|
|
@@ -778,56 +761,19 @@ export class DaikinMapper {
|
|
|
778
761
|
entityCategory: definitionArg.entityCategory,
|
|
779
762
|
source: snapshotArg.source,
|
|
780
763
|
error: snapshotArg.error,
|
|
764
|
+
homeId: snapshotArg.device.homeId,
|
|
781
765
|
...definitionArg.attributes,
|
|
782
766
|
}),
|
|
783
767
|
available: definitionArg.available ?? snapshotArg.online,
|
|
784
768
|
};
|
|
785
769
|
}
|
|
786
770
|
|
|
787
|
-
private static controlCommand(snapshotArg: IDaikinSnapshot, settingsArg: IDaikinCommandRequest['settings'], requestArg: IServiceCallRequest): IDaikinCommandRequest {
|
|
788
|
-
return { action: 'set_control', protocol: snapshotArg.device.apiVariant, settings: this.cleanAttributes(settingsArg || {}) as IDaikinCommandRequest['settings'], service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
private static presetCommand(snapshotArg: IDaikinSnapshot, presetArg: string | undefined, requestArg: IServiceCallRequest): IDaikinCommandRequest | undefined {
|
|
792
|
-
if (!presetArg) {
|
|
793
|
-
return undefined;
|
|
794
|
-
}
|
|
795
|
-
const preset = presetArg.toLowerCase();
|
|
796
|
-
if (preset === 'away') {
|
|
797
|
-
return { action: 'set_holiday', protocol: snapshotArg.device.apiVariant, enabled: true, mode: 'on', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
798
|
-
}
|
|
799
|
-
if (preset === 'boost') {
|
|
800
|
-
return { action: 'set_advanced_mode', protocol: snapshotArg.device.apiVariant, enabled: true, mode: 'powerful', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
801
|
-
}
|
|
802
|
-
if (preset === 'eco') {
|
|
803
|
-
return { action: 'set_advanced_mode', protocol: snapshotArg.device.apiVariant, enabled: true, mode: 'econo', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
804
|
-
}
|
|
805
|
-
if (preset === 'none') {
|
|
806
|
-
if (snapshotArg.climate.presetMode === 'away') {
|
|
807
|
-
return { action: 'set_holiday', protocol: snapshotArg.device.apiVariant, enabled: false, mode: 'off', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
808
|
-
}
|
|
809
|
-
if (snapshotArg.climate.presetMode === 'boost') {
|
|
810
|
-
return { action: 'set_advanced_mode', protocol: snapshotArg.device.apiVariant, enabled: false, mode: 'powerful', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
811
|
-
}
|
|
812
|
-
if (snapshotArg.climate.presetMode === 'eco') {
|
|
813
|
-
return { action: 'set_advanced_mode', protocol: snapshotArg.device.apiVariant, enabled: false, mode: 'econo', service: requestArg.service, target: requestArg.target, data: requestArg.data };
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
return undefined;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
771
|
private static supportedClimateFeatures(snapshotArg: IDaikinSnapshot): string[] {
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
features.push('swing_mode');
|
|
826
|
-
}
|
|
827
|
-
if (snapshotArg.capabilities.awayMode || snapshotArg.capabilities.advancedModes) {
|
|
828
|
-
features.push('preset_mode');
|
|
829
|
-
}
|
|
830
|
-
return features;
|
|
772
|
+
if (!snapshotArg.nativeState) return [];
|
|
773
|
+
return [
|
|
774
|
+
...(snapshotArg.nativeState.capabilities.power ? ['turn_on', 'turn_off'] : []),
|
|
775
|
+
...(snapshotArg.nativeState.capabilities.targetTemperature ? ['target_temperature'] : []),
|
|
776
|
+
];
|
|
831
777
|
}
|
|
832
778
|
|
|
833
779
|
private static detectVariant(configArg: IDaikinConfig, rawDataArg: Partial<IDaikinRawData>, valuesArg: IDaikinValueMap): TDaikinApiVariant {
|
|
@@ -846,9 +792,6 @@ export class DaikinMapper {
|
|
|
846
792
|
if (Object.keys(rawDataArg.resources || {}).some((keyArg) => keyArg.startsWith('skyfi/')) || valuesArg.lztemp_c !== undefined || valuesArg.zone_name !== undefined) {
|
|
847
793
|
return 'airbase';
|
|
848
794
|
}
|
|
849
|
-
if (configArg.apiKey) {
|
|
850
|
-
return 'brp072c';
|
|
851
|
-
}
|
|
852
795
|
return 'brp069';
|
|
853
796
|
}
|
|
854
797
|
|
|
@@ -869,28 +812,6 @@ export class DaikinMapper {
|
|
|
869
812
|
return value || 'unknown';
|
|
870
813
|
}
|
|
871
814
|
|
|
872
|
-
private static hvacAction(hvacModeArg: TDaikinHvacMode, compressorFrequencyArg?: number): TDaikinHvacAction {
|
|
873
|
-
if (hvacModeArg === 'off') {
|
|
874
|
-
return 'off';
|
|
875
|
-
}
|
|
876
|
-
if (compressorFrequencyArg === 0 && (hvacModeArg === 'cool' || hvacModeArg === 'heat')) {
|
|
877
|
-
return 'idle';
|
|
878
|
-
}
|
|
879
|
-
if (hvacModeArg === 'cool') {
|
|
880
|
-
return 'cooling';
|
|
881
|
-
}
|
|
882
|
-
if (hvacModeArg === 'heat') {
|
|
883
|
-
return 'heating';
|
|
884
|
-
}
|
|
885
|
-
if (hvacModeArg === 'dry') {
|
|
886
|
-
return 'drying';
|
|
887
|
-
}
|
|
888
|
-
if (hvacModeArg === 'fan_only') {
|
|
889
|
-
return 'fan';
|
|
890
|
-
}
|
|
891
|
-
return 'idle';
|
|
892
|
-
}
|
|
893
|
-
|
|
894
815
|
private static presetMode(valuesArg: IDaikinValueMap, variantArg: TDaikinApiVariant): TDaikinPresetMode {
|
|
895
816
|
if (this.daikinToHuman('en_hol', valuesArg.en_hol, variantArg) === 'on') {
|
|
896
817
|
return 'away';
|
|
@@ -1025,10 +946,6 @@ export class DaikinMapper {
|
|
|
1025
946
|
return undefined;
|
|
1026
947
|
}
|
|
1027
948
|
|
|
1028
|
-
private static stringValue(valueArg: unknown): string | undefined {
|
|
1029
|
-
return typeof valueArg === 'string' && valueArg.trim() ? valueArg.trim() : undefined;
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
949
|
private static title(valueArg: string | undefined): string | undefined {
|
|
1033
950
|
if (!valueArg) {
|
|
1034
951
|
return undefined;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type * as plugins from '../../plugins.js';
|
|
2
|
+
|
|
1
3
|
export const daikinDomain = 'daikin';
|
|
2
4
|
export const daikinDisplayName = 'Daikin AC';
|
|
3
5
|
export const daikinDefaultHttpPort = 80;
|
|
@@ -10,11 +12,10 @@ export const daikinUdpDiscoveryMessage = 'DAIKIN_UDP/common/basic_info';
|
|
|
10
12
|
export const daikinZeroconfType = '_dkapi._tcp.local.';
|
|
11
13
|
|
|
12
14
|
export type TDaikinApiVariant = 'auto' | 'brp069' | 'brp072c' | 'airbase' | 'skyfi' | 'brp084';
|
|
13
|
-
export type TDaikinSnapshotSource = 'http' | '
|
|
15
|
+
export type TDaikinSnapshotSource = 'http' | 'manual' | 'snapshot' | 'runtime';
|
|
14
16
|
export type TDaikinHvacMode = 'off' | 'fan_only' | 'dry' | 'cool' | 'heat' | 'heat_cool' | 'auto' | 'unknown' | string;
|
|
15
17
|
export type TDaikinHvacAction = 'off' | 'idle' | 'cooling' | 'heating' | 'drying' | 'fan' | 'unknown';
|
|
16
18
|
export type TDaikinPresetMode = 'none' | 'away' | 'boost' | 'eco' | string;
|
|
17
|
-
export type TDaikinCommandAction = 'refresh' | 'set_control' | 'set_holiday' | 'set_advanced_mode' | 'set_streamer' | 'set_zone';
|
|
18
19
|
|
|
19
20
|
export interface IDaikinValueMap {
|
|
20
21
|
[key: string]: string | undefined;
|
|
@@ -52,6 +53,7 @@ export interface IDaikinDeviceSnapshotInfo {
|
|
|
52
53
|
ssl?: boolean;
|
|
53
54
|
macAddress?: string;
|
|
54
55
|
apiVariant: TDaikinApiVariant;
|
|
56
|
+
homeId?: string;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
export interface IDaikinClimateSnapshot {
|
|
@@ -121,58 +123,18 @@ export interface IDaikinSnapshot {
|
|
|
121
123
|
updatedAt: string;
|
|
122
124
|
source: TDaikinSnapshotSource;
|
|
123
125
|
error?: string;
|
|
126
|
+
/** Present only for a current observation from the public selected BRP069 protocol. */
|
|
127
|
+
nativeState?: plugins.ecobridgeDeviceManager.IDaikinState;
|
|
124
128
|
}
|
|
125
129
|
|
|
126
|
-
|
|
127
|
-
mode?: string;
|
|
128
|
-
pow?: string;
|
|
129
|
-
stemp?: string | number;
|
|
130
|
-
shum?: string | number;
|
|
131
|
-
f_rate?: string;
|
|
132
|
-
f_dir?: string;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export interface IDaikinCommandRequest {
|
|
136
|
-
action: TDaikinCommandAction;
|
|
137
|
-
method?: 'GET' | 'POST';
|
|
138
|
-
path?: string;
|
|
139
|
-
query?: Record<string, string | number | boolean | undefined>;
|
|
140
|
-
protocol?: TDaikinApiVariant | 'legacy';
|
|
141
|
-
settings?: Partial<IDaikinControlSettings>;
|
|
142
|
-
mode?: string;
|
|
143
|
-
enabled?: boolean;
|
|
144
|
-
zoneId?: number;
|
|
145
|
-
zoneKey?: string;
|
|
146
|
-
zoneValue?: string;
|
|
147
|
-
service?: string;
|
|
148
|
-
target?: Record<string, unknown>;
|
|
149
|
-
data?: Record<string, unknown>;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export interface IDaikinCommandExecutor {
|
|
153
|
-
execute(requestArg: IDaikinCommandRequest): Promise<unknown>;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export interface IDaikinClientLike {
|
|
157
|
-
getSnapshot?: () => Promise<IDaikinSnapshot | Partial<IDaikinRawData>>;
|
|
158
|
-
getRawData?: () => Promise<Partial<IDaikinRawData>>;
|
|
159
|
-
getResource?: (pathArg: string, queryArg?: Record<string, string | number | boolean | undefined>) => Promise<IDaikinValueMap>;
|
|
160
|
-
execute?: (requestArg: IDaikinCommandRequest) => Promise<unknown>;
|
|
161
|
-
destroy?: () => Promise<void>;
|
|
162
|
-
}
|
|
163
|
-
|
|
130
|
+
/** Offline mapper input; this shape cannot authorize native setup or effects. */
|
|
164
131
|
export interface IDaikinConfig {
|
|
165
132
|
host?: string;
|
|
166
133
|
url?: string;
|
|
167
134
|
port?: number;
|
|
168
135
|
ssl?: boolean;
|
|
169
136
|
tls?: boolean;
|
|
170
|
-
verifySsl?: boolean;
|
|
171
|
-
apiKey?: string;
|
|
172
|
-
uuid?: string;
|
|
173
|
-
password?: string;
|
|
174
137
|
apiVariant?: TDaikinApiVariant;
|
|
175
|
-
timeoutMs?: number;
|
|
176
138
|
name?: string;
|
|
177
139
|
manufacturer?: string;
|
|
178
140
|
model?: string;
|
|
@@ -181,12 +143,10 @@ export interface IDaikinConfig {
|
|
|
181
143
|
snapshot?: IDaikinSnapshot;
|
|
182
144
|
rawData?: Partial<IDaikinRawData>;
|
|
183
145
|
values?: IDaikinValueMap;
|
|
184
|
-
client?: IDaikinClientLike;
|
|
185
|
-
commandExecutor?: IDaikinCommandExecutor;
|
|
186
146
|
online?: boolean;
|
|
187
147
|
}
|
|
188
148
|
|
|
189
|
-
export interface IHomeAssistantDaikinConfig extends
|
|
149
|
+
export interface IHomeAssistantDaikinConfig extends IDaikinNativeConfig {}
|
|
190
150
|
|
|
191
151
|
export interface IDaikinManualEntry extends IDaikinConfig {
|
|
192
152
|
id?: string;
|
|
@@ -239,3 +199,22 @@ export interface IDaikinRefreshResult {
|
|
|
239
199
|
error?: string;
|
|
240
200
|
data?: unknown;
|
|
241
201
|
}
|
|
202
|
+
|
|
203
|
+
/** Live setup is an explicit selected, unauthenticated BRP069 LAN connection. */
|
|
204
|
+
export interface IDaikinIntegrationOptions {
|
|
205
|
+
readonly homeId?: string;
|
|
206
|
+
readonly capacity?: number;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export interface IDaikinNativeConfig {
|
|
210
|
+
homeId: string;
|
|
211
|
+
apiVariant: 'brp069';
|
|
212
|
+
host: string;
|
|
213
|
+
expectedMac: string;
|
|
214
|
+
allowPlaintext: true;
|
|
215
|
+
name?: string;
|
|
216
|
+
port?: number;
|
|
217
|
+
timeoutMs?: number;
|
|
218
|
+
maxResponseBytes?: number;
|
|
219
|
+
maxPendingOperations?: number;
|
|
220
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { IDaikinNativeConfig } from './daikin.types.js';
|
|
2
|
+
|
|
3
|
+
export const daikinObject = (valueArg: unknown, nameArg: string): Record<string, unknown> => {
|
|
4
|
+
if (!valueArg || typeof valueArg !== 'object' || Object.getPrototypeOf(valueArg) !== Object.prototype) {
|
|
5
|
+
throw new TypeError(`${nameArg} must be a plain object.`);
|
|
6
|
+
}
|
|
7
|
+
const result: Record<string, unknown> = {};
|
|
8
|
+
for (const key of Reflect.ownKeys(valueArg)) {
|
|
9
|
+
const descriptor = Object.getOwnPropertyDescriptor(valueArg, key);
|
|
10
|
+
if (typeof key !== 'string' || !descriptor || !('value' in descriptor) || !descriptor.enumerable) {
|
|
11
|
+
throw new TypeError(`${nameArg} accepts only enumerable own data fields.`);
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(result, key, { value: descriptor.value, enumerable: true });
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const daikinKeys = (valueArg: Record<string, unknown>, allowedArg: readonly string[]): void => {
|
|
19
|
+
if (Object.keys(valueArg).some((keyArg) => !allowedArg.includes(keyArg))) throw new TypeError('Daikin arguments contain unsupported fields.');
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const text = (valueArg: unknown, nameArg: string, maximumArg: number): string => {
|
|
23
|
+
if (typeof valueArg !== 'string' || valueArg.length === 0 || valueArg.length > maximumArg || /[\p{Cc}\p{Cs}]/u.test(valueArg)) {
|
|
24
|
+
throw new TypeError(`${nameArg} must be a nonempty bounded string without control characters.`);
|
|
25
|
+
}
|
|
26
|
+
return valueArg;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const optionalNumber = (valueArg: unknown, nameArg: string): number | undefined => {
|
|
30
|
+
if (valueArg === undefined) return undefined;
|
|
31
|
+
if (typeof valueArg !== 'number') throw new TypeError(`${nameArg} must be a number.`);
|
|
32
|
+
return valueArg;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Device address, MAC and protocol limits are validated by the public DaikinProtocol. */
|
|
36
|
+
export const normalizeDaikinConfig = (valueArg: IDaikinNativeConfig): Readonly<IDaikinNativeConfig> => {
|
|
37
|
+
const value = daikinObject(valueArg, 'Daikin configuration');
|
|
38
|
+
daikinKeys(value, ['homeId', 'apiVariant', 'host', 'expectedMac', 'allowPlaintext', 'name', 'port', 'timeoutMs', 'maxResponseBytes', 'maxPendingOperations']);
|
|
39
|
+
if (value.apiVariant !== 'brp069') throw new TypeError('Daikin live control requires the explicitly selected brp069 family.');
|
|
40
|
+
if (value.allowPlaintext !== true) throw new TypeError('Daikin BRP069 requires explicit allowPlaintext: true for unauthenticated LAN HTTP.');
|
|
41
|
+
const result: IDaikinNativeConfig = {
|
|
42
|
+
allowPlaintext: true, homeId: text(value.homeId, 'Daikin home ID', 256), apiVariant: 'brp069',
|
|
43
|
+
host: text(value.host, 'Daikin selected IPv4', 64), expectedMac: text(value.expectedMac, 'Daikin expected adapter MAC', 12).toUpperCase(),
|
|
44
|
+
};
|
|
45
|
+
if (value.name !== undefined) result.name = text(value.name, 'Daikin name', 256);
|
|
46
|
+
for (const key of ['port', 'timeoutMs', 'maxResponseBytes', 'maxPendingOperations'] as const) {
|
|
47
|
+
const number = optionalNumber(value[key], `Daikin ${key}`);
|
|
48
|
+
if (number !== undefined) result[key] = number;
|
|
49
|
+
}
|
|
50
|
+
return Object.freeze(result);
|
|
51
|
+
};
|