Skip to content

Instantly share code, notes, and snippets.

@serrj-sv
Forked from basveeling/moes_radiator_alt.js
Last active January 17, 2024 19:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save serrj-sv/af142b25de2d7ac54c3a2eb2623d9a6d to your computer and use it in GitHub Desktop.
Save serrj-sv/af142b25de2d7ac54c3a2eb2623d9a6d to your computer and use it in GitHub Desktop.
MoesHouse Tuya SH4 radiator valve eTRV thermostat zigbee2mqtt external converter
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const { duration } = require('moment');
const localValueConverter = {
divideBy2: tuya.valueConverterBasic.divideBy(2),
thermostatHolidayStartStop_SH4: {
from: (v) => {
start_year = v[0]+2000;
start_month = v[1] < 10 ? '0'+v[1] : v[1];
start_day = v[2] < 10 ? '0'+v[2] : v[2];
start_hour = v[3] < 10 ? '0'+v[3] : v[3];
start_minute = v[4] < 10 ? '0'+v[4] : v[4];
temperature = (v[5] /2).toFixed(1);
away_hours = v[6]<< 8 | v[7];
return `${start_day}/${start_month}/${start_year} ${start_hour}:${start_minute} ${away_hours} ${temperature}`;
},
to: (v) => {
const output = [];
holiday_schedule = v.split(' ');
[start_day, start_month, start_year] = holiday_schedule[0].split('/');
[start_hour, start_minute] = holiday_schedule[1].split(':')
away_hours = holiday_schedule[2];
temperature = holiday_schedule[3];
output[0]=start_year > 2000 ? start_year-2000 : start_year;
output[1]=start_month;
output[2]=start_day;
output[3]=start_hour;
output[4]=start_minute;
output[5]=Math.round(temperature * 2);
output[7]=away_hours & 0xFF;
output[6]=away_hours >> 8;
return output;
},
},
}
const definition = {
fingerprint: tuya.fingerprint('TS0601', [
'_TZE200_fhn3negr', /* model: 'SH4-ZB', vendor: 'Moes' */
]),
model: 'SH4-ZB',
vendor: 'TuYa',
description: 'Thermostat radiator valve',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints],
// ota: ota.zigbeeOTA,
onEvent: tuya.onEventSetLocalTime,
configure: tuya.configureMagicPacket,
exposes: [
e.battery(), e.child_lock(), e.open_window(),
e.open_window_temperature().withValueMin(5).withValueMax(30),
e.comfort_temperature().withValueMin(5).withValueMax(30),
e.eco_temperature().withValueMin(5).withValueMax(30),
e.numeric('auto_setpoint_override', ea.STATE_SET)
.withUnit('°C').withValueMax(30)
.withValueMin(0.5)
.withValueStep(0.5)
.withDescription('Setpoint override in auto mode'),
e.climate()
.withPreset(['auto', 'manual', 'holiday'])
.withLocalTemperatureCalibration(-5, 5, 0.1, ea.STATE_SET)
.withLocalTemperature(ea.STATE)
.withSetpoint('current_heating_setpoint', 0, 30, 0.5, ea.STATE_SET),
// .withSystemMode(['off', 'heat'], ea.STATE_SET, 'Only for Homeassistant'),
e.binary('online', ea.STATE_SET, 'ON', 'OFF')
.withDescription('The current data request from the device.'),
e.binary('boost_heating', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Boost Heating: the device will enter the boost heating mode.'),
e.numeric('boost_timeset_countdown', ea.STATE_SET).withUnit('s').withDescription('Setting ' +
'minimum 0 - maximum 900 seconds boost time. The boost (♨) function is activated. The remaining ' +
'time for the function will be counted down in seconds ( 900 to 0 ).').withValueMin(0).withValueMax(900),
e.numeric('window_detection', ea.STATE_SET).withUnit('m').withDescription('Open Window timer').withValueMin(0).withValueMax(60),
e.text('holiday_start_stop', ea.STATE_SET).withDescription('The holiday mode will automatically start ' +
'at the set time starting point and run the holiday temperature. Can be defined in the following format: ' +
'`DD/MM/YYYY HH:MM HHHH TT.T`. ' +
'For example: `01/10/2022 16:30 0240 18` (240 hours = 10 days). After the end of holiday mode, it switches to "auto" ' +
'mode and uses schedule.'),
tuya.exposes.errorStatus()
],
meta: {
tuyaDatapoints: [
// GitHib issue: https://github.com/Koenkk/zigbee-herdsman-converters/issues/1803
// sniffing eTRV -> Gateway: https://gist.github.com/serrj-sv/964d390139534754b6ea22f628b33c61
// sniffing Gateway -> eRTV: https://gist.github.com/serrj-sv/e6680647c438221b190a2b4d96805cc4
// legacy exteranl converter: https://gist.github.com/serrj-sv/af142b25de2d7ac54c3a2eb2623d9a6d
[2, 'preset', tuya.valueConverterBasic.lookup({'auto': tuya.enum(0), 'manual': tuya.enum(1), 'holiday': tuya.enum(2)})],
[16, 'current_heating_setpoint', localValueConverter.divideBy2],
[24, 'local_temperature', tuya.valueConverter.divideBy10],
[30, 'child_lock', tuya.valueConverter.lockUnlock],
[34, 'battery', tuya.valueConverterBasic.scale(0, 100, 50, 150)],
[45, 'error_status', tuya.valueConverter.raw],
[101, 'comfort_temperature', localValueConverter.divideBy2],
[102, 'eco_temperature', localValueConverter.divideBy2],
[103, 'holiday_start_stop', localValueConverter.thermostatHolidayStartStop_SH4], // sh4VacationPeriod
[104, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
[106, 'boost_heating', tuya.valueConverter.onOff],
[105, 'auto_setpoint_override', localValueConverter.divideBy2],
[107, 'open_window', tuya.valueConverter.onOff],
[108, null, null], // sh4Hibernate (don't know what it does)
[109, null, null], // sh4ScheduleMon - WIP
[110, null, null], // sh4ScheduleTue - WIP
[111, null, null], // sh4ScheduleWed - WIP
[112, null, null], // sh4ScheduleThu - WIP
[113, null, null], // sh4ScheduleFri - WIP
[114, null, null], // sh4ScheduleSat - WIP
[115, null, null], // sh4ScheduleSun - WIP
[116, 'open_window_temperature', localValueConverter.divideBy2],
[117, 'window_detection', tuya.valueConverter.raw], // sh4OpenWindowTime
[118, 'boost_timeset_countdown', tuya.valueConverter.raw],
[119, null, null], // sh4TempControl (don't know what it does)
[120, 'online', tuya.valueConverter.onOffNotStrict],
],
},
};
module.exports = definition;
@ohrensessel
Copy link

hi, thank you for your work. with your version of the external converter, I get the following error message "Exception while calling fromZigbee converter: Cannot read property 'datatype' of undefined}". I am on the dev branch of zigbee2mqtt (1.22.2-dev commit: 16842a3e). Any idea how I could solve this?

@serrj-sv
Copy link
Author

@ohrensessel try updated version

@chrischn82
Copy link

hi there!
i have an

modelZigbee: TS0601
manuf id: 4098
manufacturer: _TZE200_fhn3negr

bought from amazon. But with tuya_sh4_etrv.js as external converter in iobroker, it still doesnt work properly.
Device was successfully added, but the objects stay blank / null.

Before that i tried to fingerprint some "thermostat" in the tuya.js, but also with no succes.
Did i do something wrong?

@serrj-sv
Copy link
Author

serrj-sv commented Jan 28, 2022

Hi @chrischn82! I'm not familiar with iobroker... This converter was made for zigbee2mqtt. And I use it with Home Assistant.
In zigbee2mqtt this converter gives me full control over the thermostat

image

@serrj-sv
Copy link
Author

serrj-sv commented Feb 4, 2022

  • fixed date/time sync
  • updated to fix some issues related to latest release of zigbee2mqtt (1.23.0)

@IerwinDE
Copy link

I had great success with this converter and a device with manufacturer code _TZE200_i48qyn9s in zigbee2mqtt.
But as someone stated above my final goal is also to get the device to work in ioBroker.
the ioBroker zigbee adapter uses the zigbee-herdsman-converters libraries but I couldn't figure out how to add external converters to it.

I was wondering: Why hasnt this device been included in the zigbee-herdsman-converters devices yet?

@serrj-sv
Copy link
Author

serrj-sv commented Jun 6, 2023

@AlexShishko
Copy link

AlexShishko commented Jun 9, 2023

@serrj-sv. hi!
How about to PR it for out-of-the-box support?
As sad @Koenkk in Koenkk/zigbee2mqtt#17863 (comment)
I tried once a lot of time ago: Koenkk/zigbee-herdsman-converters#3447

@JbPasquier
Copy link

firstDpValue and getDataValue are now on legacy instead of tuya and aren't exposed. https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/lib/legacy.ts#L1024

As a workaround you can copy firstDpValue, dataTypes, convertMultiByteNumberPayloadToSingleDecimalNumber and getDataValue from the legacy file or for a clean update follow https://www.zigbee2mqtt.io/advanced/support-new-devices/02_support_new_tuya_devices.html

First solution is working fine with a _TZE200_zion52ef here. :-)

@lee-js
Copy link

lee-js commented Oct 1, 2023

firstDpValue and getDataValue are now on legacy instead of tuya and aren't exposed. https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/lib/legacy.ts#L1024

As a workaround you can copy firstDpValue, dataTypes, convertMultiByteNumberPayloadToSingleDecimalNumber and getDataValue from the legacy file or for a clean update follow https://www.zigbee2mqtt.io/advanced/support-new-devices/02_support_new_tuya_devices.html

First solution is working fine with a _TZE200_zion52ef here. :-)

Do you have a working .js file that works with the zion52ef? Can you share it with me? And tell me what to do with it!

@JbPasquier
Copy link

@b2un0
Copy link

b2un0 commented Oct 2, 2023

also here with usage of the legacy lib for getDataValue and firstDpValue
https://github.com/b2un0/z2m-device-converter

@serrj-sv
Copy link
Author

serrj-sv commented Oct 3, 2023

ah. winter is coming :)

@lee-js
Copy link

lee-js commented Oct 19, 2023

Sure, here you go: https://gist.github.com/JbPasquier/872c1be234188e959a053bc245401e76

Thank you for this, much appreciated.

@serrj-sv
Copy link
Author

Updated converter (no legacy stuff anymore). I will submit PR to upstream when I finish with weekly schedule part.

@b2un0
Copy link

b2un0 commented Dec 22, 2023

@serrj-svc can you take a look also to my changes here?
https://github.com/b2un0/z2m-device-converter/

(Fingerprints, whitelabel and linked issues).

@serrj-sv
Copy link
Author

@serrj-svc can you take a look also to my changes here? https://github.com/zigpy/zha-device-handlers

(Fingerprints, whitelabel and linked issues).

Hi! I'm not interested in ZHA at this moment, also I'm not good in python. I'm quite happy with my Z2M implementation )

@b2un0
Copy link

b2un0 commented Dec 22, 2023

uh, sorry, linked the wrong repo.
im also on Z2M.

I mean this one from me
https://github.com/b2un0/z2m-device-converter

and this converter (adopted from yours)

https://github.com/b2un0/z2m-device-converter/blob/main/converter/_TZE200_trv.js

@serrj-sv
Copy link
Author

and this converter

I rewrote my converter from scratch to not use legacy calls and it covers 95% of functionality. I used this model as prototype: https://github.com/Koenkk/zigbee-herdsman-converters/blob/9b1fda43a95381b3becf343c64a5a05a8f3e29db/src/devices/tuya.ts#L2846

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment