@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,11 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ zigbeeModel: ['DM A60F'],
6
+ model: 'DM A60F',
7
+ vendor: 'CY-LIGHTING',
8
+ description: '6W smart dimmable E27 lamp 2700K',
9
+ extend: extend.light_onoff_brightness(),
10
+ },
11
+ ];
@@ -0,0 +1,26 @@
1
+ const exposes = require('../lib/exposes');
2
+ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
+ const tz = require('../converters/toZigbee');
4
+ const reporting = require('../lib/reporting');
5
+ const ota = require('../lib/ota');
6
+ const e = exposes.presets;
7
+
8
+ module.exports = [
9
+ {
10
+ zigbeeModel: ['V3-BTZB', 'V3-BTZBE'],
11
+ model: 'V3-BTZB/V3-BTZBE',
12
+ vendor: 'Danalock',
13
+ description: 'BT/ZB smartlock',
14
+ fromZigbee: [fz.lock, fz.lock_operation_event, fz.battery, fz.lock_programming_event, fz.lock_pin_code_response],
15
+ toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
16
+ meta: {pinCodeCount: 20},
17
+ ota: ota.zigbeeOTA,
18
+ configure: async (device, coordinatorEndpoint, logger) => {
19
+ const endpoint = device.getEndpoint(1);
20
+ await reporting.bind(endpoint, coordinatorEndpoint, ['closuresDoorLock', 'genPowerCfg']);
21
+ await reporting.lockState(endpoint);
22
+ await reporting.batteryPercentageRemaining(endpoint);
23
+ },
24
+ exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action(), e.lock_action_source_name(), e.lock_action_user()],
25
+ },
26
+ ];
@@ -0,0 +1,340 @@
1
+ const exposes = require('../lib/exposes');
2
+ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
+ const tz = require('../converters/toZigbee');
4
+ const ota = require('../lib/ota');
5
+ const constants = require('../lib/constants');
6
+ const reporting = require('../lib/reporting');
7
+ const e = exposes.presets;
8
+ const ea = exposes.access;
9
+
10
+ module.exports = [
11
+ {
12
+ // eTRV0100 is the same as Hive TRV001 and Popp eT093WRO. If implementing anything, please consider
13
+ // changing those two too.
14
+ zigbeeModel: ['eTRV0100', 'eTRV0101', 'eTRV0103'],
15
+ model: '014G2461',
16
+ vendor: 'Danfoss',
17
+ description: 'Ally thermostat',
18
+ whiteLabel: [{vendor: 'Danfoss', model: '014G2463'}],
19
+ meta: {thermostat: {dontMapPIHeatingDemand: true}},
20
+ fromZigbee: [fz.battery, fz.thermostat, fz.thermostat_weekly_schedule, fz.hvac_user_interface,
21
+ fz.danfoss_thermostat, fz.danfoss_thermostat_setpoint_scheduled],
22
+ toZigbee: [tz.danfoss_thermostat_occupied_heating_setpoint, tz.thermostat_local_temperature, tz.danfoss_mounted_mode_active,
23
+ tz.danfoss_mounted_mode_control, tz.danfoss_thermostat_vertical_orientation, tz.danfoss_algorithm_scale_factor,
24
+ tz.danfoss_heat_available, tz.danfoss_heat_required, tz.danfoss_day_of_week, tz.danfoss_trigger_time,
25
+ tz.danfoss_window_open_internal, tz.danfoss_window_open_external, tz.danfoss_load_estimate,
26
+ tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.danfoss_radiator_covered,
27
+ tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean,
28
+ tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode,
29
+ tz.danfoss_window_open_feature, tz.danfoss_preheat_status, tz.danfoss_adaptation_status, tz.danfoss_adaptation_settings,
30
+ tz.danfoss_adaptation_control, tz.danfoss_regulation_setpoint_offset,
31
+ tz.danfoss_thermostat_occupied_heating_setpoint_scheduled],
32
+ exposes: [e.battery(), e.keypad_lockout(), e.programming_operation_mode(),
33
+ exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
34
+ .withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
35
+ 'the radiator) or `true` for not mounted (after factory reset)'),
36
+ exposes.binary('mounted_mode_control', ea.ALL, true, false)
37
+ .withDescription('Set the unit mounting mode. `false` Go to Mounted Mode or `true` Go to Mounting Mode'),
38
+ exposes.binary('thermostat_vertical_orientation', ea.ALL, true, false)
39
+ .withDescription('Thermostat Orientation. This is important for the PID in how it assesses temperature. ' +
40
+ '`false` Horizontal or `true` Vertical'),
41
+ exposes.binary('viewing_direction', ea.ALL, true, false)
42
+ .withDescription('Viewing/display direction, `false` normal or `true` upside-down'),
43
+ exposes.binary('heat_available', ea.ALL, true, false)
44
+ .withDescription('Not clear how this affects operation. However, it would appear that the device does not execute any ' +
45
+ 'motor functions if this is set to false. This may be a means to conserve battery during periods that the heating ' +
46
+ 'system is not energized (e.g. during summer). `false` No Heat Available or `true` Heat Available'),
47
+ exposes.binary('heat_required', ea.STATE_GET, true, false)
48
+ .withDescription('Whether or not the unit needs warm water. `false` No Heat Request or `true` Heat Request'),
49
+ exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
50
+ .withDescription('Values observed are `0` (manual), `1` (schedule) or `2` (externally)'),
51
+ exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 35, 0.5).withLocalTemperature().withPiHeatingDemand()
52
+ .withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
53
+ exposes.numeric('occupied_heating_setpoint_scheduled', ea.ALL)
54
+ .withValueMin(5).withValueMax(35).withValueStep(0.5).withUnit('°C')
55
+ .withDescription('Scheduled change of the setpoint. Alternative method for changing the setpoint. In the opposite ' +
56
+ 'to occupied_heating_setpoint it does not trigger an aggressive response from the actuator. ' +
57
+ '(more suitable for scheduled changes)'),
58
+ exposes.numeric('external_measured_room_sensor', ea.ALL)
59
+ .withDescription('The temperature sensor of the TRV is — due to its design — relatively close to the heat source ' +
60
+ '(i.e. the hot water in the radiator). Thus there are situations where the `local_temperature` measured by the ' +
61
+ 'TRV is not accurate enough: If the radiator is covered behind curtains or furniture, if the room is rather big, or ' +
62
+ 'if the radiator itself is big and the flow temperature is high, then the temperature in the room may easily diverge ' +
63
+ 'from the `local_temperature` measured by the TRV by 5°C to 8°C. In this case you might choose to use an external ' +
64
+ 'room sensor and send the measured value of the external room sensor to the `External_measured_room_sensor` property.' +
65
+ 'The way the TRV operates on the `External_measured_room_sensor` depends on the setting of the `Radiator_covered` ' +
66
+ 'property: If `Radiator_covered` is `false` (Auto Offset Mode): You *must* set the `External_measured_room_sensor` ' +
67
+ 'property *at least* every 3 hours. After 3 hours the TRV disables this function and resets the value of the ' +
68
+ '`External_measured_room_sensor` property to -8000 (disabled). You *should* set the `External_measured_room_sensor` ' +
69
+ 'property *at most* every 30 minutes or every 0.1K change in measured room temperature.' +
70
+ 'If `Radiator_covered` is `true` (Room Sensor Mode): You *must* set the `External_measured_room_sensor` property *at ' +
71
+ 'least* every 30 minutes. After 35 minutes the TRV disables this function and resets the value of the ' +
72
+ '`External_measured_room_sensor` property to -8000 (disabled). You *should* set the `External_measured_room_sensor` ' +
73
+ 'property *at most* every 5 minutes or every 0.1K change in measured room temperature.')
74
+ .withValueMin(-8000).withValueMax(3500),
75
+ exposes.binary('radiator_covered', ea.ALL, true, false)
76
+ .withDescription('Controls whether the TRV should solely rely on an external room sensor or operate in offset mode. ' +
77
+ '`false` = Auto Offset Mode (use this e.g. for exposed radiators) or `true` = Room Sensor Mode (use this e.g. for ' +
78
+ 'covered radiators). Please note that this flag only controls how the TRV operates on the value of ' +
79
+ '`External_measured_room_sensor`; only setting this flag without setting the `External_measured_room_sensor` ' +
80
+ 'has no (noticable?) effect.'),
81
+ exposes.binary('window_open_feature', ea.ALL, true, false)
82
+ .withDescription('Whether or not the window open feature is enabled'),
83
+ exposes.enum('window_open_internal', ea.STATE_GET,
84
+ ['quarantine', 'closed', 'hold', 'open', 'external_open'])
85
+ .withDescription('0=Quarantine, 1=Windows are closed, 2=Hold - Windows are maybe about to open, ' +
86
+ '3=Open window detected, 4=In window open state from external but detected closed locally'),
87
+ exposes.binary('window_open_external', ea.ALL, true, false)
88
+ .withDescription('Set if the window is open or close. This setting will trigger a change in the internal ' +
89
+ 'window and heating demand. `false` (windows are closed) or `true` (windows are open)'),
90
+ exposes.enum('day_of_week', ea.ALL,
91
+ ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'away_or_vacation'])
92
+ .withDescription('Exercise day of week: 0=Sun...6=Sat, 7=undefined'),
93
+ exposes.numeric('trigger_time', ea.ALL).withValueMin(0).withValueMax(65535)
94
+ .withDescription('Exercise trigger time. Minutes since midnight (65535=undefined). Range 0 to 1439'),
95
+ exposes.numeric('algorithm_scale_factor', ea.ALL).withValueMin(1).withValueMax(10)
96
+ .withDescription('Scale factor of setpoint filter timeconstant ("aggressiveness" of control algorithm) '+
97
+ '1= Quick ... 5=Moderate ... 10=Slow'),
98
+ exposes.binary('load_balancing_enable', ea.ALL, true, false)
99
+ .withDescription('Whether or not the thermostat acts as standalone thermostat or shares load with other ' +
100
+ 'thermostats in the room. The gateway must update load_room_mean if enabled.'),
101
+ exposes.numeric('load_room_mean', ea.ALL)
102
+ .withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)')
103
+ .withValueMin(-8000).withValueMax(2000),
104
+ exposes.numeric('load_estimate', ea.STATE_GET)
105
+ .withDescription('Load estimate on this radiator')
106
+ .withValueMin(-8000).withValueMax(3600),
107
+ exposes.binary('preheat_status', ea.STATE_GET, true, false)
108
+ .withDescription('Specific for pre-heat running in Zigbee Weekly Schedule mode'),
109
+ exposes.enum('adaptation_run_status', ea.STATE_GET, ['none', 'in_progress', 'found', 'lost'])
110
+ .withDescription('Status of adaptation run: None (before first run), In Progress, Valve Characteristic Found, ' +
111
+ 'Valve Characteristic Lost'),
112
+ exposes.binary('adaptation_run_settings', ea.ALL, true, false)
113
+ .withDescription('Automatic adaptation run enabled (the one during the night)'),
114
+ exposes.enum('adaptation_run_control', ea.ALL, ['none', 'initiate_adaptation', 'cancel_adaptation'])
115
+ .withDescription('Adaptation run control: Initiate Adaptation Run or Cancel Adaptation Run'),
116
+ exposes.numeric('regulation_setpoint_offset', ea.ALL)
117
+ .withDescription('Regulation SetPoint Offset in range -2.5°C to 2.5°C in steps of 0.1°C. Value 2.5°C = 25.')
118
+ .withValueMin(-25).withValueMax(25)],
119
+ ota: ota.zigbeeOTA,
120
+ configure: async (device, coordinatorEndpoint, logger) => {
121
+ const endpoint = device.getEndpoint(1);
122
+ const options = {manufacturerCode: 0x1246};
123
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']);
124
+
125
+ // standard ZCL attributes
126
+ await reporting.batteryPercentageRemaining(endpoint);
127
+ await reporting.thermostatTemperature(endpoint);
128
+ await reporting.thermostatPIHeatingDemand(endpoint);
129
+ await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
130
+
131
+ // danfoss attributes
132
+ await endpoint.configureReporting('hvacThermostat', [{
133
+ attribute: 'danfossMountedModeActive',
134
+ minimumReportInterval: constants.repInterval.MINUTE,
135
+ maximumReportInterval: constants.repInterval.MAX,
136
+ reportableChange: 1,
137
+ }], options);
138
+ await endpoint.configureReporting('hvacThermostat', [{
139
+ attribute: 'danfossWindowOpenInternal',
140
+ minimumReportInterval: constants.repInterval.MINUTE,
141
+ maximumReportInterval: constants.repInterval.HOUR,
142
+ reportableChange: 1,
143
+ }], options);
144
+ await endpoint.configureReporting('hvacThermostat', [{
145
+ attribute: 'danfossHeatRequired',
146
+ minimumReportInterval: constants.repInterval.MINUTE,
147
+ maximumReportInterval: constants.repInterval.HOUR,
148
+ reportableChange: 1,
149
+ }], options);
150
+ await endpoint.configureReporting('hvacThermostat', [{
151
+ attribute: 'danfossExternalMeasuredRoomSensor',
152
+ minimumReportInterval: constants.repInterval.MINUTE,
153
+ maximumReportInterval: constants.repInterval.MAX,
154
+ reportableChange: 1,
155
+ }], options);
156
+ await endpoint.configureReporting('hvacThermostat', [{
157
+ attribute: 'danfossAdaptionRunStatus',
158
+ minimumReportInterval: constants.repInterval.MINUTE,
159
+ maximumReportInterval: constants.repInterval.HOUR,
160
+ reportableChange: 1,
161
+ }], options);
162
+
163
+ try {
164
+ await endpoint.configureReporting('hvacThermostat', [{
165
+ attribute: 'danfossPreheatStatus',
166
+ minimumReportInterval: constants.repInterval.MINUTE,
167
+ maximumReportInterval: constants.repInterval.MAX,
168
+ reportableChange: 1,
169
+ }], options);
170
+ } catch (e) {
171
+ /* not supported by all */
172
+ }
173
+
174
+ try {
175
+ await endpoint.read('hvacThermostat', [
176
+ 'danfossWindowOpenFeatureEnable',
177
+ 'danfossWindowOpenExternal',
178
+ 'danfossDayOfWeek',
179
+ 'danfossTriggerTime',
180
+ 'danfossAlgorithmScaleFactor',
181
+ 'danfossHeatAvailable',
182
+ 'danfossMountedModeControl',
183
+ 'danfossMountedModeActive',
184
+ 'danfossExternalMeasuredRoomSensor',
185
+ 'danfossRadiatorCovered',
186
+ 'danfossLoadBalancingEnable',
187
+ 'danfossLoadRoomMean',
188
+ 'danfossAdaptionRunControl',
189
+ 'danfossAdaptionRunSettings',
190
+ 'danfossRegulationSetpointOffset',
191
+ ], options);
192
+ } catch (e) {
193
+ /* not supported by all https://github.com/Koenkk/zigbee2mqtt/issues/11872 */
194
+ }
195
+
196
+ // read systemMode to have an initial value
197
+ await endpoint.read('hvacThermostat', ['systemMode']);
198
+
199
+ // read keypadLockout, we don't need reporting as it cannot be set physically on the device
200
+ await endpoint.read('hvacUserInterfaceCfg', ['keypadLockout']);
201
+
202
+ // Seems that it is bug in Danfoss, device does not asks for the time with binding
203
+ // So, we need to write time during configure (same as for HEIMAN devices)
204
+ const time = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000);
205
+ // Time-master + synchronised
206
+ const values = {timeStatus: 3, time: time, timeZone: ((new Date()).getTimezoneOffset() * -1) * 60};
207
+ endpoint.write('genTime', values);
208
+ },
209
+ },
210
+ {
211
+ fingerprint: [
212
+ {modelID: '0x8020', manufacturerName: 'Danfoss'}, // RT24V Display
213
+ {modelID: '0x8021', manufacturerName: 'Danfoss'}, // RT24V Display Floor sensor
214
+ {modelID: '0x8030', manufacturerName: 'Danfoss'}, // RTbattery Display
215
+ {modelID: '0x8031', manufacturerName: 'Danfoss'}, // RTbattery Display Infrared
216
+ {modelID: '0x8034', manufacturerName: 'Danfoss'}, // RTbattery Dial
217
+ {modelID: '0x8035', manufacturerName: 'Danfoss'}], // RTbattery Dial Infrared
218
+ model: 'Icon',
219
+ vendor: 'Danfoss',
220
+ description: 'Icon floor heating (regulator, Zigbee module & thermostats)',
221
+ fromZigbee: [
222
+ fz.danfoss_icon_regulator,
223
+ fz.danfoss_thermostat,
224
+ fz.danfoss_icon_battery,
225
+ fz.thermostat],
226
+ toZigbee: [
227
+ tz.thermostat_local_temperature,
228
+ tz.thermostat_occupied_heating_setpoint,
229
+ tz.thermostat_system_mode,
230
+ tz.thermostat_running_state,
231
+ tz.thermostat_min_heat_setpoint_limit,
232
+ tz.thermostat_max_heat_setpoint_limit,
233
+ tz.danfoss_output_status,
234
+ tz.danfoss_room_status_code,
235
+ tz.danfoss_system_status_water,
236
+ tz.danfoss_system_status_code,
237
+ tz.danfoss_multimaster_role,
238
+ ],
239
+ meta: {multiEndpoint: true, thermostat: {dontMapPIHeatingDemand: true}},
240
+ // ota: ota.zigbeeOTA,
241
+ endpoint: (device) => {
242
+ return {
243
+ 'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4, 'l5': 5,
244
+ 'l6': 6, 'l7': 7, 'l8': 8, 'l9': 9, 'l10': 10,
245
+ 'l11': 11, 'l12': 12, 'l13': 13, 'l14': 14, 'l15': 15, 'l16': 232,
246
+ };
247
+ },
248
+ exposes: [].concat(((endpointsCount) => {
249
+ const features = [];
250
+ for (let i = 1; i <= endpointsCount; i++) {
251
+ const epName = `l${i}`;
252
+ if (i!=16) {
253
+ features.push(e.battery().withEndpoint(epName));
254
+ features.push(exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 35, 0.5)
255
+ .withLocalTemperature().withRunningState(['idle', 'heat']).withSystemMode(['heat']).withEndpoint(epName));
256
+ features.push(exposes.numeric('abs_min_heat_setpoint_limit', ea.STATE)
257
+ .withUnit('°C').withEndpoint(epName)
258
+ .withDescription('Absolute min temperature allowed on the device'));
259
+ features.push(exposes.numeric('abs_max_heat_setpoint_limit', ea.STATE)
260
+ .withUnit('°C').withEndpoint(epName)
261
+ .withDescription('Absolute max temperature allowed on the device'));
262
+ features.push(exposes.numeric('min_heat_setpoint_limit', ea.ALL)
263
+ .withValueMin(4).withValueMax(35).withValueStep(0.5).withUnit('°C')
264
+ .withEndpoint(epName).withDescription('Min temperature limit set on the device'));
265
+ features.push(exposes.numeric('max_heat_setpoint_limit', ea.ALL)
266
+ .withValueMin(4).withValueMax(35).withValueStep(0.5).withUnit('°C')
267
+ .withEndpoint(epName).withDescription('Max temperature limit set on the device'));
268
+ features.push(exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
269
+ .withEndpoint(epName));
270
+ features.push(exposes.enum('output_status', ea.STATE_GET, ['inactive', 'active'])
271
+ .withEndpoint(epName).withDescription('Danfoss Output Status [Active vs Inactive])'));
272
+ features.push(exposes.enum('room_status_code', ea.STATE_GET, ['no_error', 'missing_rt',
273
+ 'rt_touch_error', 'floor_sensor_short_circuit', 'floor_sensor_disconnected'])
274
+ .withEndpoint(epName).withDescription('Thermostat status'));
275
+ } else {
276
+ features.push(exposes.enum('system_status_code', ea.STATE_GET, ['no_error', 'missing_expansion_board',
277
+ 'missing_radio_module', 'missing_command_module', 'missing_master_rail', 'missing_slave_rail_no_1',
278
+ 'missing_slave_rail_no_2', 'pt1000_input_short_circuit', 'pt1000_input_open_circuit',
279
+ 'error_on_one_or_more_output']).withEndpoint('l16').withDescription('Regulator Status'));
280
+ features.push(exposes.enum('system_status_water', ea.STATE_GET, ['hot_water_flow_in_pipes', 'cool_water_flow_in_pipes'])
281
+ .withEndpoint('l16').withDescription('Water Status of Regulator'));
282
+ features.push(exposes.enum('multimaster_role', ea.STATE_GET, ['invalid_unused', 'master', 'slave_1', 'slave_2'])
283
+ .withEndpoint('l16').withDescription('Regulator role (Master vs Slave)'));
284
+ }
285
+ }
286
+
287
+ return features;
288
+ })(16)),
289
+ configure: async (device, coordinatorEndpoint, logger) => {
290
+ const options = {manufacturerCode: 0x1246};
291
+
292
+ for (let i = 1; i <= 15; i++) {
293
+ const endpoint = device.getEndpoint(i);
294
+ if (typeof endpoint !== 'undefined') {
295
+ await reporting.bind(endpoint, coordinatorEndpoint,
296
+ ['genPowerCfg', 'hvacThermostat', 'hvacUserInterfaceCfg']);
297
+ await reporting.batteryPercentageRemaining(endpoint,
298
+ {min: constants.repInterval.HOUR, max: 43200, change: 1});
299
+ await reporting.thermostatTemperature(endpoint,
300
+ {min: 0, max: constants.repInterval.MINUTES_10, change: 10});
301
+ await reporting.thermostatOccupiedHeatingSetpoint(endpoint,
302
+ {min: 0, max: constants.repInterval.MINUTES_10, change: 10});
303
+
304
+ await endpoint.configureReporting('hvacThermostat', [{
305
+ attribute: 'danfossOutputStatus',
306
+ minimumReportInterval: constants.repInterval.MINUTE,
307
+ maximumReportInterval: constants.repInterval.MINUTES_10,
308
+ reportableChange: 1,
309
+ }], options);
310
+
311
+ // Danfoss Icon Thermostat Specific
312
+ await endpoint.read('hvacThermostat', [
313
+ 'danfossOutputStatus',
314
+ 'danfossRoomStatusCode'], options);
315
+
316
+ // Standard Thermostat
317
+ await endpoint.read('hvacThermostat', ['localTemp']);
318
+ await endpoint.read('hvacThermostat', ['occupiedHeatingSetpoint']);
319
+ await endpoint.read('hvacThermostat', ['systemMode']);
320
+ await endpoint.read('hvacThermostat', ['setpointChangeSource']);
321
+ await endpoint.read('hvacThermostat', ['absMinHeatSetpointLimit']);
322
+ await endpoint.read('hvacThermostat', ['absMaxHeatSetpointLimit']);
323
+ await endpoint.read('hvacThermostat', ['minHeatSetpointLimit']);
324
+ await endpoint.read('hvacThermostat', ['maxHeatSetpointLimit']);
325
+ await endpoint.read('genPowerCfg', ['batteryPercentageRemaining']);
326
+ }
327
+ }
328
+
329
+ // Danfoss Icon Regulator Specific
330
+ const endpoint232 = device.getEndpoint(232);
331
+
332
+ await reporting.bind(endpoint232, coordinatorEndpoint, ['haDiagnostic']);
333
+
334
+ await endpoint232.read('haDiagnostic', [
335
+ 'danfossSystemStatusCode',
336
+ 'danfossSystemStatusWater',
337
+ 'danfossMultimasterRole'], options);
338
+ },
339
+ },
340
+ ];
@@ -0,0 +1,55 @@
1
+ const exposes = require('../lib/exposes');
2
+ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
+ const tz = require('../converters/toZigbee');
4
+ const extend = require('../lib/extend');
5
+ const ea = exposes.access;
6
+ const e = exposes.presets;
7
+
8
+ const fzLocal = {
9
+ DTB2011014: {
10
+ cluster: 'genOnOff',
11
+ type: ['attributeReport', 'readResponse'],
12
+ convert: (model, msg, publish, options, meta) => {
13
+ return {
14
+ key_1: msg.data['41361'] === 1 ? 'ON' : 'OFF',
15
+ key_2: msg.data['41362'] === 1 ? 'ON' : 'OFF',
16
+ key_3: msg.data['41363'] === 1 ? 'ON' : 'OFF',
17
+ key_4: msg.data['41364'] === 1 ? 'ON' : 'OFF',
18
+ };
19
+ },
20
+ },
21
+ };
22
+
23
+ module.exports = [
24
+ {
25
+ zigbeeModel: ['DTB190502A1'],
26
+ model: 'DTB190502A1',
27
+ vendor: 'databyte.ch',
28
+ description: 'CC2530 based IO Board',
29
+ fromZigbee: [fz.DTB190502A1],
30
+ toZigbee: [tz.DTB190502A1_LED],
31
+ exposes: [exposes.binary('led_state', ea.STATE, 'ON', 'OFF'),
32
+ exposes.enum('key_state', ea.STATE, ['KEY_SYS', 'KEY_UP', 'KEY_DOWN', 'KEY_NONE'])],
33
+ },
34
+ {
35
+ zigbeeModel: ['DTB-ED2004-012'],
36
+ model: 'ED2004-012',
37
+ vendor: 'databyte.ch',
38
+ description: 'Panda 1 - wall switch',
39
+ extend: extend.switch(),
40
+ },
41
+ {
42
+ zigbeeModel: ['DTB-ED2011-014'],
43
+ model: 'Touch4',
44
+ vendor: 'databyte.ch',
45
+ description: 'Wall touchsensor with 4 keys',
46
+ fromZigbee: [fzLocal.DTB2011014, fz.battery],
47
+ toZigbee: [],
48
+ exposes: [e.battery(), e.linkquality(),
49
+ exposes.binary('key_1', ea.STATE, 'ON', 'OFF'),
50
+ exposes.binary('key_2', ea.STATE, 'ON', 'OFF'),
51
+ exposes.binary('key_3', ea.STATE, 'ON', 'OFF'),
52
+ exposes.binary('key_4', ea.STATE, 'ON', 'OFF'),
53
+ ],
54
+ },
55
+ ];