@willieee802/zigbee-herdsman-converters 15.0.8-4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/converters/fromZigbee.js +8439 -0
  4. package/converters/toZigbee.js +7162 -0
  5. package/devices/ITCommander.js +37 -0
  6. package/devices/RMC002.js +20 -0
  7. package/devices/acova.js +101 -0
  8. package/devices/acuity_brands_lighting.js +11 -0
  9. package/devices/adeo.js +256 -0
  10. package/devices/adurosmart.js +130 -0
  11. package/devices/aeotec.js +13 -0
  12. package/devices/airam.js +59 -0
  13. package/devices/ajax_online.js +49 -0
  14. package/devices/akuvox.js +28 -0
  15. package/devices/alchemy.js +18 -0
  16. package/devices/aldi.js +53 -0
  17. package/devices/alecto.js +98 -0
  18. package/devices/anchor.js +17 -0
  19. package/devices/atlantic.js +110 -0
  20. package/devices/atsmart.js +28 -0
  21. package/devices/aubess.js +21 -0
  22. package/devices/aurora_lighting.js +292 -0
  23. package/devices/automaton.js +44 -0
  24. package/devices/awox.js +184 -0
  25. package/devices/axis.js +22 -0
  26. package/devices/bankamp.js +11 -0
  27. package/devices/bega.js +22 -0
  28. package/devices/belkin.js +11 -0
  29. package/devices/bitron.js +334 -0
  30. package/devices/blaupunkt.js +27 -0
  31. package/devices/blitzwolf.js +47 -0
  32. package/devices/bosch.js +702 -0
  33. package/devices/brimate.js +15 -0
  34. package/devices/bseed.js +17 -0
  35. package/devices/bticino.js +118 -0
  36. package/devices/busch-jaeger.js +140 -0
  37. package/devices/byun.js +24 -0
  38. package/devices/calex.js +37 -0
  39. package/devices/candeo.js +49 -0
  40. package/devices/casaia.js +52 -0
  41. package/devices/centralite.js +359 -0
  42. package/devices/cleode.js +20 -0
  43. package/devices/cleverio.js +36 -0
  44. package/devices/climax.js +138 -0
  45. package/devices/commercial_electric.js +16 -0
  46. package/devices/connecte.js +46 -0
  47. package/devices/cree.js +11 -0
  48. package/devices/ctm.js +999 -0
  49. package/devices/current_products_corp.js +24 -0
  50. package/devices/custom_devices_diy.js +850 -0
  51. package/devices/cy-lighting.js +11 -0
  52. package/devices/danalock.js +26 -0
  53. package/devices/danfoss.js +340 -0
  54. package/devices/databyte.ch.js +55 -0
  55. package/devices/datek.js +246 -0
  56. package/devices/dawon_dns.js +338 -0
  57. package/devices/develco.js +868 -0
  58. package/devices/digi.js +14 -0
  59. package/devices/diyruz.js +305 -0
  60. package/devices/dlink.js +37 -0
  61. package/devices/dnake.js +11 -0
  62. package/devices/dresden_elektronik.js +47 -0
  63. package/devices/easyaccess.js +27 -0
  64. package/devices/eatonhalo_led.js +11 -0
  65. package/devices/echostar.js +25 -0
  66. package/devices/ecodim.js +145 -0
  67. package/devices/ecolink.js +21 -0
  68. package/devices/ecosmart.js +64 -0
  69. package/devices/ecozy.js +31 -0
  70. package/devices/edp.js +39 -0
  71. package/devices/eglo.js +25 -0
  72. package/devices/elko.js +176 -0
  73. package/devices/enbrighten.js +163 -0
  74. package/devices/enocean.js +52 -0
  75. package/devices/envilar.js +73 -0
  76. package/devices/essentialb.js +87 -0
  77. package/devices/eurotronic.js +48 -0
  78. package/devices/evanell.js +29 -0
  79. package/devices/evn.js +31 -0
  80. package/devices/evology.js +24 -0
  81. package/devices/evvr.js +17 -0
  82. package/devices/ewelink.js +184 -0
  83. package/devices/ezex.js +24 -0
  84. package/devices/fantem.js +77 -0
  85. package/devices/feibit.js +172 -0
  86. package/devices/fireangel.js +15 -0
  87. package/devices/frankever.js +23 -0
  88. package/devices/garza.js +11 -0
  89. package/devices/ge.js +111 -0
  90. package/devices/gewiss.js +48 -0
  91. package/devices/gidealed.js +11 -0
  92. package/devices/giderwel.js +11 -0
  93. package/devices/giex.js +222 -0
  94. package/devices/girier.js +19 -0
  95. package/devices/gledopto.js +756 -0
  96. package/devices/gmy.js +11 -0
  97. package/devices/gs.js +29 -0
  98. package/devices/halemeier.js +18 -0
  99. package/devices/hampton_bay.js +37 -0
  100. package/devices/heiman.js +805 -0
  101. package/devices/hej.js +107 -0
  102. package/devices/hfh.js +11 -0
  103. package/devices/hgkg.js +54 -0
  104. package/devices/hilux.js +11 -0
  105. package/devices/hive.js +524 -0
  106. package/devices/home_control_as.js +27 -0
  107. package/devices/hommyn.js +24 -0
  108. package/devices/honyar.js +29 -0
  109. package/devices/hornbach.js +53 -0
  110. package/devices/hzc.js +21 -0
  111. package/devices/hzc_electric.js +42 -0
  112. package/devices/icasa.js +121 -0
  113. package/devices/idinio.js +19 -0
  114. package/devices/ihorn.js +61 -0
  115. package/devices/ikea.js +1168 -0
  116. package/devices/ilightsin.js +11 -0
  117. package/devices/iluminize.js +262 -0
  118. package/devices/ilux.js +11 -0
  119. package/devices/immax.js +203 -0
  120. package/devices/innr.js +705 -0
  121. package/devices/inovelli.js +1315 -0
  122. package/devices/insta.js +110 -0
  123. package/devices/iolloi.js +20 -0
  124. package/devices/iotperfect.js +20 -0
  125. package/devices/iris.js +180 -0
  126. package/devices/istar.js +20 -0
  127. package/devices/jasco.js +55 -0
  128. package/devices/javis.js +37 -0
  129. package/devices/jethome.js +48 -0
  130. package/devices/jiawen.js +18 -0
  131. package/devices/jumitech.js +18 -0
  132. package/devices/jxuan.js +49 -0
  133. package/devices/kami.js +15 -0
  134. package/devices/keen_home.js +80 -0
  135. package/devices/klikaanklikuit.js +17 -0
  136. package/devices/kmpcil.js +148 -0
  137. package/devices/konke.js +141 -0
  138. package/devices/ksentry.js +17 -0
  139. package/devices/kurvia.js +17 -0
  140. package/devices/kwikset.js +120 -0
  141. package/devices/lanesto.js +11 -0
  142. package/devices/lds.js +11 -0
  143. package/devices/led_trading.js +69 -0
  144. package/devices/ledvance.js +353 -0
  145. package/devices/leedarson.js +130 -0
  146. package/devices/legrand.js +554 -0
  147. package/devices/lellki.js +146 -0
  148. package/devices/letsled.js +11 -0
  149. package/devices/letv.js +18 -0
  150. package/devices/leviton.js +142 -0
  151. package/devices/lg.js +18 -0
  152. package/devices/lidl.js +1000 -0
  153. package/devices/lifecontrol.js +92 -0
  154. package/devices/lightsolutions.js +37 -0
  155. package/devices/linkind.js +205 -0
  156. package/devices/livingwise.js +59 -0
  157. package/devices/livolo.js +286 -0
  158. package/devices/lixee.js +779 -0
  159. package/devices/lonsonho.js +218 -0
  160. package/devices/lubeez.js +18 -0
  161. package/devices/lupus.js +74 -0
  162. package/devices/lutron.js +32 -0
  163. package/devices/lux.js +40 -0
  164. package/devices/m-elec.js +18 -0
  165. package/devices/makegood.js +51 -0
  166. package/devices/matcall_bv.js +18 -0
  167. package/devices/meazon.js +47 -0
  168. package/devices/mercator.js +225 -0
  169. package/devices/miboxer.js +72 -0
  170. package/devices/micromatic.js +29 -0
  171. package/devices/moes.js +400 -0
  172. package/devices/mycket.js +11 -0
  173. package/devices/m/303/274ller_licht.js +220 -0
  174. package/devices/namron.js +774 -0
  175. package/devices/nanoleaf.js +11 -0
  176. package/devices/neo.js +86 -0
  177. package/devices/net2grid.js +29 -0
  178. package/devices/netvox.js +35 -0
  179. package/devices/niko.js +314 -0
  180. package/devices/ninja_blocks.js +24 -0
  181. package/devices/niviss.js +11 -0
  182. package/devices/nodon.js +109 -0
  183. package/devices/nordtronic.js +30 -0
  184. package/devices/nous.js +88 -0
  185. package/devices/novo.js +17 -0
  186. package/devices/nue_3a.js +417 -0
  187. package/devices/nyce.js +67 -0
  188. package/devices/onesti.js +59 -0
  189. package/devices/openlumi.js +22 -0
  190. package/devices/orvibo.js +515 -0
  191. package/devices/osram.js +519 -0
  192. package/devices/oujiabao.js +15 -0
  193. package/devices/owon.js +352 -0
  194. package/devices/ozsmartthings.js +11 -0
  195. package/devices/paul_neuhaus.js +96 -0
  196. package/devices/paulmann.js +158 -0
  197. package/devices/peq.js +24 -0
  198. package/devices/perenio.js +413 -0
  199. package/devices/philips.js +3118 -0
  200. package/devices/plaid.js +25 -0
  201. package/devices/plugwise.js +173 -0
  202. package/devices/popp.js +10 -0
  203. package/devices/profalux.js +47 -0
  204. package/devices/prolight.js +54 -0
  205. package/devices/qmotion.js +33 -0
  206. package/devices/qoto.js +113 -0
  207. package/devices/quotra.js +18 -0
  208. package/devices/rademacher.js +18 -0
  209. package/devices/rgb_genie.js +119 -0
  210. package/devices/robb.js +335 -0
  211. package/devices/roome.js +15 -0
  212. package/devices/rtx.js +90 -0
  213. package/devices/salus_controls.js +137 -0
  214. package/devices/samotech.js +93 -0
  215. package/devices/saswell.js +58 -0
  216. package/devices/scanproducts.js +32 -0
  217. package/devices/schlage.js +24 -0
  218. package/devices/schneider_electric.js +1039 -0
  219. package/devices/schwaiger.js +62 -0
  220. package/devices/seastar_intelligence.js +16 -0
  221. package/devices/securifi.js +39 -0
  222. package/devices/sengled.js +332 -0
  223. package/devices/sercomm.js +140 -0
  224. package/devices/shenzhen_homa.js +53 -0
  225. package/devices/shinasystem.js +686 -0
  226. package/devices/siglis.js +440 -0
  227. package/devices/sinope.js +1257 -0
  228. package/devices/siterwell.js +46 -0
  229. package/devices/skydance.js +112 -0
  230. package/devices/slv.js +27 -0
  231. package/devices/smart9.js +27 -0
  232. package/devices/smart_home_pty.js +18 -0
  233. package/devices/smartenit.js +42 -0
  234. package/devices/smartthings.js +495 -0
  235. package/devices/smartwings.js +24 -0
  236. package/devices/sohan_electric.js +13 -0
  237. package/devices/solaredge.js +11 -0
  238. package/devices/somgoms.js +47 -0
  239. package/devices/sonoff.js +262 -0
  240. package/devices/spotmau.js +36 -0
  241. package/devices/sprut.js +317 -0
  242. package/devices/stelpro.js +216 -0
  243. package/devices/sunricher.js +625 -0
  244. package/devices/swann.js +33 -0
  245. package/devices/sylvania.js +200 -0
  246. package/devices/tci.js +25 -0
  247. package/devices/technicolor.js +47 -0
  248. package/devices/terncy.js +64 -0
  249. package/devices/the_light_group.js +70 -0
  250. package/devices/third_reality.js +195 -0
  251. package/devices/titan_products.js +22 -0
  252. package/devices/tplink.js +42 -0
  253. package/devices/trust.js +114 -0
  254. package/devices/tubeszb.js +20 -0
  255. package/devices/tuya.js +4215 -0
  256. package/devices/ubisys.js +938 -0
  257. package/devices/uhome.js +25 -0
  258. package/devices/universal_electronics_inc.js +119 -0
  259. package/devices/urlighting.js +12 -0
  260. package/devices/useelink.js +52 -0
  261. package/devices/vbled.js +18 -0
  262. package/devices/vesternet.js +188 -0
  263. package/devices/viessmann.js +51 -0
  264. package/devices/villeroy_boch.js +18 -0
  265. package/devices/vimar.js +78 -0
  266. package/devices/visonic.js +80 -0
  267. package/devices/vrey.js +18 -0
  268. package/devices/wally.js +25 -0
  269. package/devices/waxman.js +45 -0
  270. package/devices/weiser.js +67 -0
  271. package/devices/weten.js +13 -0
  272. package/devices/wisdom.js +11 -0
  273. package/devices/woox.js +177 -0
  274. package/devices/wyze.js +23 -0
  275. package/devices/xiaomi.js +3223 -0
  276. package/devices/xinghuoyuan.js +11 -0
  277. package/devices/yale.js +227 -0
  278. package/devices/ynoa.js +68 -0
  279. package/devices/yookee.js +23 -0
  280. package/devices/ysrsai.js +26 -0
  281. package/devices/zemismart.js +254 -0
  282. package/devices/zen.js +34 -0
  283. package/devices/zipato.js +11 -0
  284. package/index.js +242 -0
  285. package/lib/color.js +784 -0
  286. package/lib/configureKey.js +944 -0
  287. package/lib/constants.js +316 -0
  288. package/lib/exposes.js +677 -0
  289. package/lib/extend.js +180 -0
  290. package/lib/kelvinToXy.js +1912 -0
  291. package/lib/legacy.js +2223 -0
  292. package/lib/light.js +111 -0
  293. package/lib/ota/OTA_URLs.md +119 -0
  294. package/lib/ota/common.js +476 -0
  295. package/lib/ota/index.js +10 -0
  296. package/lib/ota/inovelli.js +72 -0
  297. package/lib/ota/ledvance.js +52 -0
  298. package/lib/ota/lixee.js +57 -0
  299. package/lib/ota/salus.js +82 -0
  300. package/lib/ota/securifi.js +25 -0
  301. package/lib/ota/tradfri.js +45 -0
  302. package/lib/ota/ubisys.js +61 -0
  303. package/lib/ota/zigbeeOTA.js +161 -0
  304. package/lib/philips.js +667 -0
  305. package/lib/reporting.js +234 -0
  306. package/lib/store.js +57 -0
  307. package/lib/tuya.js +2027 -0
  308. package/lib/utils.js +527 -0
  309. package/lib/xiaomi.d.ts +11 -0
  310. package/lib/xiaomi.js +1288 -0
  311. package/lib/zosung.js +243 -0
  312. package/package.json +39 -0
@@ -0,0 +1,779 @@
1
+ /* eslint-disable camelcase */
2
+ /* eslint-disable max-len */
3
+ 'use strict';
4
+ const exposes = require('../lib/exposes');
5
+ const globalStore = require('../lib/store');
6
+ const {repInterval} = require('../lib/constants');
7
+ const reporting = require('../lib/reporting');
8
+ const fz = require('../converters/fromZigbee');
9
+ const ea = exposes.access;
10
+ const e = exposes.presets;
11
+ const utils = require('../lib/utils');
12
+ const ota = require('../lib/ota');
13
+ const {Buffer} = require('buffer');
14
+ const herdsman = require('zigbee-herdsman');
15
+
16
+
17
+ /* Start ZiPulses */
18
+
19
+ const unitsZiPulses = [
20
+ 'kWh',
21
+ 'm3',
22
+ 'ft3',
23
+ 'ccf',
24
+ 'US gl',
25
+ 'IMP gl',
26
+ 'BTUs',
27
+ 'L (litre)',
28
+ 'kPA (jauge)',
29
+ 'kPA (absolu)',
30
+ 'kPA (absolu)',
31
+ 'sans unité',
32
+ 'MJ',
33
+ 'kVar',
34
+ ];
35
+
36
+ const tzSeMetering = {
37
+ key: ['divisor', 'multiplier', 'unitOfMeasure'],
38
+ convertSet: async (entity, key, value, meta) => {
39
+ if (key === 'unitOfMeasure') {
40
+ const val = unitsZiPulses.indexOf(value);
41
+ const payload = {768: {value: val, type: herdsman.Zcl.DataType.enum8}};
42
+ await entity.write('seMetering', payload);
43
+ await entity.read('seMetering', [key]);
44
+ return {state: {'unitOfMeasure': value}};
45
+ } else {
46
+ await entity.write('seMetering', {
47
+ [key]: value,
48
+ });
49
+ }
50
+
51
+ return {state: {[key]: value}};
52
+ },
53
+ // convertGet: async (entity, key, meta) => {
54
+ // await entity.read('seMetering', [key]);
55
+ // },
56
+ };
57
+
58
+
59
+ const fzZiPulses = {
60
+ cluster: 'seMetering',
61
+ type: ['attributeReport', 'readResponse'],
62
+ convert: (model, msg, publish, options, meta) => {
63
+ const payload = {};
64
+ if (msg.data.hasOwnProperty('multiplier')) {
65
+ payload['multiplier'] = msg.data['multiplier'];
66
+ }
67
+ if (msg.data.hasOwnProperty('divisor')) {
68
+ payload['divisor'] = msg.data['divisor'];
69
+ }
70
+ if (msg.data.hasOwnProperty('unitOfMeasure')) {
71
+ const val = msg.data['unitOfMeasure'];
72
+ payload['unitOfMeasure'] = unitsZiPulses[val];
73
+ }
74
+
75
+ return payload;
76
+ },
77
+ };
78
+
79
+
80
+ /* End ZiPulses */
81
+
82
+ const fzLocal = {
83
+ lixee_ha_electrical_measurement: {
84
+ cluster: 'haElectricalMeasurement',
85
+ type: ['attributeReport', 'readResponse'],
86
+ convert: (model, msg, publish, options, meta) => {
87
+ const result = {};
88
+
89
+ const elements = [
90
+ /* 0x0305 */ 'totalReactivePower',
91
+ /* 0x0505 */ 'rmsVoltage',
92
+ /* 0x0508 */ 'rmsCurrent',
93
+ /* 0x050A */ 'rmsCurrentMax',
94
+ /* 0x050B */ 'activePower',
95
+ /* 0x050D */ 'activePowerMax',
96
+ /* 0x050E */ 'reactivePower',
97
+ /* 0x050F */ 'apparentPower',
98
+ /* 0x0511 */ 'averageRmsVoltageMeasPeriod',
99
+ /* 0x0905 */ 'rmsVoltagePhB',
100
+ /* 0x0908 */ 'rmsCurrentPhB',
101
+ /* 0x090A */ 'rmsCurrentMaxPhB',
102
+ /* 0x090B */ 'activePowerPhB',
103
+ /* 0x090E */ 'reactivePowerPhB',
104
+ /* 0x090D */ 'activePowerMaxPhB',
105
+ /* 0x090F */ 'apparentPowerPhB',
106
+ /* 0x0911 */ 'averageRmsVoltageMeasurePeriodPhB',
107
+ /* 0x0A05 */ 'rmsVoltagePhC',
108
+ /* 0x0A08 */ 'rmsCurrentPhC',
109
+ /* 0x0A0A */ 'rmsCurrentMaxPhC',
110
+ /* 0x0A0D */ 'activePowerMaxPhC',
111
+ /* 0x0A0E */ 'reactivePowerPhC',
112
+ /* 0x0A0F */ 'apparentPowerPhC',
113
+ /* 0x0A11 */ 'averageRmsVoltageMeasPeriodPhC',
114
+ ];
115
+
116
+ for (const at of elements) {
117
+ const at_snake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
118
+ if (msg.data[at] != null) {
119
+ result[at_snake] = msg.data[at];
120
+ }
121
+ }
122
+ return result;
123
+ },
124
+ },
125
+ lixee_private_fz: {
126
+ cluster: 'liXeePrivate', // 0xFF66
127
+ type: ['attributeReport', 'readResponse'],
128
+ convert: (model, msg, publish, options, meta) => {
129
+ const result = {};
130
+ const elements = [
131
+ /* 0x0000 */ 'currentTarif',
132
+ /* 0x0001 */ 'tomorrowColor',
133
+ /* 0x0002 */ 'scheduleHPHC',
134
+ /* 0x0003 */ 'presencePotential',
135
+ /* 0x0004 */ 'startNoticeEJP',
136
+ /* 0x0005 */ 'warnDPS',
137
+ /* 0x0006 */ 'warnDIR1',
138
+ /* 0x0007 */ 'warnDIR2',
139
+ /* 0x0008 */ 'warnDIR3',
140
+ /* 0x0200 */ 'currentPrice',
141
+ /* 0x0201 */ 'currentIndexTarif',
142
+ /* 0x0202 */ 'currentDate',
143
+ /* 0x0203 */ 'activeEnerfyOutD01',
144
+ /* 0x0204 */ 'activeEnerfyOutD02',
145
+ /* 0x0205 */ 'activeEnerfyOutD03',
146
+ /* 0x0206 */ 'activeEnerfyOutD04',
147
+ /* 0x0207 */ 'injectedVA',
148
+ /* 0x0208 */ 'injectedVAMaxN',
149
+ /* 0x0209 */ 'injectedVAMaxN1',
150
+ /* 0x0210 */ 'injectedActiveLoadN',
151
+ /* 0x0211 */ 'injectedActiveLoadN1',
152
+ /* 0x0212 */ 'drawnVAMaxN1',
153
+ /* 0x0213 */ 'drawnVAMaxN1P2',
154
+ /* 0x0214 */ 'drawnVAMaxN1P3',
155
+ /* 0x0215 */ 'message1',
156
+ /* 0x0216 */ 'message2',
157
+ /* 0x0217 */ 'statusRegister',
158
+ /* 0x0218 */ 'startMobilePoint1',
159
+ /* 0x0219 */ 'stopMobilePoint1',
160
+ /* 0x0220 */ 'startMobilePoint2',
161
+ /* 0x0221 */ 'stopMobilePoint2',
162
+ /* 0x0222 */ 'startMobilePoint3',
163
+ /* 0x0223 */ 'stopMobilePoint3',
164
+ /* 0x0224 */ 'relais',
165
+ /* 0x0225 */ 'daysNumberCurrentCalendar',
166
+ /* 0x0226 */ 'daysNumberNextCalendar',
167
+ /* 0x0227 */ 'daysProfileCurrentCalendar',
168
+ /* 0x0228 */ 'daysProfileNextCalendar',
169
+ ];
170
+ const kWh_p = options && options.kWh_precision ? options.kWh_precision : 0;
171
+ for (const at of elements) {
172
+ const at_snake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
173
+ let val = msg.data[at];
174
+ if (val != null) {
175
+ if (val.hasOwnProperty('type') && val.type === 'Buffer') {
176
+ val = Buffer.from(val.data);
177
+ }
178
+ if (Buffer.isBuffer(val)) {
179
+ val = val.toString(); // Convert buffer to string
180
+ }
181
+ if (typeof val === 'string' || val instanceof String) {
182
+ val = val.replace(/\0/g, ''); // Remove all null chars when str
183
+ val = val.replace(/\s+/g, ' ').trim(); // Remove extra and leading spaces
184
+ }
185
+ switch (at) {
186
+ case 'activeEnerfyOutD01':
187
+ case 'activeEnerfyOutD02':
188
+ case 'activeEnerfyOutD03':
189
+ case 'activeEnerfyOutD04':
190
+ val = utils.precisionRound(val / 1000, kWh_p); // from Wh to kWh
191
+ break;
192
+ }
193
+ result[at_snake] = val;
194
+ }
195
+ }
196
+ return result;
197
+ },
198
+ },
199
+ lixee_metering: {
200
+ cluster: 'seMetering', // 0x0702
201
+ type: ['attributeReport', 'readResponse'],
202
+ convert: (model, msg, publish, options, meta) => {
203
+ const result = {};
204
+ const elements = [
205
+ /* 0x0000 */ 'currentSummDelivered',
206
+ /* 0x0001 */ 'currentSummReceived',
207
+ /* 0x0020 */ 'activeRegisterTierDelivered',
208
+ /* 0x0100 */ 'currentTier1SummDelivered',
209
+ /* 0x0102 */ 'currentTier2SummDelivered',
210
+ /* 0x0104 */ 'currentTier3SummDelivered',
211
+ /* 0x0106 */ 'currentTier4SummDelivered',
212
+ /* 0x0108 */ 'currentTier5SummDelivered',
213
+ /* 0x010A */ 'currentTier6SummDelivered',
214
+ /* 0x010C */ 'currentTier7SummDelivered',
215
+ /* 0x010E */ 'currentTier8SummDelivered',
216
+ /* 0x0110 */ 'currentTier9SummDelivered',
217
+ /* 0x0112 */ 'currentTier10SummDelivered',
218
+ /* 0x0307 */ 'siteId',
219
+ /* 0x0308 */ 'meterSerialNumber',
220
+ ];
221
+ const kWh_p = options && options.kWh_precision ? options.kWh_precision : 0;
222
+ for (const at of elements) {
223
+ const at_snake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
224
+ const val = msg.data[at];
225
+ if (val != null) {
226
+ result[at_snake] = val; // By default we assign raw value
227
+ switch (at) {
228
+ // If we receive a Buffer, transform to human readable text
229
+ case 'meterSerialNumber':
230
+ case 'siteId':
231
+ if (Buffer.isBuffer(val)) {
232
+ result[at_snake] = val.toString();
233
+ }
234
+ break;
235
+ case 'currentSummDelivered':
236
+ case 'currentSummReceived':
237
+ case 'currentTier1SummDelivered':
238
+ case 'currentTier2SummDelivered':
239
+ case 'currentTier3SummDelivered':
240
+ case 'currentTier4SummDelivered':
241
+ case 'currentTier5SummDelivered':
242
+ case 'currentTier6SummDelivered':
243
+ case 'currentTier7SummDelivered':
244
+ case 'currentTier8SummDelivered':
245
+ case 'currentTier9SummDelivered':
246
+ case 'currentTier10SummDelivered':
247
+ result[at_snake] = utils.precisionRound(((val[0] << 32) + val[1]) / 1000, kWh_p); // Wh to kWh
248
+ break;
249
+ }
250
+ }
251
+ }
252
+ // TODO: Check if all tarifs which doesn't publish "currentSummDelivered" use just Tier1 & Tier2
253
+ if (result['current_summ_delivered'] == 0 &&
254
+ (result['current_tier1_summ_delivered'] > 0 || result['current_tier2_summ_delivered'] > 0)) {
255
+ result['current_summ_delivered'] = result['current_tier1_summ_delivered'] + result['current_tier2_summ_delivered'];
256
+ }
257
+ return result;
258
+ },
259
+ },
260
+ };
261
+
262
+
263
+ // we are doing it with exclusion and not inclusion because the list is dynamic (based on zlinky mode),
264
+ // and change based on that. Just some few attributes are useless, so we exclude them
265
+ const tarifsDef = {
266
+ histo_BASE: {
267
+ fname: 'Historique - BASE',
268
+ currentTarf: 'BASE', excluded: [
269
+ 'HCHC',
270
+ 'HCHP',
271
+ 'HHPHC',
272
+ 'EJPHN',
273
+ 'EJPHPM',
274
+ 'BBRHCJB',
275
+ 'BBRHPJB',
276
+ 'BBRHCJW',
277
+ 'BBRHPJW',
278
+ 'BBRHCJR',
279
+ 'BBRHPJR',
280
+ 'DEMAIN',
281
+ 'PEJP',
282
+ ]},
283
+ histo_HCHP: {
284
+ fname: 'Historique - HCHP',
285
+ currentTarf: 'HC..', excluded: [
286
+ 'BASE',
287
+ 'EJPHN',
288
+ 'EJPHPM',
289
+ 'BBRHCJB',
290
+ 'BBRHPJB',
291
+ 'BBRHCJW',
292
+ 'BBRHPJW',
293
+ 'BBRHCJR',
294
+ 'BBRHPJR',
295
+ 'DEMAIN',
296
+ 'PEJP',
297
+ ]},
298
+ histo_EJP: {
299
+ fname: 'Historique - EJP',
300
+ currentTarf: 'EJP.', excluded: [
301
+ 'BASE',
302
+ 'HCHC',
303
+ 'HCHP',
304
+ 'BBRHCJB',
305
+ 'BBRHPJB',
306
+ 'BBRHCJW',
307
+ 'BBRHPJW',
308
+ 'BBRHCJR',
309
+ 'BBRHPJR',
310
+ 'DEMAIN',
311
+ ]},
312
+ histo_BBR: {
313
+ fname: 'Historique - BBR',
314
+ currentTarf: 'BBR', excluded: [
315
+ 'BASE',
316
+ 'HCHC',
317
+ 'HCHP',
318
+ 'EJPHN',
319
+ 'EJPHPM',
320
+ 'PEJP',
321
+ ]},
322
+ stand_SEM_WE_MERCR: {
323
+ fname: 'Standard - Sem WE Mercredi',
324
+ currentTarf: 'SEM WE MERCREDI', excluded: [
325
+ 'EASF04',
326
+ 'EASF05',
327
+ 'EASF06',
328
+ 'EASF07',
329
+ 'EASF08',
330
+ 'EASF09',
331
+ 'EASF10',
332
+ 'EASD02',
333
+ 'EASD03',
334
+ 'EASD04',
335
+ 'DPM1',
336
+ 'DPM2',
337
+ 'DPM3',
338
+ 'FPM1',
339
+ 'FPM2',
340
+ 'FPM3',
341
+ 'NJOURF',
342
+ 'NJOURF+1',
343
+ 'PJOURF+1',
344
+ 'PPOINTE1',
345
+ ]},
346
+ stand_BASE: {
347
+ fname: 'Standard - BASE',
348
+ currentTarf: 'BASE',
349
+ excluded: [
350
+ 'EASF03',
351
+ 'EASF04',
352
+ 'EASF05',
353
+ 'EASF06',
354
+ 'EASF07',
355
+ 'EASF08',
356
+ 'EASF09',
357
+ 'EASF10',
358
+ 'EASD02',
359
+ 'EASD03',
360
+ 'EASD04',
361
+ 'DPM1',
362
+ 'DPM2',
363
+ 'DPM3',
364
+ 'FPM1',
365
+ 'FPM2',
366
+ 'FPM3',
367
+ 'NJOURF',
368
+ 'NJOURF+1',
369
+ 'PJOURF+1',
370
+ 'PPOINTE1',
371
+ ]},
372
+ stand_HPHC: {
373
+ fname: 'Standard - Heure Pleine Heure Creuse',
374
+ currentTarf: 'H PLEINE/CREUSE', excluded: [
375
+ 'EASF03',
376
+ 'EASF04',
377
+ 'EASF05',
378
+ 'EASF06',
379
+ 'EASF07',
380
+ 'EASF08',
381
+ 'EASF09',
382
+ 'EASF10',
383
+ 'EASD03',
384
+ 'EASD04',
385
+ 'DPM1',
386
+ 'DPM2',
387
+ 'DPM3',
388
+ 'FPM1',
389
+ 'FPM2',
390
+ 'FPM3',
391
+ 'NJOURF',
392
+ 'NJOURF+1',
393
+ 'PJOURF+1',
394
+ 'PPOINTE1',
395
+ ]},
396
+ };
397
+
398
+
399
+ const linkyModeDef = {
400
+ standard: 'standard',
401
+ legacy: 'historique',
402
+ };
403
+
404
+ const linkyPhaseDef = {
405
+ single: 'single_phase',
406
+ three: 'three_phase',
407
+ all: 'both',
408
+ };
409
+
410
+ const clustersDef = {
411
+ _0xFF66: 'liXeePrivate', // 0xFF66
412
+ _0x0B04: 'haElectricalMeasurement', // 0x0B04
413
+ _0x0702: 'seMetering', // 0x0702
414
+ _0x0B01: 'haMeterIdentification', // 0x0B01
415
+ };
416
+
417
+
418
+ // full list available on https://github.com/fairecasoimeme/Zlinky_TIC/blob/master/README.md
419
+
420
+ // Properties must be EAXCTLY ".split(/(?=[A-Z])/).join('_').toLowerCase()" of att
421
+ const exposedData = [
422
+ // Historique
423
+ {cluster: clustersDef._0x0702, att: 'meterSerialNumber', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.text('ADCO', ea.STATE).withProperty('meter_serial_number').withDescription('Serial Number')},
424
+ {cluster: clustersDef._0x0702, att: 'currentSummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BASE', ea.STATE).withUnit('kWh').withProperty('current_summ_delivered').withDescription('Base index')},
425
+ {cluster: clustersDef._0xFF66, att: 'currentTarif', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.text('OPTARIF', ea.STATE).withProperty('current_tarif').withDescription('Tarif option')},
426
+ {cluster: clustersDef._0x0B01, att: 'availablePower', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ISOUSC', ea.STATE).withUnit('A').withProperty('available_power').withDescription('Subscribed intensity level')},
427
+ {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HCHC', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('HCHC index')},
428
+ {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HCHP', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('HCHP index')},
429
+ {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('EJPHN', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('EJPHN index')},
430
+ {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('EJPHPM', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('EJPHPM index')},
431
+ {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJB', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('BBRHCJB index')},
432
+ {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJB', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('BBRHPJB index')},
433
+ {cluster: clustersDef._0x0702, att: 'currentTier3SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJW', ea.STATE).withUnit('kWh').withProperty('current_tier3_summ_delivered').withDescription('BBRHCJW index')},
434
+ {cluster: clustersDef._0x0702, att: 'currentTier4SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJW', ea.STATE).withUnit('kWh').withProperty('current_tier4_summ_delivered').withDescription('BBRHPJW index')},
435
+ {cluster: clustersDef._0x0702, att: 'currentTier5SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJR', ea.STATE).withUnit('kWh').withProperty('current_tier5_summ_delivered').withDescription('BBRHCJR index')},
436
+ {cluster: clustersDef._0x0702, att: 'currentTier6SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJR', ea.STATE).withUnit('kWh').withProperty('current_tier6_summ_delivered').withDescription('BBRHPJR index')},
437
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrent', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST', ea.STATE).withUnit('A').withProperty('rms_current').withDescription('RMS current')},
438
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrent', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST1', ea.STATE).withUnit('A').withProperty('rms_current').withDescription('RMS current (phase 1)')},
439
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrentPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST2', ea.STATE).withUnit('A').withProperty('rms_current_ph_b').withDescription('RMS current (phase 2)')},
440
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrentPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST3', ea.STATE).withUnit('A').withProperty('rms_current_ph_c').withDescription('RMS current (phase 3)')},
441
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrentMax', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX', ea.STATE).withUnit('A').withProperty('rms_current_max').withDescription('RMS current peak')},
442
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrentMax', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX1', ea.STATE).withUnit('A').withProperty('rms_current_max').withDescription('RMS current peak (phase 1)')},
443
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrentMaxPhB', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX2', ea.STATE).withUnit('A').withProperty('rms_current_max_ph_b').withDescription('RMS current peak (phase 2)')},
444
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrentMaxPhC', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX3', ea.STATE).withUnit('A').withProperty('rms_current_max_ph_c').withDescription('RMS current peak (phase 3)')},
445
+ {cluster: clustersDef._0x0B04, att: 'activePowerMax', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PMAX', ea.STATE).withUnit('W').withProperty('active_power_max').withDescription('Three-phase power peak')},
446
+ {cluster: clustersDef._0x0B04, att: 'apparentPower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PAPP', ea.STATE).withUnit('VA').withProperty('apparent_power').withDescription('Apparent power')},
447
+ {cluster: clustersDef._0x0702, att: 'activeRegisterTierDelivered', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.text('PTEC', ea.STATE).withProperty('active_register_tier_delivered').withDescription('Current pricing period')},
448
+ {cluster: clustersDef._0xFF66, att: 'tomorrowColor', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.text('DEMAIN', ea.STATE).withProperty('tomorrow_color').withDescription('Tomorrow color')},
449
+ {cluster: clustersDef._0xFF66, att: 'scheduleHPHC', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HHPHC', ea.STATE).withProperty('schedule_h_p_h_c').withDescription('Schedule HPHC')},
450
+ {cluster: clustersDef._0xFF66, att: 'presencePotential', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PPOT', ea.STATE).withProperty('presence_potential').withDescription('Presence of potentials')},
451
+ {cluster: clustersDef._0xFF66, att: 'startNoticeEJP', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PEJP', ea.STATE).withUnit('min').withProperty('start_notice_e_j_p').withDescription('EJP start notice (30min)')},
452
+ {cluster: clustersDef._0xFF66, att: 'warnDPS', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ADPS', ea.STATE).withUnit('A').withProperty('warn_d_p_s').withDescription('Subscribed Power Exceeded Warning')},
453
+ {cluster: clustersDef._0xFF66, att: 'warnDIR1', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ADIR1', ea.STATE).withUnit('A').withProperty('warn_d_i_r1').withDescription('Over Current Warning (phase 1)')},
454
+ {cluster: clustersDef._0xFF66, att: 'warnDIR2', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ADIR2', ea.STATE).withUnit('A').withProperty('warn_d_i_r2').withDescription('Over Current Warning (phase 2)')},
455
+ {cluster: clustersDef._0xFF66, att: 'warnDIR3', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ADIR3', ea.STATE).withUnit('A').withProperty('warn_d_i_r3').withDescription('Over Current Warning (phase 3)')},
456
+ {cluster: clustersDef._0x0702, att: 'meterSerialNumber', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('ADSC', ea.STATE).withProperty('meter_serial_number').withDescription('Serial Number')},
457
+ {cluster: clustersDef._0xFF66, att: 'currentTarif', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('NGTF', ea.STATE).withProperty('current_tarif').withDescription('Supplier pricing schedule name')},
458
+ {cluster: clustersDef._0xFF66, att: 'currentPrice', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('LTARF', ea.STATE).withProperty('current_price').withDescription('Current supplier price label')},
459
+ {cluster: clustersDef._0xFF66, att: 'currentIndexTarif', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('NTARF', ea.STATE).withProperty('current_index_tarif').withDescription('Current tariff index number')},
460
+ {cluster: clustersDef._0x0B01, att: 'softwareRevision', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('VTIC', ea.STATE).withProperty('software_revision').withDescription('Customer tele-information protocol version')},
461
+ {cluster: clustersDef._0xFF66, att: 'currentDate', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('DATE', ea.STATE).withProperty('current_date').withDescription('Current date and time')},
462
+ {cluster: clustersDef._0x0702, att: 'currentSummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EAST', ea.STATE).withUnit('kWh').withProperty('current_summ_delivered').withDescription('Total active power delivered')},
463
+ {cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF01', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('Total provider active power delivered (index 01)')},
464
+ {cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF02', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('Total provider active power delivered (index 02)')},
465
+ {cluster: clustersDef._0x0702, att: 'currentTier3SummDelivered', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF03', ea.STATE).withUnit('kWh').withProperty('current_tier3_summ_delivered').withDescription('Total provider active power delivered (index 03)')},
466
+ {cluster: clustersDef._0x0702, att: 'currentTier4SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF04', ea.STATE).withUnit('kWh').withProperty('current_tier4_summ_delivered').withDescription('Total provider active power delivered (index 04)')},
467
+ {cluster: clustersDef._0x0702, att: 'currentTier5SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF05', ea.STATE).withUnit('kWh').withProperty('current_tier5_summ_delivered').withDescription('Total provider active power delivered (index 05)')},
468
+ {cluster: clustersDef._0x0702, att: 'currentTier6SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF06', ea.STATE).withUnit('kWh').withProperty('current_tier6_summ_delivered').withDescription('Total provider active power delivered (index 06)')},
469
+ {cluster: clustersDef._0x0702, att: 'currentTier7SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF07', ea.STATE).withUnit('kWh').withProperty('current_tier7_summ_delivered').withDescription('Total provider active power delivered (index 07)')},
470
+ {cluster: clustersDef._0x0702, att: 'currentTier8SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF08', ea.STATE).withUnit('kWh').withProperty('current_tier8_summ_delivered').withDescription('Total provider active power delivered (index 08)')},
471
+ {cluster: clustersDef._0x0702, att: 'currentTier9SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF09', ea.STATE).withUnit('kWh').withProperty('current_tier9_summ_delivered').withDescription('Total provider active power delivered (index 09)')},
472
+ {cluster: clustersDef._0x0702, att: 'currentTier10SummDelivered', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF10', ea.STATE).withUnit('kWh').withProperty('current_tier10_summ_delivered').withDescription('Total provider active power delivered (index 10)')},
473
+ {cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD01', reportable: true, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD01', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d01').withDescription('Active energy withdrawn Distributor (index 01)')},
474
+ {cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD02', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD02', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d02').withDescription('Active energy withdrawn Distributor (index 02)')},
475
+ {cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD03', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD03', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d03').withDescription('Active energy withdrawn Distributor (index 03)')},
476
+ {cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD04', reportable: false, report: {change: 100}, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD04', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d04').withDescription('Active energy withdrawn Distributor (index 04)')},
477
+ {cluster: clustersDef._0x0702, att: 'currentSummReceived', reportable: true, report: {change: 100}, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EAIT', ea.STATE).withUnit('kWh').withProperty('current_summ_received').withDescription('Total active power injected')},
478
+ {cluster: clustersDef._0x0B04, att: 'totalReactivePower', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('ERQ1', ea.STATE).withUnit('VArh').withProperty('total_reactive_power').withDescription('Total reactive power (Q1)')},
479
+ {cluster: clustersDef._0x0B04, att: 'reactivePower', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('ERQ2', ea.STATE).withUnit('VArh').withProperty('reactive_power').withDescription('Total reactive power (Q2)')},
480
+ {cluster: clustersDef._0x0B04, att: 'reactivePowerPhB', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('ERQ3', ea.STATE).withUnit('VArh').withProperty('reactive_power_ph_b').withDescription('Total reactive power (Q3)')},
481
+ {cluster: clustersDef._0x0B04, att: 'reactivePowerPhC', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('ERQ4', ea.STATE).withUnit('VArh').withProperty('reactive_power_ph_c').withDescription('Total reactive power (Q4)')},
482
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrent', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('IRMS1', ea.STATE).withUnit('A').withProperty('rms_current').withDescription('RMS current')},
483
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrentPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('IRMS2', ea.STATE).withUnit('A').withProperty('rms_current_ph_b').withDescription('RMS current (phase 2)')},
484
+ {cluster: clustersDef._0x0B04, att: 'rmsCurrentPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('IRMS3', ea.STATE).withUnit('A').withProperty('rms_current_ph_c').withDescription('RMS current (phase 3)')},
485
+ {cluster: clustersDef._0x0B04, att: 'rmsVoltage', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('URMS1', ea.STATE).withUnit('V').withProperty('rms_voltage').withDescription('RMS voltage')},
486
+ {cluster: clustersDef._0x0B04, att: 'rmsVoltagePhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('URMS2', ea.STATE).withUnit('V').withProperty('rms_voltage_ph_b').withDescription('RMS voltage (phase 2)')},
487
+ {cluster: clustersDef._0x0B04, att: 'rmsVoltagePhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('URMS3', ea.STATE).withUnit('V').withProperty('rms_voltage_ph_c').withDescription('RMS voltage (phase 3)')},
488
+ {cluster: clustersDef._0x0B01, att: 'availablePower', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('PREF', ea.STATE).withUnit('kVA').withProperty('available_power').withDescription('Apparent power of reference')},
489
+ {cluster: clustersDef._0xFF66, att: 'statusRegister', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('STGE', ea.STATE).withProperty('status_register').withDescription('Register of Statutes')},
490
+ {cluster: clustersDef._0x0B01, att: 'powerThreshold', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('PCOUP', ea.STATE).withUnit('kVA').withProperty('power_threshold').withDescription('Apparent power threshold')},
491
+ {cluster: clustersDef._0xFF66, att: 'injectedVA', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTI', ea.STATE).withUnit('VA').withProperty('injected_v_a').withDescription('Instantaneous apparent power injected')},
492
+ {cluster: clustersDef._0xFF66, att: 'injectedVAMaxN', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXIN', ea.STATE).withUnit('VA').withProperty('injected_v_a_max_n').withDescription('Apparent power max. injected n')},
493
+ {cluster: clustersDef._0xFF66, att: 'injectedVAMaxN1', reportable: false, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXIN-1', ea.STATE).withUnit('VA').withProperty('injected_v_a_max_n1').withDescription('Apparent power max. injected n-1')},
494
+ {cluster: clustersDef._0x0B04, att: 'activePower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('CCASN', ea.STATE).withUnit('W').withProperty('active_power').withDescription('Current point of the active load curve drawn')},
495
+ {cluster: clustersDef._0x0B04, att: 'activePowerPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('CCASN-1', ea.STATE).withUnit('W').withProperty('active_power_ph_b').withDescription('Previous point of the active load curve drawn')},
496
+ {cluster: clustersDef._0xFF66, att: 'injectedActiveLoadN', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('CCAIN', ea.STATE).withUnit('W').withProperty('injected_active_load_n').withDescription('Point n of the withdrawn active load curve')},
497
+ {cluster: clustersDef._0xFF66, att: 'injectedActiveLoadN1', reportable: false, onlyProducer: true, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('CCAIN-1', ea.STATE).withUnit('W').withProperty('injected_active_load_n1').withDescription('Point n-1 of the withdrawn active load curve')},
498
+ {cluster: clustersDef._0x0B04, att: 'averageRmsVoltageMeasPeriod', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('UMOY1', ea.STATE).withUnit('V').withProperty('average_rms_voltage_meas_period').withDescription('Average RMS voltage (phase 1)')},
499
+ {cluster: clustersDef._0x0B04, att: 'averageRmsVoltageMeasurePeriodPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('UMOY2', ea.STATE).withUnit('V').withProperty('average_rms_voltage_measure_period_ph_b').withDescription('Average RMS voltage (phase 2)')},
500
+ {cluster: clustersDef._0x0B04, att: 'averageRmsVoltageMeasPeriodPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('UMOY3', ea.STATE).withUnit('V').withProperty('average_rms_voltage_meas_period_ph_c').withDescription('Average RMS voltage (phase 3)')},
501
+ {cluster: clustersDef._0x0B04, att: 'apparentPower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTS', ea.STATE).withUnit('VA').withProperty('apparent_power').withDescription('Immediate apparent power delivered')},
502
+ {cluster: clustersDef._0x0B04, att: 'apparentPower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTS1', ea.STATE).withUnit('VA').withProperty('apparent_power').withDescription('Immediate apparent power delivered (phase 1)')},
503
+ {cluster: clustersDef._0x0B04, att: 'apparentPowerPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTS2', ea.STATE).withUnit('VA').withProperty('apparent_power_ph_b').withDescription('Immediate apparent power delivered (phase 2)')},
504
+ {cluster: clustersDef._0x0B04, att: 'apparentPowerPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTS3', ea.STATE).withUnit('VA').withProperty('apparent_power_ph_c').withDescription('Immediate apparent power delivered (phase 3)')},
505
+ {cluster: clustersDef._0x0B04, att: 'activePowerMax', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN', ea.STATE).withUnit('VA').withProperty('active_power_max').withDescription('Apparent power delivered peak')},
506
+ {cluster: clustersDef._0x0B04, att: 'activePowerMax', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN1', ea.STATE).withUnit('VA').withProperty('active_power_max').withDescription('Apparent power delivered peak (phase 1)')},
507
+ {cluster: clustersDef._0x0B04, att: 'activePowerMaxPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN2', ea.STATE).withUnit('VA').withProperty('active_power_max_ph_b').withDescription('Apparent power delivered peak (phase 2)')},
508
+ {cluster: clustersDef._0x0B04, att: 'activePowerMaxPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN3', ea.STATE).withUnit('VA').withProperty('active_power_max_ph_c').withDescription('Apparent power delivered peak (phase 3)')},
509
+ {cluster: clustersDef._0xFF66, att: 'drawnVAMaxN1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN-1', ea.STATE).withUnit('VA').withProperty('drawn_v_a_max_n1').withDescription('Apparent power max. draw-off n-1')},
510
+ {cluster: clustersDef._0xFF66, att: 'drawnVAMaxN1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN1-1', ea.STATE).withUnit('VA').withProperty('drawn_v_a_max_n1').withDescription('Apparent power max. draw-off n-1 (phase 1)')},
511
+ {cluster: clustersDef._0xFF66, att: 'drawnVAMaxN1P2', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN2-1', ea.STATE).withUnit('VA').withProperty('drawn_v_a_max_n1_p2').withDescription('Apparent power max. draw-off n-1 (phase 2)')},
512
+ {cluster: clustersDef._0xFF66, att: 'drawnVAMaxN1P3', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN3-1', ea.STATE).withUnit('VA').withProperty('drawn_v_a_max_n1_p3').withDescription('Apparent power max. draw-off n-1 (phase 3)')},
513
+ {cluster: clustersDef._0xFF66, att: 'message1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('MSG1', ea.STATE).withProperty('message1').withDescription('Message short')},
514
+ {cluster: clustersDef._0xFF66, att: 'message2', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('MSG2', ea.STATE).withProperty('message2').withDescription('Message ultra-short')},
515
+ {cluster: clustersDef._0x0702, att: 'siteId', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('PRM', ea.STATE).withProperty('site_id').withDescription('PRM number')},
516
+ {cluster: clustersDef._0xFF66, att: 'startMobilePoint1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('DPM1', ea.STATE).withProperty('start_mobile_point1').withDescription('Start mobile point 1')},
517
+ {cluster: clustersDef._0xFF66, att: 'stopMobilePoint1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('FPM1', ea.STATE).withProperty('stop_mobile_point1').withDescription('Stop mobile point 1')},
518
+ {cluster: clustersDef._0xFF66, att: 'startMobilePoint2', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('DPM2', ea.STATE).withProperty('start_mobile_point2').withDescription('Start mobile point 2')},
519
+ {cluster: clustersDef._0xFF66, att: 'stopMobilePoint2', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('FPM2', ea.STATE).withProperty('stop_mobile_point2').withDescription('Stop mobile point 2')},
520
+ {cluster: clustersDef._0xFF66, att: 'startMobilePoint3', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('DPM3', ea.STATE).withProperty('start_mobile_point3').withDescription('Start mobile point 3')},
521
+ {cluster: clustersDef._0xFF66, att: 'stopMobilePoint3', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('FPM3', ea.STATE).withProperty('stop_mobile_point3').withDescription('Stop mobile point 3')},
522
+ {cluster: clustersDef._0xFF66, att: 'relais', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('RELAIS', ea.STATE).withProperty('relais')},
523
+ {cluster: clustersDef._0xFF66, att: 'daysNumberCurrentCalendar', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('NJOURF', ea.STATE).withProperty('days_number_current_calendar').withDescription('Current day number supplier calendar')},
524
+ {cluster: clustersDef._0xFF66, att: 'daysNumberNextCalendar', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('NJOURF+1', ea.STATE).withProperty('days_number_next_calendar').withDescription('Next day number supplier calendar')},
525
+ {cluster: clustersDef._0xFF66, att: 'daysProfileCurrentCalendar', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('PJOURF+1', ea.STATE).withProperty('days_profile_current_calendar').withDescription('Profile of the next supplier calendar day')},
526
+ {cluster: clustersDef._0xFF66, att: 'daysProfileNextCalendar', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('PPOINTE1', ea.STATE).withProperty('days_profile_next_calendar').withDescription('Profile of the next check-in day')},
527
+ ];
528
+
529
+ function getCurrentConfig(device, options, logger=console) {
530
+ let endpoint;
531
+ try {
532
+ endpoint = device.getEndpoint(1);
533
+ } catch (error) {
534
+ logger.debug(error);
535
+ }
536
+
537
+ function getConfig(targetOption, bitLinkyMode, valueTrue, valueFalse) {
538
+ const valueDefault = valueFalse;
539
+ if (options && options.hasOwnProperty(targetOption) && options[targetOption] != 'auto') {
540
+ if (options[targetOption] === 'true' || options[targetOption] === 'false') {
541
+ return options[targetOption] === 'true'; // special case for production
542
+ }
543
+ return options[targetOption];
544
+ }
545
+
546
+ let lMode;
547
+ try {
548
+ lMode = endpoint.clusters[clustersDef._0xFF66].attributes['linkyMode'];
549
+ lMode.raiseError; // raise if undefined
550
+ return (lMode >> bitLinkyMode & 1) == 1 ? valueTrue : valueFalse;
551
+ } catch (err) {
552
+ logger.warn(`Was not able to detect the Linky `+ targetOption +`. Default to ` + valueDefault);
553
+ return valueDefault; // default value in the worst case
554
+ }
555
+ }
556
+
557
+ const linkyMode = getConfig('linky_mode', 0, linkyModeDef.standard, linkyModeDef.legacy);
558
+
559
+ const linkyPhase = getConfig('energy_phase', 1, linkyPhaseDef.three, linkyPhaseDef.single);
560
+
561
+ let linkyProduction = false; // In historique we can't be producer
562
+
563
+ if (linkyMode == linkyModeDef.standard) {
564
+ linkyProduction = getConfig('production', 2, true, false);
565
+ }
566
+
567
+ // Main filter
568
+ let myExpose = exposedData
569
+ .filter((e) => e.linkyMode == linkyMode && (e.linkyPhase == linkyPhase || e.linkyPhase == linkyPhaseDef.all) && (linkyProduction || !e.onlyProducer));
570
+
571
+ // Filter even more, based on our current tarif
572
+ let currentTarf = '';
573
+
574
+ if (options && options.hasOwnProperty('tarif') && options['tarif'] != 'auto') {
575
+ currentTarf = Object.entries(tarifsDef).find(( [k, v] ) => (v.fname == options['tarif']))[1].currentTarf;
576
+ } else {
577
+ try {
578
+ const lixAtts = endpoint.clusters[clustersDef._0xFF66].attributes;
579
+ lixAtts.raiseIfEmpty;
580
+ currentTarf = fzLocal.lixee_private_fz.convert({}, {data: lixAtts}).current_tarif;
581
+ } catch (error) {
582
+ logger.warn(`Not able to detect the current tarif. Not filtering any expose...`);
583
+ }
584
+ }
585
+
586
+ logger.debug(`zlinky config: ` + linkyMode + `, `+ linkyPhase + `, `+ linkyProduction.toString() +`, `+ currentTarf);
587
+
588
+ switch (currentTarf) {
589
+ case linkyMode == linkyModeDef.legacy && tarifsDef.histo_BASE.currentTarf:
590
+ myExpose = myExpose.filter((a) => !tarifsDef.histo_BASE.excluded.includes(a.exposes.name));
591
+ break;
592
+ case linkyMode == linkyModeDef.legacy && tarifsDef.histo_HCHP.currentTarf:
593
+ myExpose = myExpose.filter((a) => !tarifsDef.histo_HCHP.excluded.includes(a.exposes.name));
594
+ break;
595
+ case linkyMode == linkyModeDef.legacy && tarifsDef.histo_EJP.currentTarf:
596
+ myExpose = myExpose.filter((a) => !tarifsDef.histo_EJP.excluded.includes(a.exposes.name));
597
+ break;
598
+ case linkyMode == linkyModeDef.legacy && currentTarf && currentTarf.startsWith(tarifsDef.histo_BBR.currentTarf):
599
+ myExpose = myExpose.filter((a) => !tarifsDef.histo_BBR.excluded.includes(a.exposes.name));
600
+ break;
601
+ case linkyMode == linkyModeDef.standard && tarifsDef.stand_SEM_WE_MERCR.currentTarf:
602
+ myExpose = myExpose.filter((a) => !tarifsDef.stand_SEM_WE_MERCR.excluded.includes(a.exposes.name));
603
+ break;
604
+ case linkyMode == linkyModeDef.standard && tarifsDef.stand_HPHC.currentTarf:
605
+ myExpose = myExpose.filter((a) => !tarifsDef.stand_HPHC.excluded.includes(a.exposes.name));
606
+ break;
607
+ case linkyMode == linkyModeDef.standard && tarifsDef.stand_BASE.currentTarf:
608
+ myExpose = myExpose.filter((a) => !tarifsDef.stand_BASE.excluded.includes(a.exposes.name));
609
+ break;
610
+ default:
611
+ break;
612
+ }
613
+
614
+ // Filter exposed attributes with user whitelist
615
+ if (options && options.hasOwnProperty('tic_command_whitelist')) {
616
+ const tic_commands_str = options['tic_command_whitelist'].toUpperCase();
617
+ if (tic_commands_str !== 'ALL') {
618
+ const tic_commands = tic_commands_str.split(',').map((a) => a.trim());
619
+ myExpose = myExpose.filter((a) => tic_commands.includes(a.exposes.name));
620
+ }
621
+ }
622
+
623
+ return myExpose;
624
+ }
625
+ module.exports = [
626
+ {
627
+ zigbeeModel: ['ZLinky_TIC', 'ZLinky_TIC\u0000'],
628
+ model: 'ZLinky_TIC',
629
+ vendor: 'LiXee',
630
+ description: 'Lixee ZLinky',
631
+ fromZigbee: [fzLocal.lixee_metering, fz.meter_identification, fzLocal.lixee_ha_electrical_measurement, fzLocal.lixee_private_fz],
632
+ toZigbee: [],
633
+ exposes: (device, options) => {
634
+ // docs generation
635
+ let exposes;
636
+ if (device == null && options == null) {
637
+ exposes = exposedData.map((e) => e.exposes)
638
+ .filter((value, index, self) =>
639
+ index === self.findIndex((t) => (
640
+ t.property === value.property // Remove duplicates
641
+ )),
642
+ );
643
+ } else {
644
+ exposes = getCurrentConfig(device, options).map((e) => e.exposes);
645
+ }
646
+
647
+ exposes.push(e.linkquality());
648
+ return exposes;
649
+ },
650
+ options: [
651
+ exposes.options.measurement_poll_interval(),
652
+ exposes.enum(`linky_mode`, ea.SET, ['auto', linkyModeDef.legacy, linkyModeDef.standard])
653
+ .withDescription(`Counter with TIC in mode standard or historique. May require restart (default: auto)`),
654
+ exposes.enum(`energy_phase`, ea.SET, ['auto', linkyPhaseDef.single, linkyPhaseDef.three])
655
+ .withDescription(`Power with single or three phase. May require restart (default: auto)`),
656
+ exposes.enum(`production`, ea.SET, ['auto', 'true', 'false']).withDescription(`If you produce energy back to the grid (works ONLY when linky_mode: ${linkyModeDef.standard}, default: auto)`),
657
+ exposes.enum(`tarif`, ea.SET, [...Object.entries(tarifsDef).map(( [k, v] ) => (v.fname)), 'auto'])
658
+ .withDescription(`Overrides the automatic current tarif. This option will exclude unnecesary attributes. Open a issue to support more of them. Default: auto`),
659
+ exposes.options.precision(`kWh`),
660
+ exposes.numeric(`measurement_poll_chunk`, ea.SET).withValueMin(1).withDescription(`During the poll, request multiple exposes to the Zlinky at once for reducing Zigbee network overload. Too much request at once could exceed device limit. Requieres Z2M restart. Default: 1`),
661
+ exposes.text(`tic_command_whitelist`, ea.SET).withDescription(`List of TIC commands to be exposed (separated by comma). Reconfigure device after change. Default: all`),
662
+ ],
663
+ configure: async (device, coordinatorEndpoint, logger, options) => {
664
+ const endpoint = device.getEndpoint(1);
665
+
666
+ await reporting.bind(endpoint, coordinatorEndpoint, [
667
+ clustersDef._0x0702, /* seMetering */
668
+ clustersDef._0x0B01, /* haMeterIdentification */
669
+ clustersDef._0x0B04, /* haElectricalMeasurement */
670
+ clustersDef._0xFF66, /* liXeePrivate */
671
+ ]);
672
+
673
+ await endpoint.read('liXeePrivate', ['linkyMode', 'currentTarif'], {manufacturerCode: null})
674
+ .catch((e) => {
675
+ // https://github.com/Koenkk/zigbee2mqtt/issues/11674
676
+ logger.warn(`Failed to read zigbee attributes: ${e}`);
677
+ });
678
+
679
+ const configReportings = [];
680
+ const suscribeNew = getCurrentConfig(device, options, logger).filter((e) => e.reportable);
681
+
682
+ const unsuscribe = endpoint.configuredReportings
683
+ .filter((e) => !suscribeNew.some((r) => e.cluster.name == r.cluster && e.attribute.name == r.att));
684
+ // Unsuscribe reports that doesn't correspond with the current config
685
+ (await Promise.allSettled(unsuscribe.map((e) => endpoint.configureReporting(e.cluster.name, reporting.payload(e.attribute.name, e.minimumReportInterval, 65535, e.reportableChange), {manufacturerCode: null}))))
686
+ .filter((e) => e.status == 'rejected')
687
+ .forEach((e) => {
688
+ throw e.reason;
689
+ });
690
+
691
+ for (const e of suscribeNew) {
692
+ let params = {
693
+ att: e.att,
694
+ min: repInterval.MINUTE,
695
+ max: repInterval.MINUTES_15,
696
+ change: 1,
697
+ };
698
+ // Override reportings
699
+ if (e.hasOwnProperty('report')) {
700
+ params = {...params, ...e.report};
701
+ }
702
+ configReportings.push(endpoint
703
+ .configureReporting(
704
+ e.cluster, reporting.payload(params.att, params.min, params.max, params.change),
705
+ {manufacturerCode: null}),
706
+ );
707
+ }
708
+ (await Promise.allSettled(configReportings))
709
+ .filter((e) => e.status == 'rejected')
710
+ .forEach((e) => {
711
+ throw e.reason;
712
+ });
713
+ },
714
+ ota: ota.lixee,
715
+ onEvent: async (type, data, device, options) => {
716
+ const endpoint = device.getEndpoint(1);
717
+ if (type === 'start') {
718
+ endpoint.read('liXeePrivate', ['linkyMode', 'currentTarif'], {manufacturerCode: null})
719
+ .catch((e) => {
720
+ // https://github.com/Koenkk/zigbee2mqtt/issues/11674
721
+ console.warn(`Failed to read zigbee attributes: ${e}`);
722
+ });
723
+ } else if (type === 'stop') {
724
+ clearInterval(globalStore.getValue(device, 'interval'));
725
+ globalStore.clearValue(device, 'interval');
726
+ } else if (!globalStore.hasValue(device, 'interval')) {
727
+ const seconds = options && options.measurement_poll_interval ? options.measurement_poll_interval : 60;
728
+ const measurement_poll_chunk = options && options.measurement_poll_chunk ? options.measurement_poll_chunk : 1;
729
+
730
+ const interval = setInterval(async () => {
731
+ const currentExposes = getCurrentConfig(device, options)
732
+ .filter((e) => !endpoint.configuredReportings.some((r) => r.cluster.name == e.cluster && r.attribute.name == e.att));
733
+
734
+ for (const key in clustersDef) {
735
+ if (Object.hasOwnProperty.call(clustersDef, key)) {
736
+ const cluster = clustersDef[key];
737
+
738
+ const targ = currentExposes.filter((e)=> e.cluster == cluster).map((e)=> e.att);
739
+ if (targ.length) {
740
+ let i; let j;
741
+ // Split array by chunks
742
+ for (i = 0, j = targ.length; i < j; i += measurement_poll_chunk) {
743
+ await endpoint
744
+ .read(cluster, targ.slice(i, i + measurement_poll_chunk), {manufacturerCode: null})
745
+ .catch((e) => {
746
+ // https://github.com/Koenkk/zigbee2mqtt/issues/11674
747
+ console.warn(`Failed to read zigbee attributes: ${e}`);
748
+ });
749
+ }
750
+ }
751
+ }
752
+ }
753
+ }, seconds * 1000);
754
+ globalStore.putValue(device, 'interval', interval);
755
+ }
756
+ },
757
+ },
758
+
759
+ {
760
+ zigbeeModel: ['ZiPulses'],
761
+ model: 'ZiPulses',
762
+ vendor: 'LiXee',
763
+ description: 'Lixee ZiPulses',
764
+ fromZigbee: [fz.battery, fz.temperature, fz.metering, fzZiPulses],
765
+ toZigbee: [tzSeMetering],
766
+ exposes: [e.battery_voltage(), e.temperature(),
767
+ exposes.numeric('multiplier', ea.STATE_SET).withValueMin(1).withValueMax(1000).withDescription('It is necessary to press the link button to update'),
768
+ exposes.numeric('divisor', ea.STATE_SET).withValueMin(1).withValueMax(1000).withDescription('It is necessary to press the link button to update'),
769
+ exposes.enum('unitOfMeasure', ea.STATE_SET, unitsZiPulses).withDescription('It is necessary to press the link button to update'),
770
+ exposes.numeric('energy', ea.STATE),
771
+ ],
772
+ configure: async (device, coordinatorEndpoint, logger) => {
773
+ const endpoint = device.getEndpoint(1);
774
+ const binds = ['genPowerCfg', 'seMetering', 'msTemperatureMeasurement'];
775
+ await reporting.bind(endpoint, coordinatorEndpoint, binds);
776
+ await endpoint.read('seMetering', ['divisor', 'unitOfMeasure', 'multiplier']);
777
+ },
778
+ },
779
+ ];