@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.
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/converters/fromZigbee.js +8439 -0
- package/converters/toZigbee.js +7162 -0
- package/devices/ITCommander.js +37 -0
- package/devices/RMC002.js +20 -0
- package/devices/acova.js +101 -0
- package/devices/acuity_brands_lighting.js +11 -0
- package/devices/adeo.js +256 -0
- package/devices/adurosmart.js +130 -0
- package/devices/aeotec.js +13 -0
- package/devices/airam.js +59 -0
- package/devices/ajax_online.js +49 -0
- package/devices/akuvox.js +28 -0
- package/devices/alchemy.js +18 -0
- package/devices/aldi.js +53 -0
- package/devices/alecto.js +98 -0
- package/devices/anchor.js +17 -0
- package/devices/atlantic.js +110 -0
- package/devices/atsmart.js +28 -0
- package/devices/aubess.js +21 -0
- package/devices/aurora_lighting.js +292 -0
- package/devices/automaton.js +44 -0
- package/devices/awox.js +184 -0
- package/devices/axis.js +22 -0
- package/devices/bankamp.js +11 -0
- package/devices/bega.js +22 -0
- package/devices/belkin.js +11 -0
- package/devices/bitron.js +334 -0
- package/devices/blaupunkt.js +27 -0
- package/devices/blitzwolf.js +47 -0
- package/devices/bosch.js +702 -0
- package/devices/brimate.js +15 -0
- package/devices/bseed.js +17 -0
- package/devices/bticino.js +118 -0
- package/devices/busch-jaeger.js +140 -0
- package/devices/byun.js +24 -0
- package/devices/calex.js +37 -0
- package/devices/candeo.js +49 -0
- package/devices/casaia.js +52 -0
- package/devices/centralite.js +359 -0
- package/devices/cleode.js +20 -0
- package/devices/cleverio.js +36 -0
- package/devices/climax.js +138 -0
- package/devices/commercial_electric.js +16 -0
- package/devices/connecte.js +46 -0
- package/devices/cree.js +11 -0
- package/devices/ctm.js +999 -0
- package/devices/current_products_corp.js +24 -0
- package/devices/custom_devices_diy.js +850 -0
- package/devices/cy-lighting.js +11 -0
- package/devices/danalock.js +26 -0
- package/devices/danfoss.js +340 -0
- package/devices/databyte.ch.js +55 -0
- package/devices/datek.js +246 -0
- package/devices/dawon_dns.js +338 -0
- package/devices/develco.js +868 -0
- package/devices/digi.js +14 -0
- package/devices/diyruz.js +305 -0
- package/devices/dlink.js +37 -0
- package/devices/dnake.js +11 -0
- package/devices/dresden_elektronik.js +47 -0
- package/devices/easyaccess.js +27 -0
- package/devices/eatonhalo_led.js +11 -0
- package/devices/echostar.js +25 -0
- package/devices/ecodim.js +145 -0
- package/devices/ecolink.js +21 -0
- package/devices/ecosmart.js +64 -0
- package/devices/ecozy.js +31 -0
- package/devices/edp.js +39 -0
- package/devices/eglo.js +25 -0
- package/devices/elko.js +176 -0
- package/devices/enbrighten.js +163 -0
- package/devices/enocean.js +52 -0
- package/devices/envilar.js +73 -0
- package/devices/essentialb.js +87 -0
- package/devices/eurotronic.js +48 -0
- package/devices/evanell.js +29 -0
- package/devices/evn.js +31 -0
- package/devices/evology.js +24 -0
- package/devices/evvr.js +17 -0
- package/devices/ewelink.js +184 -0
- package/devices/ezex.js +24 -0
- package/devices/fantem.js +77 -0
- package/devices/feibit.js +172 -0
- package/devices/fireangel.js +15 -0
- package/devices/frankever.js +23 -0
- package/devices/garza.js +11 -0
- package/devices/ge.js +111 -0
- package/devices/gewiss.js +48 -0
- package/devices/gidealed.js +11 -0
- package/devices/giderwel.js +11 -0
- package/devices/giex.js +222 -0
- package/devices/girier.js +19 -0
- package/devices/gledopto.js +756 -0
- package/devices/gmy.js +11 -0
- package/devices/gs.js +29 -0
- package/devices/halemeier.js +18 -0
- package/devices/hampton_bay.js +37 -0
- package/devices/heiman.js +805 -0
- package/devices/hej.js +107 -0
- package/devices/hfh.js +11 -0
- package/devices/hgkg.js +54 -0
- package/devices/hilux.js +11 -0
- package/devices/hive.js +524 -0
- package/devices/home_control_as.js +27 -0
- package/devices/hommyn.js +24 -0
- package/devices/honyar.js +29 -0
- package/devices/hornbach.js +53 -0
- package/devices/hzc.js +21 -0
- package/devices/hzc_electric.js +42 -0
- package/devices/icasa.js +121 -0
- package/devices/idinio.js +19 -0
- package/devices/ihorn.js +61 -0
- package/devices/ikea.js +1168 -0
- package/devices/ilightsin.js +11 -0
- package/devices/iluminize.js +262 -0
- package/devices/ilux.js +11 -0
- package/devices/immax.js +203 -0
- package/devices/innr.js +705 -0
- package/devices/inovelli.js +1315 -0
- package/devices/insta.js +110 -0
- package/devices/iolloi.js +20 -0
- package/devices/iotperfect.js +20 -0
- package/devices/iris.js +180 -0
- package/devices/istar.js +20 -0
- package/devices/jasco.js +55 -0
- package/devices/javis.js +37 -0
- package/devices/jethome.js +48 -0
- package/devices/jiawen.js +18 -0
- package/devices/jumitech.js +18 -0
- package/devices/jxuan.js +49 -0
- package/devices/kami.js +15 -0
- package/devices/keen_home.js +80 -0
- package/devices/klikaanklikuit.js +17 -0
- package/devices/kmpcil.js +148 -0
- package/devices/konke.js +141 -0
- package/devices/ksentry.js +17 -0
- package/devices/kurvia.js +17 -0
- package/devices/kwikset.js +120 -0
- package/devices/lanesto.js +11 -0
- package/devices/lds.js +11 -0
- package/devices/led_trading.js +69 -0
- package/devices/ledvance.js +353 -0
- package/devices/leedarson.js +130 -0
- package/devices/legrand.js +554 -0
- package/devices/lellki.js +146 -0
- package/devices/letsled.js +11 -0
- package/devices/letv.js +18 -0
- package/devices/leviton.js +142 -0
- package/devices/lg.js +18 -0
- package/devices/lidl.js +1000 -0
- package/devices/lifecontrol.js +92 -0
- package/devices/lightsolutions.js +37 -0
- package/devices/linkind.js +205 -0
- package/devices/livingwise.js +59 -0
- package/devices/livolo.js +286 -0
- package/devices/lixee.js +779 -0
- package/devices/lonsonho.js +218 -0
- package/devices/lubeez.js +18 -0
- package/devices/lupus.js +74 -0
- package/devices/lutron.js +32 -0
- package/devices/lux.js +40 -0
- package/devices/m-elec.js +18 -0
- package/devices/makegood.js +51 -0
- package/devices/matcall_bv.js +18 -0
- package/devices/meazon.js +47 -0
- package/devices/mercator.js +225 -0
- package/devices/miboxer.js +72 -0
- package/devices/micromatic.js +29 -0
- package/devices/moes.js +400 -0
- package/devices/mycket.js +11 -0
- package/devices/m/303/274ller_licht.js +220 -0
- package/devices/namron.js +774 -0
- package/devices/nanoleaf.js +11 -0
- package/devices/neo.js +86 -0
- package/devices/net2grid.js +29 -0
- package/devices/netvox.js +35 -0
- package/devices/niko.js +314 -0
- package/devices/ninja_blocks.js +24 -0
- package/devices/niviss.js +11 -0
- package/devices/nodon.js +109 -0
- package/devices/nordtronic.js +30 -0
- package/devices/nous.js +88 -0
- package/devices/novo.js +17 -0
- package/devices/nue_3a.js +417 -0
- package/devices/nyce.js +67 -0
- package/devices/onesti.js +59 -0
- package/devices/openlumi.js +22 -0
- package/devices/orvibo.js +515 -0
- package/devices/osram.js +519 -0
- package/devices/oujiabao.js +15 -0
- package/devices/owon.js +352 -0
- package/devices/ozsmartthings.js +11 -0
- package/devices/paul_neuhaus.js +96 -0
- package/devices/paulmann.js +158 -0
- package/devices/peq.js +24 -0
- package/devices/perenio.js +413 -0
- package/devices/philips.js +3118 -0
- package/devices/plaid.js +25 -0
- package/devices/plugwise.js +173 -0
- package/devices/popp.js +10 -0
- package/devices/profalux.js +47 -0
- package/devices/prolight.js +54 -0
- package/devices/qmotion.js +33 -0
- package/devices/qoto.js +113 -0
- package/devices/quotra.js +18 -0
- package/devices/rademacher.js +18 -0
- package/devices/rgb_genie.js +119 -0
- package/devices/robb.js +335 -0
- package/devices/roome.js +15 -0
- package/devices/rtx.js +90 -0
- package/devices/salus_controls.js +137 -0
- package/devices/samotech.js +93 -0
- package/devices/saswell.js +58 -0
- package/devices/scanproducts.js +32 -0
- package/devices/schlage.js +24 -0
- package/devices/schneider_electric.js +1039 -0
- package/devices/schwaiger.js +62 -0
- package/devices/seastar_intelligence.js +16 -0
- package/devices/securifi.js +39 -0
- package/devices/sengled.js +332 -0
- package/devices/sercomm.js +140 -0
- package/devices/shenzhen_homa.js +53 -0
- package/devices/shinasystem.js +686 -0
- package/devices/siglis.js +440 -0
- package/devices/sinope.js +1257 -0
- package/devices/siterwell.js +46 -0
- package/devices/skydance.js +112 -0
- package/devices/slv.js +27 -0
- package/devices/smart9.js +27 -0
- package/devices/smart_home_pty.js +18 -0
- package/devices/smartenit.js +42 -0
- package/devices/smartthings.js +495 -0
- package/devices/smartwings.js +24 -0
- package/devices/sohan_electric.js +13 -0
- package/devices/solaredge.js +11 -0
- package/devices/somgoms.js +47 -0
- package/devices/sonoff.js +262 -0
- package/devices/spotmau.js +36 -0
- package/devices/sprut.js +317 -0
- package/devices/stelpro.js +216 -0
- package/devices/sunricher.js +625 -0
- package/devices/swann.js +33 -0
- package/devices/sylvania.js +200 -0
- package/devices/tci.js +25 -0
- package/devices/technicolor.js +47 -0
- package/devices/terncy.js +64 -0
- package/devices/the_light_group.js +70 -0
- package/devices/third_reality.js +195 -0
- package/devices/titan_products.js +22 -0
- package/devices/tplink.js +42 -0
- package/devices/trust.js +114 -0
- package/devices/tubeszb.js +20 -0
- package/devices/tuya.js +4215 -0
- package/devices/ubisys.js +938 -0
- package/devices/uhome.js +25 -0
- package/devices/universal_electronics_inc.js +119 -0
- package/devices/urlighting.js +12 -0
- package/devices/useelink.js +52 -0
- package/devices/vbled.js +18 -0
- package/devices/vesternet.js +188 -0
- package/devices/viessmann.js +51 -0
- package/devices/villeroy_boch.js +18 -0
- package/devices/vimar.js +78 -0
- package/devices/visonic.js +80 -0
- package/devices/vrey.js +18 -0
- package/devices/wally.js +25 -0
- package/devices/waxman.js +45 -0
- package/devices/weiser.js +67 -0
- package/devices/weten.js +13 -0
- package/devices/wisdom.js +11 -0
- package/devices/woox.js +177 -0
- package/devices/wyze.js +23 -0
- package/devices/xiaomi.js +3223 -0
- package/devices/xinghuoyuan.js +11 -0
- package/devices/yale.js +227 -0
- package/devices/ynoa.js +68 -0
- package/devices/yookee.js +23 -0
- package/devices/ysrsai.js +26 -0
- package/devices/zemismart.js +254 -0
- package/devices/zen.js +34 -0
- package/devices/zipato.js +11 -0
- package/index.js +242 -0
- package/lib/color.js +784 -0
- package/lib/configureKey.js +944 -0
- package/lib/constants.js +316 -0
- package/lib/exposes.js +677 -0
- package/lib/extend.js +180 -0
- package/lib/kelvinToXy.js +1912 -0
- package/lib/legacy.js +2223 -0
- package/lib/light.js +111 -0
- package/lib/ota/OTA_URLs.md +119 -0
- package/lib/ota/common.js +476 -0
- package/lib/ota/index.js +10 -0
- package/lib/ota/inovelli.js +72 -0
- package/lib/ota/ledvance.js +52 -0
- package/lib/ota/lixee.js +57 -0
- package/lib/ota/salus.js +82 -0
- package/lib/ota/securifi.js +25 -0
- package/lib/ota/tradfri.js +45 -0
- package/lib/ota/ubisys.js +61 -0
- package/lib/ota/zigbeeOTA.js +161 -0
- package/lib/philips.js +667 -0
- package/lib/reporting.js +234 -0
- package/lib/store.js +57 -0
- package/lib/tuya.js +2027 -0
- package/lib/utils.js +527 -0
- package/lib/xiaomi.d.ts +11 -0
- package/lib/xiaomi.js +1288 -0
- package/lib/zosung.js +243 -0
- package/package.json +39 -0
|
@@ -0,0 +1,1257 @@
|
|
|
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 constants = require('../lib/constants');
|
|
5
|
+
const utils = require('../lib/utils');
|
|
6
|
+
const reporting = require('../lib/reporting');
|
|
7
|
+
const extend = require('../lib/extend');
|
|
8
|
+
const e = exposes.presets;
|
|
9
|
+
const ea = exposes.access;
|
|
10
|
+
const {precisionRound} = require('../lib/utils');
|
|
11
|
+
|
|
12
|
+
const manuSinope = {manufacturerCode: 0x119C};
|
|
13
|
+
|
|
14
|
+
const fzLocal = {
|
|
15
|
+
ias_water_leak_alarm: {
|
|
16
|
+
// RM3500ZB specific
|
|
17
|
+
cluster: 'ssIasZone',
|
|
18
|
+
type: ['commandStatusChangeNotification', 'attributeReport', 'readResponse'],
|
|
19
|
+
convert: (model, msg, publish, options, meta) => {
|
|
20
|
+
const zoneStatus = msg.data.zoneStatus;
|
|
21
|
+
return {
|
|
22
|
+
water_leak: (zoneStatus & 1) > 0,
|
|
23
|
+
tamper: (zoneStatus & 1<<2) > 0,
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
thermostat: {
|
|
28
|
+
cluster: 'hvacThermostat',
|
|
29
|
+
type: ['attributeReport', 'readResponse'],
|
|
30
|
+
options: [exposes.options.legacy()],
|
|
31
|
+
convert: (model, msg, publish, options, meta) => {
|
|
32
|
+
delete msg['running_state'];
|
|
33
|
+
const result = {};
|
|
34
|
+
const occupancyLookup = {0: 'unoccupied', 1: 'occupied'};
|
|
35
|
+
const cycleOutputLookup = {15: '15_sec', 300: '5_min', 600: '10_min',
|
|
36
|
+
900: '15_min', 1200: '20_min', 1800: '30_min', 65535: 'off'};
|
|
37
|
+
|
|
38
|
+
if (msg.data.hasOwnProperty('1024')) {
|
|
39
|
+
result.thermostat_occupancy = occupancyLookup[msg.data['1024']];
|
|
40
|
+
}
|
|
41
|
+
if (msg.data.hasOwnProperty('SinopeOccupancy')) {
|
|
42
|
+
result.thermostat_occupancy = occupancyLookup[msg.data['SinopeOccupancy']];
|
|
43
|
+
}
|
|
44
|
+
if (msg.data.hasOwnProperty('1025')) {
|
|
45
|
+
result.main_cycle_output = cycleOutputLookup[msg.data['1025']];
|
|
46
|
+
}
|
|
47
|
+
if (msg.data.hasOwnProperty('SinopeMainCycleOutput')) {
|
|
48
|
+
result.main_cycle_output = cycleOutputLookup[msg.data['SinopeMainCycleOutput']];
|
|
49
|
+
}
|
|
50
|
+
if (msg.data.hasOwnProperty('1026')) {
|
|
51
|
+
const lookup = {0: 'on_demand', 1: 'sensing'};
|
|
52
|
+
result.backlight_auto_dim = lookup[msg.data['1026']];
|
|
53
|
+
}
|
|
54
|
+
if (msg.data.hasOwnProperty('SinopeBacklight')) {
|
|
55
|
+
const lookup = {0: 'on_demand', 1: 'sensing'};
|
|
56
|
+
result.backlight_auto_dim = lookup[msg.data['SinopeBacklight']];
|
|
57
|
+
}
|
|
58
|
+
if (msg.data.hasOwnProperty('1028')) {
|
|
59
|
+
result.aux_cycle_output = cycleOutputLookup[msg.data['1028']];
|
|
60
|
+
}
|
|
61
|
+
if (msg.data.hasOwnProperty('localTemp')) {
|
|
62
|
+
result.local_temperature = precisionRound(msg.data['localTemp'], 2) / 100;
|
|
63
|
+
}
|
|
64
|
+
if (msg.data.hasOwnProperty('localTemperatureCalibration')) {
|
|
65
|
+
result.local_temperature_calibration = precisionRound(msg.data['localTemperatureCalibration'], 2) / 10;
|
|
66
|
+
}
|
|
67
|
+
if (msg.data.hasOwnProperty('outdoorTemp')) {
|
|
68
|
+
result.outdoor_temperature = precisionRound(msg.data['outdoorTemp'], 2) / 100;
|
|
69
|
+
}
|
|
70
|
+
if (msg.data.hasOwnProperty('occupiedHeatingSetpoint')) {
|
|
71
|
+
result.occupied_heating_setpoint = precisionRound(msg.data['occupiedHeatingSetpoint'], 2) / 100;
|
|
72
|
+
}
|
|
73
|
+
if (msg.data.hasOwnProperty('unoccupiedHeatingSetpoint')) {
|
|
74
|
+
result.unoccupied_heating_setpoint = precisionRound(msg.data['unoccupiedHeatingSetpoint'], 2) / 100;
|
|
75
|
+
}
|
|
76
|
+
if (msg.data.hasOwnProperty('occupiedCoolingSetpoint')) {
|
|
77
|
+
result.occupied_cooling_setpoint = precisionRound(msg.data['occupiedCoolingSetpoint'], 2) / 100;
|
|
78
|
+
}
|
|
79
|
+
if (msg.data.hasOwnProperty('unoccupiedCoolingSetpoint')) {
|
|
80
|
+
result.unoccupied_cooling_setpoint = precisionRound(msg.data['unoccupiedCoolingSetpoint'], 2) / 100;
|
|
81
|
+
}
|
|
82
|
+
if (msg.data.hasOwnProperty('ctrlSeqeOfOper')) {
|
|
83
|
+
result.control_sequence_of_operation = constants.thermostatControlSequenceOfOperations[msg.data['ctrlSeqeOfOper']];
|
|
84
|
+
}
|
|
85
|
+
if (msg.data.hasOwnProperty('systemMode')) {
|
|
86
|
+
result.system_mode = constants.thermostatSystemModes[msg.data['systemMode']];
|
|
87
|
+
}
|
|
88
|
+
if (msg.data.hasOwnProperty('pIHeatingDemand')) {
|
|
89
|
+
result.pi_heating_demand = precisionRound(msg.data['pIHeatingDemand'], 0);
|
|
90
|
+
}
|
|
91
|
+
if (msg.data.hasOwnProperty('minHeatSetpointLimit')) {
|
|
92
|
+
result.min_heat_setpoint_limit = precisionRound(msg.data['minHeatSetpointLimit'], 2) / 100;
|
|
93
|
+
}
|
|
94
|
+
if (msg.data.hasOwnProperty('maxHeatSetpointLimit')) {
|
|
95
|
+
result.max_heat_setpoint_limit = precisionRound(msg.data['maxHeatSetpointLimit'], 2) / 100;
|
|
96
|
+
}
|
|
97
|
+
if (msg.data.hasOwnProperty('absMinHeatSetpointLimit')) {
|
|
98
|
+
result.abs_min_heat_setpoint_limit = precisionRound(msg.data['absMinHeatSetpointLimit'], 2) / 100;
|
|
99
|
+
}
|
|
100
|
+
if (msg.data.hasOwnProperty('absMaxHeatSetpointLimit')) {
|
|
101
|
+
result.abs_max_heat_setpoint_limit = precisionRound(msg.data['absMaxHeatSetpointLimit'], 2) / 100;
|
|
102
|
+
}
|
|
103
|
+
if (msg.data.hasOwnProperty('pIHeatingDemand')) {
|
|
104
|
+
result.running_state = msg.data['pIHeatingDemand'] >= 10 ? 'heat' : 'idle';
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
sinope: {
|
|
110
|
+
cluster: 'manuSpecificSinope',
|
|
111
|
+
type: ['attributeReport', 'readResponse'],
|
|
112
|
+
convert: (model, msg, publish, options, meta) => {
|
|
113
|
+
const result = {};
|
|
114
|
+
if (msg.data.hasOwnProperty('GFCiStatus')) {
|
|
115
|
+
const lookup = {0: 'off', 1: 'on'};
|
|
116
|
+
result.gfci_status = lookup[msg.data['GFCiStatus']];
|
|
117
|
+
}
|
|
118
|
+
if (msg.data.hasOwnProperty('floorLimitStatus')) {
|
|
119
|
+
const lookup = {0: 'off', 1: 'on'};
|
|
120
|
+
result.floor_limit_status = lookup[msg.data['floorLimitStatus']];
|
|
121
|
+
}
|
|
122
|
+
if (msg.data.hasOwnProperty('outdoorTempToDisplayTimeout')) {
|
|
123
|
+
result.enable_outdoor_temperature = msg.data['outdoorTempToDisplayTimeout'] == 10800 ? 'ON' : 'OFF';
|
|
124
|
+
}
|
|
125
|
+
if (msg.data.hasOwnProperty('currentTimeToDisplay')) {
|
|
126
|
+
result.current_time_to_display = msg.data['currentTimeToDisplay'];
|
|
127
|
+
}
|
|
128
|
+
if (msg.data.hasOwnProperty('floorControlMode')) {
|
|
129
|
+
const lookup = {1: 'ambiant', 2: 'floor'};
|
|
130
|
+
result.floor_control_mode = lookup[msg.data['floorControlMode']];
|
|
131
|
+
}
|
|
132
|
+
if (msg.data.hasOwnProperty('ambiantMaxHeatSetpointLimit')) {
|
|
133
|
+
result.ambiant_max_heat_setpoint = msg.data['ambiantMaxHeatSetpointLimit'] / 100.0;
|
|
134
|
+
if (result.ambiant_max_heat_setpoint === -327.68) {
|
|
135
|
+
result.ambiant_max_heat_setpoint = 'off';
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (msg.data.hasOwnProperty('floorMinHeatSetpointLimit')) {
|
|
139
|
+
result.floor_min_heat_setpoint = msg.data['floorMinHeatSetpointLimit'] / 100.0;
|
|
140
|
+
if (result.floor_min_heat_setpoint === -327.68) {
|
|
141
|
+
result.floor_min_heat_setpoint = 'off';
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (msg.data.hasOwnProperty('floorMaxHeatSetpointLimit')) {
|
|
145
|
+
result.floor_max_heat_setpoint = msg.data['floorMaxHeatSetpointLimit'] / 100.0;
|
|
146
|
+
if (result.floor_max_heat_setpoint === -327.68) {
|
|
147
|
+
result.floor_max_heat_setpoint = 'off';
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (msg.data.hasOwnProperty('temperatureSensor')) {
|
|
151
|
+
const lookup = {0: '10k', 1: '12k'};
|
|
152
|
+
result.floor_temperature_sensor = lookup[msg.data['temperatureSensor']];
|
|
153
|
+
}
|
|
154
|
+
if (msg.data.hasOwnProperty('timeFormatToDisplay')) {
|
|
155
|
+
const lookup = {0: '24h', 1: '12h'};
|
|
156
|
+
result.time_format = lookup[msg.data['timeFormatToDisplay']];
|
|
157
|
+
}
|
|
158
|
+
if (msg.data.hasOwnProperty('connectedLoad')) {
|
|
159
|
+
result.connected_load = msg.data['connectedLoad'];
|
|
160
|
+
}
|
|
161
|
+
if (msg.data.hasOwnProperty('auxConnectedLoad')) {
|
|
162
|
+
result.aux_connected_load = msg.data['auxConnectedLoad'];
|
|
163
|
+
if (result.aux_connected_load == 65535) {
|
|
164
|
+
result.aux_connected_load = 'disabled';
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (msg.data.hasOwnProperty('pumpProtection')) {
|
|
168
|
+
result.pump_protection = msg.data['pumpProtection'] == 1 ? 'ON' : 'OFF';
|
|
169
|
+
}
|
|
170
|
+
if (msg.data.hasOwnProperty('dimmerTimmer')) {
|
|
171
|
+
result.timer_seconds = msg.data['dimmerTimmer'];
|
|
172
|
+
}
|
|
173
|
+
if (msg.data.hasOwnProperty('ledIntensityOn')) {
|
|
174
|
+
result.led_intensity_on = msg.data['ledIntensityOn'];
|
|
175
|
+
}
|
|
176
|
+
if (msg.data.hasOwnProperty('ledIntensityOff')) {
|
|
177
|
+
result.led_intensity_off = msg.data['ledIntensityOff'];
|
|
178
|
+
}
|
|
179
|
+
if (msg.data.hasOwnProperty('minimumBrightness')) {
|
|
180
|
+
result.minimum_brightness = msg.data['minimumBrightness'];
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
const tzLocal = {
|
|
187
|
+
thermostat_occupancy: {
|
|
188
|
+
key: ['thermostat_occupancy'],
|
|
189
|
+
convertSet: async (entity, key, value, meta) => {
|
|
190
|
+
const sinopeOccupancy = {0: 'unoccupied', 1: 'occupied'};
|
|
191
|
+
const SinopeOccupancy = utils.getKey(sinopeOccupancy, value, value, Number);
|
|
192
|
+
await entity.write('hvacThermostat', {SinopeOccupancy}, manuSinope);
|
|
193
|
+
return {state: {'thermostat_occupancy': value}};
|
|
194
|
+
},
|
|
195
|
+
convertGet: async (entity, key, meta) => {
|
|
196
|
+
await entity.read('hvacThermostat', ['SinopeOccupancy'], manuSinope);
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
backlight_autodim: {
|
|
200
|
+
key: ['backlight_auto_dim'],
|
|
201
|
+
convertSet: async (entity, key, value, meta) => {
|
|
202
|
+
const sinopeBacklightParam = {0: 'on_demand', 1: 'sensing'};
|
|
203
|
+
const SinopeBacklight = utils.getKey(sinopeBacklightParam, value, value, Number);
|
|
204
|
+
await entity.write('hvacThermostat', {SinopeBacklight}, manuSinope);
|
|
205
|
+
return {state: {'backlight_auto_dim': value}};
|
|
206
|
+
},
|
|
207
|
+
convertGet: async (entity, key, meta) => {
|
|
208
|
+
await entity.read('hvacThermostat', ['SinopeBacklight'], manuSinope);
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
main_cycle_output: {
|
|
212
|
+
key: ['main_cycle_output'],
|
|
213
|
+
convertSet: async (entity, key, value, meta) => {
|
|
214
|
+
const lookup = {'15_sec': 15, '5_min': 300, '10_min': 600, '15_min': 900, '20_min': 1200, '30_min': 1800};
|
|
215
|
+
await entity.write('hvacThermostat', {SinopeMainCycleOutput: lookup[value]}, manuSinope);
|
|
216
|
+
return {state: {'main_cycle_output': value}};
|
|
217
|
+
},
|
|
218
|
+
convertGet: async (entity, key, meta) => {
|
|
219
|
+
await entity.read('hvacThermostat', ['SinopeMainCycleOutput'], manuSinope);
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
aux_cycle_output: {
|
|
223
|
+
// TH1400ZB specific
|
|
224
|
+
key: ['aux_cycle_output'],
|
|
225
|
+
convertSet: async (entity, key, value, meta) => {
|
|
226
|
+
const lookup = {'off': 65535, '15_sec': 15, '5_min': 300, '10_min': 600, '15_min': 900, '20_min': 1200, '30_min': 1800};
|
|
227
|
+
await entity.write('hvacThermostat', {SinopeAuxCycleOutput: lookup[value]});
|
|
228
|
+
return {state: {'aux_cycle_output': value}};
|
|
229
|
+
},
|
|
230
|
+
convertGet: async (entity, key, meta) => {
|
|
231
|
+
await entity.read('hvacThermostat', ['SinopeAuxCycleOutput']);
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
enable_outdoor_temperature: {
|
|
235
|
+
key: ['enable_outdoor_temperature'],
|
|
236
|
+
convertSet: async (entity, key, value, meta) => {
|
|
237
|
+
if (value.toLowerCase() == 'on') {
|
|
238
|
+
await entity.write('manuSpecificSinope', {outdoorTempToDisplayTimeout: 10800}, manuSinope);
|
|
239
|
+
} else if (value.toLowerCase() == 'off') {
|
|
240
|
+
// set timer to 12 sec in order to disable outdoor temperature
|
|
241
|
+
await entity.write('manuSpecificSinope', {outdoorTempToDisplayTimeout: 12}, manuSinope);
|
|
242
|
+
}
|
|
243
|
+
return {readAfterWriteTime: 250, state: {enable_outdoor_temperature: value}};
|
|
244
|
+
},
|
|
245
|
+
convertGet: async (entity, key, meta) => {
|
|
246
|
+
await entity.read('manuSpecificSinope', ['outdoorTempToDisplayTimeout'], manuSinope);
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
outdoor_temperature: {
|
|
250
|
+
key: ['thermostat_outdoor_temperature'],
|
|
251
|
+
convertSet: async (entity, key, value, meta) => {
|
|
252
|
+
if (value > -100 && value < 100) {
|
|
253
|
+
await entity.write('manuSpecificSinope', {outdoorTempToDisplay: value * 100}, manuSinope);
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
thermostat_time: {
|
|
258
|
+
key: ['thermostat_time'],
|
|
259
|
+
convertSet: async (entity, key, value, meta) => {
|
|
260
|
+
if (value === '') {
|
|
261
|
+
const thermostatDate = new Date();
|
|
262
|
+
const thermostatTimeSec = thermostatDate.getTime() / 1000;
|
|
263
|
+
const thermostatTimezoneOffsetSec = thermostatDate.getTimezoneOffset() * 60;
|
|
264
|
+
const currentTimeToDisplay = Math.round(thermostatTimeSec - thermostatTimezoneOffsetSec - 946684800);
|
|
265
|
+
await entity.write('manuSpecificSinope', {currentTimeToDisplay}, manuSinope);
|
|
266
|
+
} else if (value !== '') {
|
|
267
|
+
await entity.write('manuSpecificSinope', {currentTimeToDisplay: value}, manuSinope);
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
floor_control_mode: {
|
|
272
|
+
// TH1300ZB and TH1400ZB specific
|
|
273
|
+
key: ['floor_control_mode'],
|
|
274
|
+
convertSet: async (entity, key, value, meta) => {
|
|
275
|
+
if (typeof value !== 'string') {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
const lookup = {'ambiant': 1, 'floor': 2};
|
|
279
|
+
value = value.toLowerCase();
|
|
280
|
+
if (lookup.hasOwnProperty(value)) {
|
|
281
|
+
await entity.write('manuSpecificSinope', {floorControlMode: lookup[value]});
|
|
282
|
+
}
|
|
283
|
+
return {readAfterWriteTime: 250, state: {floor_control_mode: value}};
|
|
284
|
+
},
|
|
285
|
+
convertGet: async (entity, key, meta) => {
|
|
286
|
+
await entity.read('manuSpecificSinope', ['floorControlMode']);
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
ambiant_max_heat_setpoint: {
|
|
290
|
+
// TH1300ZB and TH1400ZBspecific
|
|
291
|
+
key: ['ambiant_max_heat_setpoint'],
|
|
292
|
+
convertSet: async (entity, key, value, meta) => {
|
|
293
|
+
if ((value >= 5 && value <= 36) || value == 'off') {
|
|
294
|
+
await entity.write('manuSpecificSinope', {ambiantMaxHeatSetpointLimit: (value == 'off' ? -32768 : value * 100)});
|
|
295
|
+
return {readAfterWriteTime: 250, state: {ambiant_max_heat_setpoint: value}};
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
convertGet: async (entity, key, meta) => {
|
|
299
|
+
await entity.read('manuSpecificSinope', ['ambiantMaxHeatSetpointLimit']);
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
floor_min_heat_setpoint: {
|
|
303
|
+
// TH1300ZB and TH1400ZB specific
|
|
304
|
+
key: ['floor_min_heat_setpoint'],
|
|
305
|
+
convertSet: async (entity, key, value, meta) => {
|
|
306
|
+
if ((value >= 5 && value <= 34) || value == 'off') {
|
|
307
|
+
await entity.write('manuSpecificSinope', {floorMinHeatSetpointLimit: (value == 'off' ? -32768 : value * 100)});
|
|
308
|
+
return {readAfterWriteTime: 250, state: {floor_min_heat_setpoint: value}};
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
convertGet: async (entity, key, meta) => {
|
|
312
|
+
await entity.read('manuSpecificSinope', ['floorMinHeatSetpointLimit']);
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
floor_max_heat_setpoint: {
|
|
316
|
+
// TH1300ZB and TH1400ZB specific
|
|
317
|
+
key: ['floor_max_heat_setpoint'],
|
|
318
|
+
convertSet: async (entity, key, value, meta) => {
|
|
319
|
+
if ((value >= 7 && value <= 36) || value == 'off') {
|
|
320
|
+
await entity.write('manuSpecificSinope', {floorMaxHeatSetpointLimit: (value == 'off' ? -32768 : value * 100)});
|
|
321
|
+
return {readAfterWriteTime: 250, state: {floor_max_heat_setpoint: value}};
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
convertGet: async (entity, key, meta) => {
|
|
325
|
+
await entity.read('manuSpecificSinope', ['floorMaxHeatSetpointLimit']);
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
temperature_sensor: {
|
|
329
|
+
// TH1300ZB and TH1400ZB specific
|
|
330
|
+
key: ['floor_temperature_sensor'],
|
|
331
|
+
convertSet: async (entity, key, value, meta) => {
|
|
332
|
+
if (typeof value !== 'string') {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const lookup = {'10k': 0, '12k': 1};
|
|
336
|
+
value = value.toLowerCase();
|
|
337
|
+
if (lookup.hasOwnProperty(value)) {
|
|
338
|
+
await entity.write('manuSpecificSinope', {temperatureSensor: lookup[value]});
|
|
339
|
+
}
|
|
340
|
+
return {readAfterWriteTime: 250, state: {floor_temperature_sensor: value}};
|
|
341
|
+
},
|
|
342
|
+
convertGet: async (entity, key, meta) => {
|
|
343
|
+
await entity.read('manuSpecificSinope', ['temperatureSensor']);
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
time_format: {
|
|
347
|
+
key: ['time_format'],
|
|
348
|
+
convertSet: async (entity, key, value, meta) => {
|
|
349
|
+
if (typeof value !== 'string') {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const lookup = {'24h': 0, '12h': 1};
|
|
353
|
+
value = value.toLowerCase();
|
|
354
|
+
if (lookup.hasOwnProperty(value)) {
|
|
355
|
+
await entity.write('manuSpecificSinope', {timeFormatToDisplay: lookup[value]}, manuSinope);
|
|
356
|
+
return {readAfterWriteTime: 250, state: {time_format: value}};
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
convertGet: async (entity, key, meta) => {
|
|
360
|
+
await entity.read('manuSpecificSinope', ['timeFormatToDisplay'], manuSinope);
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
connected_load: {
|
|
364
|
+
// TH1400ZB specific
|
|
365
|
+
key: ['connected_load'],
|
|
366
|
+
convertSet: async (entity, key, value, meta) => {
|
|
367
|
+
await entity.write('manuSpecificSinope', {connectedLoad: value});
|
|
368
|
+
return {state: {connected_load: value}};
|
|
369
|
+
},
|
|
370
|
+
convertGet: async (entity, key, meta) => {
|
|
371
|
+
await entity.read('manuSpecificSinope', ['connectedLoad']);
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
aux_connected_load: {
|
|
375
|
+
// TH1400ZB specific
|
|
376
|
+
key: ['aux_connected_load'],
|
|
377
|
+
convertSet: async (entity, key, value, meta) => {
|
|
378
|
+
await entity.write('manuSpecificSinope', {auxConnectedLoad: value});
|
|
379
|
+
return {readAfterWriteTime: 250, state: {aux_connected_load: value}};
|
|
380
|
+
},
|
|
381
|
+
convertGet: async (entity, key, meta) => {
|
|
382
|
+
await entity.read('manuSpecificSinope', ['auxConnectedLoad']);
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
pump_protection: {
|
|
386
|
+
// TH1400ZB specific
|
|
387
|
+
key: ['pump_protection'],
|
|
388
|
+
convertSet: async (entity, key, value, meta) => {
|
|
389
|
+
if (value.toLowerCase() == 'on') {
|
|
390
|
+
await entity.write('manuSpecificSinope', {pumpProtection: 1});
|
|
391
|
+
} else if (value.toLowerCase() == 'off') {
|
|
392
|
+
await entity.write('manuSpecificSinope', {pumpProtection: 255});
|
|
393
|
+
}
|
|
394
|
+
return {readAfterWriteTime: 250, state: {pump_protection: value}};
|
|
395
|
+
},
|
|
396
|
+
convertGet: async (entity, key, meta) => {
|
|
397
|
+
await entity.read('manuSpecificSinope', ['pumpProtection']);
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
led_intensity_on: {
|
|
401
|
+
// DM25x0ZB and SW2500ZB
|
|
402
|
+
key: ['led_intensity_on'],
|
|
403
|
+
convertSet: async (entity, key, value, meta) => {
|
|
404
|
+
if (value >= 0 && value <= 100) {
|
|
405
|
+
await entity.write('manuSpecificSinope', {ledIntensityOn: value});
|
|
406
|
+
}
|
|
407
|
+
return {readAfterWriteTime: 250, state: {ledIntensityOn: value}};
|
|
408
|
+
},
|
|
409
|
+
convertGet: async (entity, key, meta) => {
|
|
410
|
+
await entity.read('manuSpecificSinope', ['ledIntensityOn']);
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
led_intensity_off: {
|
|
414
|
+
// DM2500ZB and SW2500ZB
|
|
415
|
+
key: ['led_intensity_off'],
|
|
416
|
+
convertSet: async (entity, key, value, meta) => {
|
|
417
|
+
if (value >= 0 && value <= 100) {
|
|
418
|
+
await entity.write('manuSpecificSinope', {ledIntensityOff: value});
|
|
419
|
+
}
|
|
420
|
+
return {readAfterWriteTime: 250, state: {ledIntensityOff: value}};
|
|
421
|
+
},
|
|
422
|
+
convertGet: async (entity, key, meta) => {
|
|
423
|
+
await entity.read('manuSpecificSinope', ['ledIntensityOff']);
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
led_color_on: {
|
|
427
|
+
// DM25x0ZB and SW2500ZB
|
|
428
|
+
key: ['led_color_on'],
|
|
429
|
+
convertSet: async (entity, key, value, meta) => {
|
|
430
|
+
const r = (value.r >= 0 && value.r <= 255) ? value.r : 0;
|
|
431
|
+
const g = (value.g >= 0 && value.g <= 255) ? value.g : 0;
|
|
432
|
+
const b = (value.b >= 0 && value.b <= 255) ? value.b : 0;
|
|
433
|
+
|
|
434
|
+
const valueHex = r + g * 256 + (b * 256 ** 2);
|
|
435
|
+
await entity.write('manuSpecificSinope', {ledColorOn: valueHex});
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
led_color_off: {
|
|
439
|
+
// DM25x0ZB and SW2500ZB
|
|
440
|
+
key: ['led_color_off'],
|
|
441
|
+
convertSet: async (entity, key, value, meta) => {
|
|
442
|
+
const r = (value.r >= 0 && value.r <= 255) ? value.r : 0;
|
|
443
|
+
const g = (value.g >= 0 && value.g <= 255) ? value.g : 0;
|
|
444
|
+
const b = (value.b >= 0 && value.b <= 255) ? value.b : 0;
|
|
445
|
+
|
|
446
|
+
const valueHex = r + g * 256 + b * 256 ** 2;
|
|
447
|
+
await entity.write('manuSpecificSinope', {ledColorOff: valueHex});
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
minimum_brightness: {
|
|
451
|
+
// DM2x0ZB
|
|
452
|
+
key: ['minimum_brightness'],
|
|
453
|
+
convertSet: async (entity, key, value, meta) => {
|
|
454
|
+
if (value >= 0 && value <= 3000) {
|
|
455
|
+
await entity.write('manuSpecificSinope', {minimumBrightness: value});
|
|
456
|
+
}
|
|
457
|
+
return {readAfterWriteTime: 250, state: {minimumBrightness: value}};
|
|
458
|
+
},
|
|
459
|
+
convertGet: async (entity, key, meta) => {
|
|
460
|
+
await entity.read('manuSpecificSinope', ['minimumBrightness']);
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
timer_seconds: {
|
|
464
|
+
// DM25x0ZB and SW2500ZB
|
|
465
|
+
key: ['timer_seconds'],
|
|
466
|
+
convertSet: async (entity, key, value, meta) => {
|
|
467
|
+
if (value >= 0 && value <= 10800) {
|
|
468
|
+
await entity.write('manuSpecificSinope', {dimmerTimmer: value});
|
|
469
|
+
}
|
|
470
|
+
return {readAfterWriteTime: 250, state: {dimmerTimmer: value}};
|
|
471
|
+
},
|
|
472
|
+
convertGet: async (entity, key, meta) => {
|
|
473
|
+
await entity.read('manuSpecificSinope', ['dimmerTimmer']);
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
module.exports = [
|
|
478
|
+
{
|
|
479
|
+
zigbeeModel: ['TH1123ZB'],
|
|
480
|
+
model: 'TH1123ZB',
|
|
481
|
+
vendor: 'Sinopé',
|
|
482
|
+
description: 'Zigbee line volt thermostat',
|
|
483
|
+
fromZigbee: [fzLocal.thermostat, fzLocal.sinope, fz.legacy.hvac_user_interface,
|
|
484
|
+
fz.electrical_measurement, fz.metering, fz.ignore_temperature_report],
|
|
485
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
486
|
+
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim,
|
|
487
|
+
tzLocal.thermostat_time, tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature,
|
|
488
|
+
tzLocal.thermostat_occupancy, tzLocal.main_cycle_output, tz.electrical_measurement_power],
|
|
489
|
+
exposes: [
|
|
490
|
+
exposes.climate()
|
|
491
|
+
.withSetpoint('occupied_heating_setpoint', 5, 30, 0.5)
|
|
492
|
+
.withSetpoint('unoccupied_heating_setpoint', 5, 30, 0.5)
|
|
493
|
+
.withLocalTemperature()
|
|
494
|
+
.withSystemMode(['off', 'heat'], ea.ALL, 'Mode of the thermostat')
|
|
495
|
+
.withPiHeatingDemand()
|
|
496
|
+
.withRunningState(['idle', 'heat'], ea.STATE),
|
|
497
|
+
exposes.enum('thermostat_occupancy', ea.ALL, ['unoccupied', 'occupied'])
|
|
498
|
+
.withDescription('Occupancy state of the thermostat'),
|
|
499
|
+
exposes.binary('enable_outdoor_temperature', ea.ALL, 'ON', 'OFF')
|
|
500
|
+
.withDescription('Showing outdoor temperature on secondary display'),
|
|
501
|
+
exposes.enum('temperature_display_mode', ea.ALL, ['celsius', 'fahrenheit'])
|
|
502
|
+
.withDescription('The temperature format displayed on the thermostat screen'),
|
|
503
|
+
exposes.enum('time_format', ea.ALL, ['24h', '12h'])
|
|
504
|
+
.withDescription('The time format featured on the thermostat display'),
|
|
505
|
+
exposes.enum('backlight_auto_dim', ea.ALL, ['on_demand', 'sensing'])
|
|
506
|
+
.withDescription('Control backlight dimming behavior'),
|
|
507
|
+
exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock1'])
|
|
508
|
+
.withDescription('Enables or disables the device’s buttons'),
|
|
509
|
+
exposes.enum('main_cycle_output', ea.ALL, ['15_sec', '15_min'])
|
|
510
|
+
.withDescription('The length of the control cycle: 15_sec=normal 15_min=fan'),
|
|
511
|
+
e.power().withAccess(ea.STATE_GET), e.current(), e.voltage(), e.energy(),
|
|
512
|
+
],
|
|
513
|
+
|
|
514
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
515
|
+
const endpoint = device.getEndpoint(1);
|
|
516
|
+
const binds = [
|
|
517
|
+
'genBasic', 'genIdentify', 'genGroups', 'hvacThermostat', 'hvacUserInterfaceCfg',
|
|
518
|
+
'msTemperatureMeasurement', 'haElectricalMeasurement', 'seMetering',
|
|
519
|
+
'manuSpecificSinope'];
|
|
520
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
521
|
+
await reporting.thermostatTemperature(endpoint);
|
|
522
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
523
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
524
|
+
|
|
525
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
526
|
+
await endpoint.configureReporting('msTemperatureMeasurement', [{
|
|
527
|
+
attribute: 'tolerance', minimumReportInterval: 1, maximumReportInterval: 0xFFFF, reportableChange: 1}]);
|
|
528
|
+
try {
|
|
529
|
+
await reporting.thermostatSystemMode(endpoint);
|
|
530
|
+
} catch (error) {/* Not all support this */}
|
|
531
|
+
|
|
532
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
533
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [1, 1]});
|
|
534
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
535
|
+
try {
|
|
536
|
+
await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']);
|
|
537
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 1: 1W
|
|
538
|
+
} catch (error) {
|
|
539
|
+
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {'acPowerMultiplier': 1, 'acPowerDivisor': 1});
|
|
540
|
+
}
|
|
541
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 100}); // divider 1000: 0.1Arms
|
|
542
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 5}); // divider 10: 0.5Vrms
|
|
543
|
+
},
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
zigbeeModel: ['TH1124ZB'],
|
|
547
|
+
model: 'TH1124ZB',
|
|
548
|
+
vendor: 'Sinopé',
|
|
549
|
+
description: 'Zigbee line volt thermostat',
|
|
550
|
+
fromZigbee: [fzLocal.thermostat, fzLocal.sinope, fz.legacy.hvac_user_interface,
|
|
551
|
+
fz.electrical_measurement, fz.metering, fz.ignore_temperature_report],
|
|
552
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
553
|
+
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim,
|
|
554
|
+
tzLocal.thermostat_time, tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature,
|
|
555
|
+
tzLocal.thermostat_occupancy, tzLocal.main_cycle_output, tz.electrical_measurement_power],
|
|
556
|
+
exposes: [
|
|
557
|
+
exposes.climate()
|
|
558
|
+
.withSetpoint('occupied_heating_setpoint', 5, 30, 0.5)
|
|
559
|
+
.withSetpoint('unoccupied_heating_setpoint', 5, 30, 0.5)
|
|
560
|
+
.withLocalTemperature()
|
|
561
|
+
.withSystemMode(['off', 'heat'], ea.ALL, 'Mode of the thermostat')
|
|
562
|
+
.withPiHeatingDemand()
|
|
563
|
+
.withRunningState(['idle', 'heat'], ea.STATE),
|
|
564
|
+
exposes.enum('thermostat_occupancy', ea.ALL, ['unoccupied', 'occupied'])
|
|
565
|
+
.withDescription('Occupancy state of the thermostat'),
|
|
566
|
+
exposes.binary('enable_outdoor_temperature', ea.ALL, 'ON', 'OFF')
|
|
567
|
+
.withDescription('Showing outdoor temperature on secondary display'),
|
|
568
|
+
exposes.enum('temperature_display_mode', ea.ALL, ['celsius', 'fahrenheit'])
|
|
569
|
+
.withDescription('The temperature format displayed on the thermostat screen'),
|
|
570
|
+
exposes.enum('time_format', ea.ALL, ['24h', '12h'])
|
|
571
|
+
.withDescription('The time format featured on the thermostat display'),
|
|
572
|
+
exposes.enum('backlight_auto_dim', ea.ALL, ['on_demand', 'sensing'])
|
|
573
|
+
.withDescription('Control backlight dimming behavior'),
|
|
574
|
+
exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock1'])
|
|
575
|
+
.withDescription('Enables or disables the device’s buttons'),
|
|
576
|
+
exposes.enum('main_cycle_output', ea.ALL, ['15_sec', '15_min'])
|
|
577
|
+
.withDescription('The length of the control cycle: 15_sec=normal 15_min=fan'),
|
|
578
|
+
e.power().withAccess(ea.STATE_GET), e.current(), e.voltage(), e.energy(),
|
|
579
|
+
],
|
|
580
|
+
|
|
581
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
582
|
+
const endpoint = device.getEndpoint(1);
|
|
583
|
+
const binds = [
|
|
584
|
+
'genBasic', 'genIdentify', 'genGroups', 'hvacThermostat', 'hvacUserInterfaceCfg',
|
|
585
|
+
'msTemperatureMeasurement', 'haElectricalMeasurement', 'seMetering',
|
|
586
|
+
'manuSpecificSinope'];
|
|
587
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
588
|
+
await reporting.thermostatTemperature(endpoint);
|
|
589
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
590
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
591
|
+
|
|
592
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
593
|
+
await endpoint.configureReporting('msTemperatureMeasurement', [{
|
|
594
|
+
attribute: 'tolerance', minimumReportInterval: 1, maximumReportInterval: 0xFFFF, reportableChange: 1}]);
|
|
595
|
+
try {
|
|
596
|
+
await reporting.thermostatSystemMode(endpoint);
|
|
597
|
+
} catch (error) {/* Not all support this */}
|
|
598
|
+
|
|
599
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
600
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [1, 1]});
|
|
601
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
602
|
+
try {
|
|
603
|
+
await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']);
|
|
604
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 1: 1W
|
|
605
|
+
} catch (error) {
|
|
606
|
+
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {'acPowerMultiplier': 1, 'acPowerDivisor': 1});
|
|
607
|
+
}
|
|
608
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 100}); // divider 1000: 0.1Arms
|
|
609
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 5}); // divider 10: 0.5Vrms
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
zigbeeModel: ['TH1123ZB-G2'],
|
|
614
|
+
model: 'TH1123ZB-G2',
|
|
615
|
+
vendor: 'Sinopé',
|
|
616
|
+
description: 'Zigbee line volt thermostat',
|
|
617
|
+
fromZigbee: [fzLocal.thermostat, fzLocal.sinope, fz.legacy.hvac_user_interface,
|
|
618
|
+
fz.electrical_measurement, fz.metering, fz.ignore_temperature_report],
|
|
619
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
620
|
+
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim,
|
|
621
|
+
tzLocal.thermostat_time, tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature,
|
|
622
|
+
tzLocal.thermostat_occupancy, tzLocal.main_cycle_output, tz.electrical_measurement_power],
|
|
623
|
+
exposes: [
|
|
624
|
+
exposes.climate()
|
|
625
|
+
.withSetpoint('occupied_heating_setpoint', 5, 30, 0.5)
|
|
626
|
+
.withSetpoint('unoccupied_heating_setpoint', 5, 30, 0.5)
|
|
627
|
+
.withLocalTemperature()
|
|
628
|
+
.withSystemMode(['off', 'heat'], ea.ALL, 'Mode of the thermostat')
|
|
629
|
+
.withPiHeatingDemand()
|
|
630
|
+
.withRunningState(['idle', 'heat'], ea.STATE),
|
|
631
|
+
exposes.enum('thermostat_occupancy', ea.ALL, ['unoccupied', 'occupied'])
|
|
632
|
+
.withDescription('Occupancy state of the thermostat'),
|
|
633
|
+
exposes.binary('enable_outdoor_temperature', ea.ALL, 'ON', 'OFF')
|
|
634
|
+
.withDescription('Showing outdoor temperature on secondary display'),
|
|
635
|
+
exposes.enum('temperature_display_mode', ea.ALL, ['celsius', 'fahrenheit'])
|
|
636
|
+
.withDescription('The temperature format displayed on the thermostat screen'),
|
|
637
|
+
exposes.enum('time_format', ea.ALL, ['24h', '12h'])
|
|
638
|
+
.withDescription('The time format featured on the thermostat display'),
|
|
639
|
+
exposes.enum('backlight_auto_dim', ea.ALL, ['on_demand', 'sensing'])
|
|
640
|
+
.withDescription('Control backlight dimming behavior'),
|
|
641
|
+
exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock1'])
|
|
642
|
+
.withDescription('Enables or disables the device’s buttons'),
|
|
643
|
+
exposes.enum('main_cycle_output', ea.ALL, ['15_sec', '15_min'])
|
|
644
|
+
.withDescription('The length of the control cycle: 15_sec=normal 15_min=fan'),
|
|
645
|
+
e.power().withAccess(ea.STATE_GET), e.current(), e.voltage(), e.energy(),
|
|
646
|
+
],
|
|
647
|
+
|
|
648
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
649
|
+
const endpoint = device.getEndpoint(1);
|
|
650
|
+
const binds = [
|
|
651
|
+
'genBasic', 'genIdentify', 'genGroups', 'hvacThermostat', 'hvacUserInterfaceCfg',
|
|
652
|
+
'msTemperatureMeasurement', 'haElectricalMeasurement', 'seMetering',
|
|
653
|
+
'manuSpecificSinope'];
|
|
654
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds); // This G2 version has limited memory space
|
|
655
|
+
const thermostatDate = new Date();
|
|
656
|
+
const thermostatTimeSec = thermostatDate.getTime() / 1000;
|
|
657
|
+
const thermostatTimezoneOffsetSec = thermostatDate.getTimezoneOffset() * 60;
|
|
658
|
+
const currentTimeToDisplay = Math.round(thermostatTimeSec - thermostatTimezoneOffsetSec - 946684800);
|
|
659
|
+
await endpoint.write('manuSpecificSinope', {currentTimeToDisplay}, manuSinope);
|
|
660
|
+
await endpoint.write('manuSpecificSinope', {'secondScreenBehavior': 0}, manuSinope); // Mode auto
|
|
661
|
+
|
|
662
|
+
await reporting.thermostatTemperature(endpoint);
|
|
663
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
664
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
665
|
+
await reporting.thermostatSystemMode(endpoint);
|
|
666
|
+
|
|
667
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
668
|
+
await endpoint.configureReporting('msTemperatureMeasurement', [{
|
|
669
|
+
attribute: 'tolerance', minimumReportInterval: 1, maximumReportInterval: 0xFFFF, reportableChange: 1}]);
|
|
670
|
+
|
|
671
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
672
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [1, 1]});
|
|
673
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
674
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 1: 1W
|
|
675
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 100}); // divider 1000: 0.1Arms
|
|
676
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 5}); // divider 10: 0.5Vrms
|
|
677
|
+
|
|
678
|
+
// Disable default reporting (not used by Sinope)
|
|
679
|
+
await reporting.thermostatRunningState(endpoint, {min: 1, max: 0xFFFF});
|
|
680
|
+
try {
|
|
681
|
+
await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
|
|
682
|
+
} catch (error) {/* Do nothing */}
|
|
683
|
+
},
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
zigbeeModel: ['TH1124ZB-G2'],
|
|
687
|
+
model: 'TH1124ZB-G2',
|
|
688
|
+
vendor: 'Sinopé',
|
|
689
|
+
description: 'Zigbee line volt thermostat',
|
|
690
|
+
fromZigbee: [fzLocal.thermostat, fzLocal.sinope, fz.legacy.hvac_user_interface,
|
|
691
|
+
fz.electrical_measurement, fz.metering, fz.ignore_temperature_report],
|
|
692
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
693
|
+
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim,
|
|
694
|
+
tzLocal.thermostat_time, tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature,
|
|
695
|
+
tzLocal.thermostat_occupancy, tzLocal.main_cycle_output, tz.electrical_measurement_power],
|
|
696
|
+
exposes: [
|
|
697
|
+
exposes.climate()
|
|
698
|
+
.withSetpoint('occupied_heating_setpoint', 5, 30, 0.5)
|
|
699
|
+
.withSetpoint('unoccupied_heating_setpoint', 5, 30, 0.5)
|
|
700
|
+
.withLocalTemperature()
|
|
701
|
+
.withSystemMode(['off', 'heat'], ea.ALL, 'Mode of the thermostat')
|
|
702
|
+
.withPiHeatingDemand()
|
|
703
|
+
.withRunningState(['idle', 'heat'], ea.STATE),
|
|
704
|
+
exposes.enum('thermostat_occupancy', ea.ALL, ['unoccupied', 'occupied'])
|
|
705
|
+
.withDescription('Occupancy state of the thermostat'),
|
|
706
|
+
exposes.binary('enable_outdoor_temperature', ea.ALL, 'ON', 'OFF')
|
|
707
|
+
.withDescription('Showing outdoor temperature on secondary display'),
|
|
708
|
+
exposes.enum('temperature_display_mode', ea.ALL, ['celsius', 'fahrenheit'])
|
|
709
|
+
.withDescription('The temperature format displayed on the thermostat screen'),
|
|
710
|
+
exposes.enum('time_format', ea.ALL, ['24h', '12h'])
|
|
711
|
+
.withDescription('The time format featured on the thermostat display'),
|
|
712
|
+
exposes.enum('backlight_auto_dim', ea.ALL, ['on_demand', 'sensing'])
|
|
713
|
+
.withDescription('Control backlight dimming behavior'),
|
|
714
|
+
exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock1'])
|
|
715
|
+
.withDescription('Enables or disables the device’s buttons'),
|
|
716
|
+
exposes.enum('main_cycle_output', ea.ALL, ['15_sec', '15_min'])
|
|
717
|
+
.withDescription('The length of the control cycle: 15_sec=normal 15_min=fan'),
|
|
718
|
+
e.power().withAccess(ea.STATE_GET), e.current(), e.voltage(), e.energy(),
|
|
719
|
+
],
|
|
720
|
+
|
|
721
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
722
|
+
const endpoint = device.getEndpoint(1);
|
|
723
|
+
const binds = [
|
|
724
|
+
'genBasic', 'genIdentify', 'genGroups', 'hvacThermostat', 'hvacUserInterfaceCfg',
|
|
725
|
+
'msTemperatureMeasurement', 'haElectricalMeasurement', 'seMetering',
|
|
726
|
+
'manuSpecificSinope'];
|
|
727
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds); // This G2 version has limited memory space
|
|
728
|
+
const thermostatDate = new Date();
|
|
729
|
+
const thermostatTimeSec = thermostatDate.getTime() / 1000;
|
|
730
|
+
const thermostatTimezoneOffsetSec = thermostatDate.getTimezoneOffset() * 60;
|
|
731
|
+
const currentTimeToDisplay = Math.round(thermostatTimeSec - thermostatTimezoneOffsetSec - 946684800);
|
|
732
|
+
await endpoint.write('manuSpecificSinope', {currentTimeToDisplay}, manuSinope);
|
|
733
|
+
await endpoint.write('manuSpecificSinope', {'secondScreenBehavior': 0}, manuSinope); // Mode auto
|
|
734
|
+
|
|
735
|
+
await reporting.thermostatTemperature(endpoint);
|
|
736
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
737
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
738
|
+
await reporting.thermostatSystemMode(endpoint);
|
|
739
|
+
|
|
740
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
741
|
+
await endpoint.configureReporting('msTemperatureMeasurement', [{
|
|
742
|
+
attribute: 'tolerance', minimumReportInterval: 1, maximumReportInterval: 0xFFFF, reportableChange: 1}]);
|
|
743
|
+
|
|
744
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
745
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [1, 1]});
|
|
746
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
747
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 1: 1W
|
|
748
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 100}); // divider 1000: 0.1Arms
|
|
749
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 5}); // divider 10: 0.5Vrms
|
|
750
|
+
|
|
751
|
+
// Disable default reporting (not used by Sinope)
|
|
752
|
+
await reporting.thermostatRunningState(endpoint, {min: 1, max: 0xFFFF});
|
|
753
|
+
try {
|
|
754
|
+
await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
|
|
755
|
+
} catch (error) {/* Do nothing */}
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
zigbeeModel: ['TH1300ZB'],
|
|
760
|
+
model: 'TH1300ZB',
|
|
761
|
+
vendor: 'Sinopé',
|
|
762
|
+
description: 'Zigbee smart floor heating thermostat',
|
|
763
|
+
fromZigbee: [fzLocal.thermostat, fzLocal.sinope, fz.legacy.hvac_user_interface,
|
|
764
|
+
fz.electrical_measurement, fz.metering, fz.ignore_temperature_report],
|
|
765
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
766
|
+
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim,
|
|
767
|
+
tzLocal.thermostat_time, tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature,
|
|
768
|
+
tzLocal.thermostat_occupancy, tzLocal.floor_control_mode, tzLocal.ambiant_max_heat_setpoint, tzLocal.floor_min_heat_setpoint,
|
|
769
|
+
tzLocal.floor_max_heat_setpoint, tzLocal.temperature_sensor, tz.electrical_measurement_power],
|
|
770
|
+
exposes: [
|
|
771
|
+
exposes.climate()
|
|
772
|
+
.withSetpoint('occupied_heating_setpoint', 5, 36, 0.5)
|
|
773
|
+
.withSetpoint('unoccupied_heating_setpoint', 5, 36, 0.5)
|
|
774
|
+
.withLocalTemperature()
|
|
775
|
+
.withSystemMode(['off', 'heat'], ea.ALL, 'Mode of the thermostat')
|
|
776
|
+
.withPiHeatingDemand()
|
|
777
|
+
.withRunningState(['idle', 'heat'], ea.STATE),
|
|
778
|
+
exposes.enum('thermostat_occupancy', ea.ALL, ['unoccupied', 'occupied'])
|
|
779
|
+
.withDescription('Occupancy state of the thermostat'),
|
|
780
|
+
exposes.binary('enable_outdoor_temperature', ea.ALL, 'ON', 'OFF')
|
|
781
|
+
.withDescription('Showing outdoor temperature on secondary display'),
|
|
782
|
+
exposes.enum('temperature_display_mode', ea.ALL, ['celsius', 'fahrenheit'])
|
|
783
|
+
.withDescription('The temperature format displayed on the thermostat screen'),
|
|
784
|
+
exposes.enum('time_format', ea.ALL, ['24h', '12h'])
|
|
785
|
+
.withDescription('The time format featured on the thermostat display'),
|
|
786
|
+
exposes.enum('backlight_auto_dim', ea.ALL, ['on_demand', 'sensing'])
|
|
787
|
+
.withDescription('Control backlight dimming behavior'),
|
|
788
|
+
exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock1'])
|
|
789
|
+
.withDescription('Enables or disables the device’s buttons'),
|
|
790
|
+
e.power().withAccess(ea.STATE_GET), e.current(), e.voltage(), e.energy()],
|
|
791
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
792
|
+
const endpoint = device.getEndpoint(1);
|
|
793
|
+
const binds = [
|
|
794
|
+
'genBasic', 'genIdentify', 'genGroups', 'hvacThermostat', 'hvacUserInterfaceCfg',
|
|
795
|
+
'haElectricalMeasurement', 'msTemperatureMeasurement', 'seMetering', 'manuSpecificSinope'];
|
|
796
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
797
|
+
await reporting.thermostatTemperature(endpoint);
|
|
798
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
799
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
800
|
+
try {
|
|
801
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
802
|
+
} catch (error) {/* Do nothing*/}
|
|
803
|
+
try {
|
|
804
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [1, 1]});
|
|
805
|
+
} catch (error) {/* Do nothing*/}
|
|
806
|
+
try {
|
|
807
|
+
await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']);
|
|
808
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 1: 1W
|
|
809
|
+
} catch (error) {
|
|
810
|
+
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {'acPowerMultiplier': 1, 'acPowerDivisor': 1});
|
|
811
|
+
}
|
|
812
|
+
try {
|
|
813
|
+
await endpoint.read('haElectricalMeasurement', ['acCurrentMultiplier', 'acCurrentDivisor']);
|
|
814
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 100}); // divider 1000: 0.1Arms
|
|
815
|
+
} catch (error) {/* Do nothing*/}
|
|
816
|
+
try {
|
|
817
|
+
await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor']);
|
|
818
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 5}); // divider 10: 0.5Vrms
|
|
819
|
+
} catch (error) {/* Do nothing*/}
|
|
820
|
+
|
|
821
|
+
try {
|
|
822
|
+
await reporting.thermostatKeypadLockMode(endpoint);
|
|
823
|
+
} catch (error) {
|
|
824
|
+
// Not all support this: https://github.com/Koenkk/zigbee2mqtt/issues/3760
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
await endpoint.configureReporting('manuSpecificSinope', [{attribute: 'GFCiStatus', minimumReportInterval: 1,
|
|
828
|
+
maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1}]);
|
|
829
|
+
await endpoint.configureReporting('manuSpecificSinope', [{attribute: 'floorLimitStatus', minimumReportInterval: 1,
|
|
830
|
+
maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1}]);
|
|
831
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // disable reporting
|
|
832
|
+
},
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
zigbeeModel: ['TH1400ZB'],
|
|
836
|
+
model: 'TH1400ZB',
|
|
837
|
+
vendor: 'Sinopé',
|
|
838
|
+
description: 'Zigbee low volt thermostat',
|
|
839
|
+
fromZigbee: [fzLocal.thermostat, fzLocal.sinope, fz.legacy.hvac_user_interface,
|
|
840
|
+
fz.electrical_measurement, fz.metering, fz.ignore_temperature_report],
|
|
841
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
842
|
+
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim,
|
|
843
|
+
tzLocal.thermostat_time, tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature,
|
|
844
|
+
tzLocal.thermostat_occupancy, tzLocal.floor_control_mode, tzLocal.ambiant_max_heat_setpoint, tzLocal.floor_min_heat_setpoint,
|
|
845
|
+
tzLocal.floor_max_heat_setpoint, tzLocal.temperature_sensor, tz.thermostat_min_heat_setpoint_limit,
|
|
846
|
+
tz.thermostat_max_heat_setpoint_limit, tzLocal.connected_load, tzLocal.aux_connected_load, tzLocal.main_cycle_output,
|
|
847
|
+
tzLocal.aux_cycle_output, tzLocal.pump_protection],
|
|
848
|
+
exposes: [
|
|
849
|
+
exposes.climate()
|
|
850
|
+
.withSetpoint('occupied_heating_setpoint', 5, 36, 0.5)
|
|
851
|
+
.withSetpoint('unoccupied_heating_setpoint', 5, 36, 0.5)
|
|
852
|
+
.withLocalTemperature()
|
|
853
|
+
.withSystemMode(['off', 'heat'])
|
|
854
|
+
.withPiHeatingDemand()
|
|
855
|
+
.withRunningState(['idle', 'heat'], ea.STATE),
|
|
856
|
+
e.max_heat_setpoint_limit(5, 36, 0.5),
|
|
857
|
+
e.min_heat_setpoint_limit(5, 36, 0.5),
|
|
858
|
+
exposes.enum('thermostat_occupancy', ea.ALL, ['unoccupied', 'occupied'])
|
|
859
|
+
.withDescription('Occupancy state of the thermostat'),
|
|
860
|
+
exposes.binary('enable_outdoor_temperature', ea.ALL, 'ON', 'OFF')
|
|
861
|
+
.withDescription('Showing outdoor temperature on secondary display'),
|
|
862
|
+
exposes.enum('temperature_display_mode', ea.ALL, ['celsius', 'fahrenheit'])
|
|
863
|
+
.withDescription('The temperature format displayed on the thermostat screen'),
|
|
864
|
+
exposes.enum('time_format', ea.ALL, ['24h', '12h'])
|
|
865
|
+
.withDescription('The time format featured on the thermostat display'),
|
|
866
|
+
exposes.enum('backlight_auto_dim', ea.ALL, ['on_demand', 'sensing'])
|
|
867
|
+
.withDescription('The display backlight behavior'),
|
|
868
|
+
exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock1'])
|
|
869
|
+
.withDescription('Enables or disables the device’s buttons'),
|
|
870
|
+
exposes.numeric('connected_load', ea.ALL)
|
|
871
|
+
.withUnit('W').withValueMin(1).withValueMax(20000)
|
|
872
|
+
.withDescription('The power in watts of the electrical load connected to the device'),
|
|
873
|
+
exposes.enum('floor_control_mode', ea.ALL, ['ambiant', 'floor'])
|
|
874
|
+
.withDescription('Control mode using floor or ambient temperature'),
|
|
875
|
+
exposes.numeric('floor_max_heat_setpoint', ea.ALL)
|
|
876
|
+
.withUnit('°C').withValueMin(7).withValueMax(36).withValueStep(0.5)
|
|
877
|
+
.withPreset('off', 'off', 'Use minimum permitted value')
|
|
878
|
+
.withDescription('The maximum floor temperature limit of the floor when in ambient control mode'),
|
|
879
|
+
exposes.numeric('floor_min_heat_setpoint', ea.ALL)
|
|
880
|
+
.withUnit('°C').withValueMin(5).withValueMax(34).withValueStep(0.5)
|
|
881
|
+
.withPreset('off', 'off', 'Use minimum permitted value')
|
|
882
|
+
.withDescription('The minimum floor temperature limit of the floor when in ambient control mode'),
|
|
883
|
+
exposes.numeric('ambiant_max_heat_setpoint', ea.ALL)
|
|
884
|
+
.withUnit('°C').withValueMin(5).withValueMax(36).withValueStep(0.5)
|
|
885
|
+
.withPreset('off', 'off', 'Use minimum permitted value')
|
|
886
|
+
.withDescription('The maximum ambient temperature limit when in floor control mode'),
|
|
887
|
+
exposes.enum('floor_temperature_sensor', ea.ALL, ['10k', '12k'])
|
|
888
|
+
.withDescription('The floor sensor'),
|
|
889
|
+
exposes.enum('main_cycle_output', ea.ALL, ['15_sec', '5_min', '10_min', '15_min', '20_min', '30_min'])
|
|
890
|
+
.withDescription('The length of the control cycle according to the type of load connected to the thermostats'),
|
|
891
|
+
exposes.enum('aux_cycle_output', ea.ALL, ['off', '15_sec', '5_min', '10_min', '15_min', '20_min', '30_min'])
|
|
892
|
+
.withDescription('The length of the control cycle according to the type of auxiliary load connected to the thermostats'),
|
|
893
|
+
exposes.binary('pump_protection', ea.ALL, 'ON', 'OFF')
|
|
894
|
+
.withDescription('This function prevents the seizure of the pump'),
|
|
895
|
+
exposes.numeric('aux_connected_load', ea.ALL)
|
|
896
|
+
.withUnit('W').withValueMin(0).withValueMax(20000)
|
|
897
|
+
.withDescription('The power in watts of the heater connected to the auxiliary output of the thermostat'),
|
|
898
|
+
],
|
|
899
|
+
|
|
900
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
901
|
+
const endpoint = device.getEndpoint(1);
|
|
902
|
+
const binds = [
|
|
903
|
+
'genBasic', 'genIdentify', 'genGroups', 'hvacThermostat',
|
|
904
|
+
'hvacUserInterfaceCfg', 'msTemperatureMeasurement', 'manuSpecificSinope'];
|
|
905
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
906
|
+
await reporting.thermostatTemperature(endpoint);
|
|
907
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
908
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
909
|
+
|
|
910
|
+
try {
|
|
911
|
+
await reporting.thermostatSystemMode(endpoint);
|
|
912
|
+
} catch (error) {/* Not all support this */}
|
|
913
|
+
|
|
914
|
+
await endpoint.read('hvacThermostat', ['occupiedHeatingSetpoint', 'localTemp', 'systemMode', 'pIHeatingDemand',
|
|
915
|
+
'SinopeBacklight', 'maxHeatSetpointLimit', 'minHeatSetpointLimit', 'SinopeMainCycleOutput', 'SinopeAuxCycleOutput']);
|
|
916
|
+
await endpoint.read('hvacUserInterfaceCfg', ['keypadLockout', 'tempDisplayMode']);
|
|
917
|
+
await endpoint.read('manuSpecificSinope', ['timeFormatToDisplay', 'connectedLoad', 'auxConnectedLoad', 'floorControlMode',
|
|
918
|
+
'floorMinHeatSetpointLimit', 'floorMaxHeatSetpointLimit', 'ambiantMaxHeatSetpointLimit', 'outdoorTempToDisplayTimeout',
|
|
919
|
+
'temperatureSensor', 'pumpProtection']);
|
|
920
|
+
|
|
921
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // disable reporting
|
|
922
|
+
},
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
zigbeeModel: ['TH1500ZB'],
|
|
926
|
+
model: 'TH1500ZB',
|
|
927
|
+
vendor: 'Sinopé',
|
|
928
|
+
description: 'Zigbee dual pole line volt thermostat',
|
|
929
|
+
fromZigbee: [fzLocal.thermostat, fzLocal.sinope, fz.legacy.hvac_user_interface,
|
|
930
|
+
fz.electrical_measurement, fz.metering, fz.ignore_temperature_report],
|
|
931
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
|
|
932
|
+
tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim,
|
|
933
|
+
tzLocal.thermostat_time, tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature,
|
|
934
|
+
tzLocal.thermostat_occupancy],
|
|
935
|
+
exposes: [
|
|
936
|
+
exposes.climate()
|
|
937
|
+
.withSetpoint('occupied_heating_setpoint', 5, 30, 0.5)
|
|
938
|
+
.withSetpoint('unoccupied_heating_setpoint', 5, 30, 0.5)
|
|
939
|
+
.withLocalTemperature()
|
|
940
|
+
.withSystemMode(['off', 'heat'], ea.ALL, 'Mode of the thermostat')
|
|
941
|
+
.withPiHeatingDemand()
|
|
942
|
+
.withRunningState(['idle', 'heat'], ea.STATE),
|
|
943
|
+
exposes.enum('thermostat_occupancy', ea.ALL, ['unoccupied', 'occupied'])
|
|
944
|
+
.withDescription('Occupancy state of the thermostat'),
|
|
945
|
+
exposes.binary('enable_outdoor_temperature', ea.ALL, 'ON', 'OFF')
|
|
946
|
+
.withDescription('Showing outdoor temperature on secondary display'),
|
|
947
|
+
exposes.enum('temperature_display_mode', ea.ALL, ['celsius', 'fahrenheit'])
|
|
948
|
+
.withDescription('The temperature format displayed on the thermostat screen'),
|
|
949
|
+
exposes.enum('time_format', ea.ALL, ['24h', '12h'])
|
|
950
|
+
.withDescription('The time format featured on the thermostat display'),
|
|
951
|
+
exposes.enum('backlight_auto_dim', ea.ALL, ['on_demand', 'sensing'])
|
|
952
|
+
.withDescription('Control backlight dimming behavior'),
|
|
953
|
+
exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock1'])
|
|
954
|
+
.withDescription('Enables or disables the device’s buttons'),
|
|
955
|
+
],
|
|
956
|
+
|
|
957
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
958
|
+
const endpoint = device.getEndpoint(1);
|
|
959
|
+
const binds = [
|
|
960
|
+
'genBasic', 'genIdentify', 'genGroups',
|
|
961
|
+
'hvacThermostat', 'hvacUserInterfaceCfg', 'msTemperatureMeasurement'];
|
|
962
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
963
|
+
await reporting.thermostatTemperature(endpoint);
|
|
964
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
965
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
966
|
+
},
|
|
967
|
+
},
|
|
968
|
+
{
|
|
969
|
+
zigbeeModel: ['SW2500ZB'],
|
|
970
|
+
model: 'SW2500ZB',
|
|
971
|
+
vendor: 'Sinopé',
|
|
972
|
+
description: 'Zigbee smart light switch',
|
|
973
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fzLocal.sinope],
|
|
974
|
+
toZigbee: [tz.on_off, tzLocal.timer_seconds, tzLocal.led_intensity_on, tzLocal.led_intensity_off,
|
|
975
|
+
tzLocal.led_color_on, tzLocal.led_color_off],
|
|
976
|
+
exposes: [e.switch(),
|
|
977
|
+
exposes.numeric('timer_seconds', ea.ALL).withValueMin(0).withValueMax(10800)
|
|
978
|
+
.withDescription('Automatically turn off load after x seconds'),
|
|
979
|
+
exposes.numeric('led_intensity_on', ea.ALL).withValueMin(0).withValueMax(100)
|
|
980
|
+
.withDescription('Control status LED intensity when load ON'),
|
|
981
|
+
exposes.numeric('led_intensity_off', ea.ALL).withValueMin(0).withValueMax(100)
|
|
982
|
+
.withDescription('Control status LED intensity when load OFF'),
|
|
983
|
+
exposes.composite('led_color_on', 'led_color_on', ea.SET)
|
|
984
|
+
.withFeature(exposes.numeric('r', ea.SET))
|
|
985
|
+
.withFeature(exposes.numeric('g', ea.SET))
|
|
986
|
+
.withFeature(exposes.numeric('b', ea.SET))
|
|
987
|
+
.withDescription('Control status LED color when load ON'),
|
|
988
|
+
exposes.composite('led_color_off', 'led_color_off', ea.SET)
|
|
989
|
+
.withFeature(exposes.numeric('r', ea.SET))
|
|
990
|
+
.withFeature(exposes.numeric('g', ea.SET))
|
|
991
|
+
.withFeature(exposes.numeric('b', ea.SET))
|
|
992
|
+
.withDescription('Control status LED color when load OFF')],
|
|
993
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
994
|
+
const endpoint = device.getEndpoint(1);
|
|
995
|
+
const binds = ['genOnOff'];
|
|
996
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
997
|
+
await reporting.onOff(endpoint);
|
|
998
|
+
},
|
|
999
|
+
},
|
|
1000
|
+
{
|
|
1001
|
+
zigbeeModel: ['DM2500ZB'],
|
|
1002
|
+
model: 'DM2500ZB',
|
|
1003
|
+
vendor: 'Sinopé',
|
|
1004
|
+
description: 'Zigbee smart dimmer',
|
|
1005
|
+
fromZigbee: [fz.on_off, fz.brightness, fz.electrical_measurement, fzLocal.sinope],
|
|
1006
|
+
toZigbee: [tz.light_onoff_brightness, tzLocal.timer_seconds, tzLocal.led_intensity_on, tzLocal.led_intensity_off,
|
|
1007
|
+
tzLocal.minimum_brightness, tzLocal.led_color_on, tzLocal.led_color_off],
|
|
1008
|
+
exposes: [e.light_brightness(),
|
|
1009
|
+
exposes.numeric('timer_seconds', ea.ALL).withValueMin(0).withValueMax(10800)
|
|
1010
|
+
.withDescription('Automatically turn off load after x seconds'),
|
|
1011
|
+
exposes.numeric('led_intensity_on', ea.ALL).withValueMin(0).withValueMax(100)
|
|
1012
|
+
.withDescription('Control status LED when load ON'),
|
|
1013
|
+
exposes.numeric('led_intensity_off', ea.ALL).withValueMin(0).withValueMax(100)
|
|
1014
|
+
.withDescription('Control status LED when load OFF'),
|
|
1015
|
+
exposes.numeric('minimum_brightness', ea.ALL).withValueMin(0).withValueMax(3000)
|
|
1016
|
+
.withDescription('Control minimum dimmer brightness'),
|
|
1017
|
+
exposes.composite('led_color_on', 'led_color_on', ea.SET)
|
|
1018
|
+
.withFeature(exposes.numeric('r', ea.SET))
|
|
1019
|
+
.withFeature(exposes.numeric('g', ea.SET))
|
|
1020
|
+
.withFeature(exposes.numeric('b', ea.SET))
|
|
1021
|
+
.withDescription('Control status LED color when load ON'),
|
|
1022
|
+
exposes.composite('led_color_off', 'led_color_off', ea.SET)
|
|
1023
|
+
.withFeature(exposes.numeric('r', ea.SET))
|
|
1024
|
+
.withFeature(exposes.numeric('g', ea.SET))
|
|
1025
|
+
.withFeature(exposes.numeric('b', ea.SET))
|
|
1026
|
+
.withDescription('Control status LED color when load OFF')],
|
|
1027
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1028
|
+
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
1029
|
+
const endpoint = device.getEndpoint(1);
|
|
1030
|
+
const binds = ['genBasic', 'genLevelCtrl'];
|
|
1031
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1032
|
+
await reporting.onOff(endpoint);
|
|
1033
|
+
await reporting.brightness(endpoint);
|
|
1034
|
+
},
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
zigbeeModel: ['DM2550ZB'],
|
|
1038
|
+
model: 'DM2550ZB',
|
|
1039
|
+
vendor: 'Sinopé',
|
|
1040
|
+
description: 'Zigbee Adaptive phase smart dimmer',
|
|
1041
|
+
fromZigbee: [fz.on_off, fz.brightness, fz.electrical_measurement, fzLocal.sinope],
|
|
1042
|
+
toZigbee: [tz.light_onoff_brightness, tzLocal.timer_seconds, tzLocal.led_intensity_on, tzLocal.led_intensity_off,
|
|
1043
|
+
tzLocal.minimum_brightness, tzLocal.led_color_on, tzLocal.led_color_off],
|
|
1044
|
+
exposes: [e.light_brightness(),
|
|
1045
|
+
exposes.numeric('timer_seconds', ea.ALL).withValueMin(0).withValueMax(10800)
|
|
1046
|
+
.withDescription('Automatically turn off load after x seconds'),
|
|
1047
|
+
exposes.numeric('led_intensity_on', ea.ALL).withValueMin(0).withValueMax(100)
|
|
1048
|
+
.withDescription('Control status LED when load ON'),
|
|
1049
|
+
exposes.numeric('led_intensity_off', ea.ALL).withValueMin(0).withValueMax(100)
|
|
1050
|
+
.withDescription('Control status LED when load OFF'),
|
|
1051
|
+
exposes.numeric('minimum_brightness', ea.ALL).withValueMin(0).withValueMax(3000)
|
|
1052
|
+
.withDescription('Control minimum dimmer brightness'),
|
|
1053
|
+
exposes.composite('led_color_on', 'led_color_on', ea.SET)
|
|
1054
|
+
.withFeature(exposes.numeric('r', ea.SET))
|
|
1055
|
+
.withFeature(exposes.numeric('g', ea.SET))
|
|
1056
|
+
.withFeature(exposes.numeric('b', ea.SET))
|
|
1057
|
+
.withDescription('Control status LED color when load ON'),
|
|
1058
|
+
exposes.composite('led_color_off', 'led_color_off', ea.SET)
|
|
1059
|
+
.withFeature(exposes.numeric('r', ea.SET))
|
|
1060
|
+
.withFeature(exposes.numeric('g', ea.SET))
|
|
1061
|
+
.withFeature(exposes.numeric('b', ea.SET))
|
|
1062
|
+
.withDescription('Control status LED color when load OFF')],
|
|
1063
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1064
|
+
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
1065
|
+
const endpoint = device.getEndpoint(1);
|
|
1066
|
+
const binds = ['genBasic', 'genLevelCtrl'];
|
|
1067
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1068
|
+
await reporting.onOff(endpoint);
|
|
1069
|
+
await reporting.brightness(endpoint);
|
|
1070
|
+
},
|
|
1071
|
+
},
|
|
1072
|
+
{
|
|
1073
|
+
zigbeeModel: ['SP2600ZB'],
|
|
1074
|
+
model: 'SP2600ZB',
|
|
1075
|
+
vendor: 'Sinopé',
|
|
1076
|
+
description: 'Zigbee smart plug',
|
|
1077
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
|
|
1078
|
+
toZigbee: [tz.on_off, tz.frequency],
|
|
1079
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy()],
|
|
1080
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1081
|
+
const endpoint = device.getEndpoint(1);
|
|
1082
|
+
const binds = ['genBasic', 'genIdentify', 'genOnOff', 'haElectricalMeasurement', 'seMetering'];
|
|
1083
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1084
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
1085
|
+
await reporting.onOff(endpoint);
|
|
1086
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 10 : 0.1W
|
|
1087
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 10}); // divider 100: 0.1Arms
|
|
1088
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 10}); // divider 100: 0.1Vrms
|
|
1089
|
+
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 1000, multiplier: 1});
|
|
1090
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [0, 1]}); // divider 1
|
|
1091
|
+
},
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
zigbeeModel: ['SP2610ZB'],
|
|
1095
|
+
model: 'SP2610ZB',
|
|
1096
|
+
vendor: 'Sinopé',
|
|
1097
|
+
description: 'Zigbee smart plug',
|
|
1098
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
|
|
1099
|
+
toZigbee: [tz.on_off, tz.frequency],
|
|
1100
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy()],
|
|
1101
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1102
|
+
const endpoint = device.getEndpoint(1);
|
|
1103
|
+
const binds = ['genBasic', 'genIdentify', 'genOnOff', 'haElectricalMeasurement', 'seMetering'];
|
|
1104
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1105
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
1106
|
+
await reporting.onOff(endpoint);
|
|
1107
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 10 : 0.1W
|
|
1108
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 10}); // divider 100: 0.1Arms
|
|
1109
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 10}); // divider 100: 0.1Vrms
|
|
1110
|
+
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 1000, multiplier: 1});
|
|
1111
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [0, 1]}); // divider 1
|
|
1112
|
+
},
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
zigbeeModel: ['RM3250ZB'],
|
|
1116
|
+
model: 'RM3250ZB',
|
|
1117
|
+
vendor: 'Sinopé',
|
|
1118
|
+
description: '50A Smart electrical load controller',
|
|
1119
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
|
|
1120
|
+
toZigbee: [tz.on_off],
|
|
1121
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy()],
|
|
1122
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1123
|
+
const endpoint = device.getEndpoint(1);
|
|
1124
|
+
const binds = ['genOnOff', 'haElectricalMeasurement', 'seMetering'];
|
|
1125
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1126
|
+
await reporting.onOff(endpoint);
|
|
1127
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
1128
|
+
await reporting.activePower(endpoint);
|
|
1129
|
+
await reporting.rmsCurrent(endpoint);
|
|
1130
|
+
await reporting.rmsVoltage(endpoint);
|
|
1131
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
1132
|
+
await reporting.currentSummDelivered(endpoint);
|
|
1133
|
+
},
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
zigbeeModel: ['WL4200'],
|
|
1137
|
+
model: 'WL4200',
|
|
1138
|
+
vendor: 'Sinopé',
|
|
1139
|
+
description: 'Zigbee smart water leak detector',
|
|
1140
|
+
fromZigbee: [fz.ias_water_leak_alarm_1, fz.temperature, fz.battery],
|
|
1141
|
+
exposes: [e.water_leak(), e.battery_low(), e.temperature(), e.battery()],
|
|
1142
|
+
toZigbee: [],
|
|
1143
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1144
|
+
const endpoint = device.getEndpoint(1);
|
|
1145
|
+
const binds = ['genPowerCfg', 'msTemperatureMeasurement'];
|
|
1146
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1147
|
+
await reporting.temperature(endpoint, {min: 600, max: constants.repInterval.MAX, change: 100});
|
|
1148
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
1149
|
+
await reporting.batteryAlarmState(endpoint);
|
|
1150
|
+
},
|
|
1151
|
+
},
|
|
1152
|
+
{
|
|
1153
|
+
zigbeeModel: ['WL4200S'],
|
|
1154
|
+
model: 'WL4200S',
|
|
1155
|
+
vendor: 'Sinopé',
|
|
1156
|
+
description: 'Zigbee smart water leak detector with external sensor',
|
|
1157
|
+
fromZigbee: [fz.ias_water_leak_alarm_1, fz.temperature, fz.battery],
|
|
1158
|
+
toZigbee: [],
|
|
1159
|
+
exposes: [e.water_leak(), e.battery_low(), e.temperature(), e.battery()],
|
|
1160
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1161
|
+
const endpoint = device.getEndpoint(1);
|
|
1162
|
+
const binds = ['genPowerCfg', 'msTemperatureMeasurement'];
|
|
1163
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1164
|
+
await reporting.temperature(endpoint, {min: 600, max: constants.repInterval.MAX, change: 100});
|
|
1165
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
1166
|
+
await reporting.batteryAlarmState(endpoint);
|
|
1167
|
+
},
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
zigbeeModel: ['VA4200WZ'],
|
|
1171
|
+
model: 'VA4200WZ',
|
|
1172
|
+
vendor: 'Sinopé',
|
|
1173
|
+
description: 'Zigbee smart water valve (3/4")',
|
|
1174
|
+
fromZigbee: [fz.cover_position_via_brightness, fz.cover_state_via_onoff, fz.battery],
|
|
1175
|
+
toZigbee: [tz.cover_via_brightness],
|
|
1176
|
+
exposes: [e.valve_switch(), e.valve_position(), e.battery_low(), e.battery()],
|
|
1177
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1178
|
+
const endpoint = device.getEndpoint(1);
|
|
1179
|
+
const binds = ['genOnOff', 'genLevelCtrl', 'genPowerCfg'];
|
|
1180
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1181
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
1182
|
+
await reporting.onOff(endpoint);
|
|
1183
|
+
await reporting.brightness(endpoint); // valve position
|
|
1184
|
+
},
|
|
1185
|
+
},
|
|
1186
|
+
{
|
|
1187
|
+
zigbeeModel: ['VA4201WZ'],
|
|
1188
|
+
model: 'VA4201WZ',
|
|
1189
|
+
vendor: 'Sinopé',
|
|
1190
|
+
description: 'Zigbee smart water valve (1")',
|
|
1191
|
+
fromZigbee: [fz.cover_position_via_brightness, fz.cover_state_via_onoff, fz.battery],
|
|
1192
|
+
toZigbee: [tz.cover_via_brightness],
|
|
1193
|
+
exposes: [e.valve_switch(), e.valve_position(), e.battery_low(), e.battery()],
|
|
1194
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1195
|
+
const endpoint = device.getEndpoint(1);
|
|
1196
|
+
const binds = ['genOnOff', 'genLevelCtrl', 'genPowerCfg'];
|
|
1197
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1198
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
1199
|
+
await reporting.onOff(endpoint);
|
|
1200
|
+
await reporting.brightness(endpoint); // valve position
|
|
1201
|
+
},
|
|
1202
|
+
},
|
|
1203
|
+
{
|
|
1204
|
+
zigbeeModel: ['VA4220ZB'],
|
|
1205
|
+
model: 'VA4220ZB',
|
|
1206
|
+
vendor: 'Sinopé',
|
|
1207
|
+
description: 'Sedna smart water valve',
|
|
1208
|
+
fromZigbee: [fz.ignore_iaszone_statuschange, fz.cover_position_via_brightness, fz.cover_state_via_onoff,
|
|
1209
|
+
fz.battery, fz.metering],
|
|
1210
|
+
toZigbee: [tz.cover_via_brightness],
|
|
1211
|
+
meta: {battery: {voltageToPercentage: {min: 5400, max: 6800}}},
|
|
1212
|
+
exposes: [e.valve_switch(), e.valve_position(), e.battery_low(), e.battery(), e.battery_voltage()],
|
|
1213
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1214
|
+
const endpoint = device.getEndpoint(1);
|
|
1215
|
+
const binds = [
|
|
1216
|
+
'genBasic', 'genGroups', 'genOnOff', 'ssIasZone', 'genLevelCtrl',
|
|
1217
|
+
'genPowerCfg', 'seMetering', 'manuSpecificSinope'];
|
|
1218
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1219
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
1220
|
+
await reporting.onOff(endpoint);
|
|
1221
|
+
await reporting.brightness(endpoint); // valve position
|
|
1222
|
+
try {
|
|
1223
|
+
await reporting.batteryVoltage(endpoint);
|
|
1224
|
+
} catch (error) {/* Do Nothing */}
|
|
1225
|
+
try {
|
|
1226
|
+
await reporting.batteryAlarmState(endpoint);
|
|
1227
|
+
} catch (error) {/* Do Nothing */}
|
|
1228
|
+
},
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
zigbeeModel: ['RM3500ZB'],
|
|
1232
|
+
model: 'RM3500ZB',
|
|
1233
|
+
vendor: 'Sinopé',
|
|
1234
|
+
description: 'Calypso smart water heater controller',
|
|
1235
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fzLocal.ias_water_leak_alarm,
|
|
1236
|
+
fzLocal.sinope, fz.temperature],
|
|
1237
|
+
toZigbee: [tz.on_off],
|
|
1238
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy(), e.water_leak(), e.temperature()],
|
|
1239
|
+
configure: async (device, coordinatorEndpoint) => {
|
|
1240
|
+
const endpoint = device.getEndpoint(1);
|
|
1241
|
+
const binds = ['genOnOff', 'haElectricalMeasurement', 'seMetering', 'msTemperatureMeasurement', 'ssIasZone',
|
|
1242
|
+
'manuSpecificSinope'];
|
|
1243
|
+
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1244
|
+
await reporting.onOff(endpoint);
|
|
1245
|
+
await reporting.temperature(endpoint, {min: 10, max: 301, change: 10}); // divider 100: 0.1C
|
|
1246
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
1247
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 2}); // divider 1 : 2W
|
|
1248
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 10}); // divider 1000: 0.01Arms
|
|
1249
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 1}); // divider 1: 1Vrms
|
|
1250
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
1251
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [10, 10]}); // divider 1000: 0,01kWh
|
|
1252
|
+
|
|
1253
|
+
await endpoint.configureReporting('ssIasZone', [{attribute: 'zoneStatus', minimumReportInterval: 1,
|
|
1254
|
+
maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1}]);
|
|
1255
|
+
},
|
|
1256
|
+
},
|
|
1257
|
+
];
|