Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New device support]: Tuya TRV _TZE204_qyr2m29i #24958

Open
JK-SW opened this issue Nov 29, 2024 · 36 comments
Open

[New device support]: Tuya TRV _TZE204_qyr2m29i #24958

JK-SW opened this issue Nov 29, 2024 · 36 comments
Labels
new device support New device support request

Comments

@JK-SW
Copy link

JK-SW commented Nov 29, 2024

Link

https://www.aliexpress.com/item/1005006068601747.html

Database entry

{"id":41,"type":"EndDevice","ieeeAddr":"0xa4c1388b262e637a","nwkAddr":37682,"manufId":4417,"manufName":"_TZE204_qyr2m29i","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[0,4,5,61184],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"65487":14400,"65506":56,"65508":1,"65534":0,"modelId":"TS0601","appVersion":74,"manufacturerName":"_TZE204_qyr2m29i","powerSource":3,"zclVersion":3,"stackVersion":0,"hwVersion":1,"dateCode":""}}},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":74,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{"configured":332242049},"lastSeen":1732877903634}

Zigbee2MQTT version

1.41.0

Comments

I bought one TRV from the page, and it was _TZE204_rtrmfadk - working great. So I bought some more from the same seller, and all are _TZE204_qyr2m29i. They look absolutely same, but does NOT work with the same converter. The best I could find is this.

External definition

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE204_qyr2m29i',
        },
    ],
    model: 'TS0601',
    vendor: 'Tuya',
        description: 'Thermostatic radiator valve',
        fromZigbee: [tuya.fz.datapoints],
        toZigbee: [tuya.tz.datapoints],
        onEvent: tuya.onEventSetTime,
        configure: tuya.configureMagicPacket,
        exposes: [
            e.child_lock(),
            e.battery_low(),
            e
                .climate()
                .withSetpoint('current_heating_setpoint', 5, 35, 1, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withSystemMode(['auto', 'heat', 'off'], ea.STATE_SET)
                .withRunningState(['idle', 'heat'], ea.STATE)
                .withLocalTemperatureCalibration(-9, 9, 1, ea.STATE_SET),
            ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
            e
                .binary('scale_protection', ea.STATE_SET, 'ON', 'OFF')
                .withDescription(
                    'If the heat sink is not fully opened within ' +
                        'two weeks or is not used for a long time, the valve will be blocked due to silting up and the heat sink will not be ' +
                        'able to be used. To ensure normal use of the heat sink, the controller will automatically open the valve fully every ' +
                        'two weeks. It will run for 30 seconds per time with the screen displaying "Ad", then return to its normal working state ' +
                        'again.',
                ),
            e
                .binary('frost_protection', ea.STATE_SET, 'ON', 'OFF')
                .withDescription(
                    'When the room temperature is lower than 5 °C, the valve opens; when the temperature rises to 8 °C, the valve closes.',
                ),
            e.numeric('error', ea.STATE).withDescription('If NTC is damaged, "Er" will be on the TRV display.'),
        ],
        meta: {
            tuyaDatapoints: [
                [2, 'system_mode', tuya.valueConverterBasic.lookup({auto: tuya.enum(0), heat: tuya.enum(1), off: tuya.enum(2)})],
                [3, 'running_state', tuya.valueConverterBasic.lookup({heat: tuya.enum(0), idle: tuya.enum(1)})],
                [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                [5, 'local_temperature', tuya.valueConverter.divideBy10],
                [7, 'child_lock', tuya.valueConverter.lockUnlock],
                [28, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
                [29, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
                [30, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
                [31, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
                [32, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
                [33, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
                [34, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
                [35, null, tuya.valueConverter.errorOrBatteryLow],
                [36, 'frost_protection', tuya.valueConverter.onOff],
                [39, 'scale_protection', tuya.valueConverter.onOff],
                [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration2],
            ],
        },
    }

module.exports =  definition;

What does/doesn't work with the external definition?

Works:
Child lock state
Current heating setpoint (but only in 1C step, not 0.5C)
Local temperature

NOT WORK
System mode (does something, but completely wrong)
Running state (empty)
Local temperature calibration (works, but indicates step 1C, actually changes in step of 0.1C, and is limited to -0.9..0.9

Missing:
manual mode
Position
battery %
MAX/MIN temperature
Window detection
Preset
System mode
Mode (comfort/eco)

@JK-SW JK-SW added the new device support New device support request label Nov 29, 2024
@SP2FET
Copy link

SP2FET commented Dec 1, 2024

this is the converter that I'm using for that device - I fixed the current setpoint step to 0.5, got the mode displaying correctly (heat/off) and the temp calibration is also working

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE204_qyr2m29i',
        },
    ],
    model: 'TS0601',
    vendor: 'Tuya',
        description: 'Thermostatic radiator valve',
        fromZigbee: [tuya.fz.datapoints],
        toZigbee: [tuya.tz.datapoints],
        onEvent: tuya.onEventSetTime,
        configure: tuya.configureMagicPacket,
        exposes: [
            e.child_lock(),
            e.battery_low(),
            e
                .climate()
                .withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withSystemMode(['heat', 'off'], ea.STATE)
                .withLocalTemperatureCalibration(-9, 9, 0.1, ea.STATE_SET),
            ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
            e
                .binary('scale_protection', ea.STATE_SET, 'ON', 'OFF')
                .withDescription(
                    'If the heat sink is not fully opened within ' +
                        'two weeks or is not used for a long time, the valve will be blocked due to silting up and the heat sink will not be ' +
                        'able to be used. To ensure normal use of the heat sink, the controller will automatically open the valve fully every ' +
                        'two weeks. It will run for 30 seconds per time with the screen displaying "Ad", then return to its normal working state ' +
                        'again.',
                ),
            e
                .binary('frost_protection', ea.STATE_SET, 'ON', 'OFF')
                .withDescription(
                    'When the room temperature is lower than 5 °C, the valve opens; when the temperature rises to 8 °C, the valve closes.',
                ),
            e.numeric('error', ea.STATE).withDescription('If NTC is damaged, "Er" will be on the TRV display.'),
        ],
        meta: {
            tuyaDatapoints: [
                [3, 'system_mode', tuya.valueConverterBasic.lookup({heat: tuya.enum(1), off: tuya.enum(0)})],
                [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                [5, 'local_temperature', tuya.valueConverter.divideBy10],
                [7, 'child_lock', tuya.valueConverter.lockUnlock],
                [28, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
                [29, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
                [30, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
                [31, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
                [32, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
                [33, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
                [34, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
                [35, null, tuya.valueConverter.errorOrBatteryLow],
                [36, 'frost_protection', tuya.valueConverter.onOff],
                [39, 'scale_protection', tuya.valueConverter.onOff],
                [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
            ],
        },
    }

module.exports =  definition;

@JK-SW
Copy link
Author

JK-SW commented Dec 4, 2024

Thanks. Yes, that is better, but the mode is still not working for me (sometimes is does start heating sometimes not). And it is missing manual mode. And TRV position. But we are getting there.. :)

@talo77
Copy link

talo77 commented Dec 5, 2024

Hello. How does it look? Do you see hope that the device will be functional via Z2MQTT?

@redbull-80
Copy link

Thank you very much for your work. Unfortunately, my TRV is not yet supported, but your converter works partially.

My TRV: https://www.banggood.com/Tuya-Smart-Zigbee3_0-Thermostat-Radiator-Valve-Temperature-Schedule-Setting-Window-Open-Detection-Function-APP-Remote-Voice-Control-Work-with-Alexa-Google-Assistance-p-2020881.html?rmmds=myorder&cur_warehouse=CN

TS0601
TZE204_ogx8u5z6

@JK-SW
Copy link
Author

JK-SW commented Dec 6, 2024

I believe that it is only a matter of time, we need the datapoints. I spent about an hour trying, but with no improvement. My only finding is that probably the modes are not on cluster 3, but 1. It seems the TRV is different from the other tuya China TRVs.

@dzikus
Copy link

dzikus commented Dec 7, 2024

@BugSniper3000
Copy link

thanks for the work all. I have got to the same point as @JK-SW . Will let you know if I have any more luck!

@ArtiPe
Copy link

ArtiPe commented Dec 11, 2024

to jest konwerter, którego używam do tego urządzenia - ustawiłem aktualny krok nastawy na 0,5, uzyskałem prawidłowe wyświetlanie trybu (ogrzewanie/wyłączenie), a kalibracja temperatury również działa

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE204_qyr2m29i',
        },
    ],
    model: 'TS0601',
    vendor: 'Tuya',
        description: 'Thermostatic radiator valve',
        fromZigbee: [tuya.fz.datapoints],
        toZigbee: [tuya.tz.datapoints],
        onEvent: tuya.onEventSetTime,
        configure: tuya.configureMagicPacket,
        exposes: [
            e.child_lock(),
            e.battery_low(),
            e
                .climate()
                .withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withSystemMode(['heat', 'off'], ea.STATE)
                .withLocalTemperatureCalibration(-9, 9, 0.1, ea.STATE_SET),
            ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
            e
                .binary('scale_protection', ea.STATE_SET, 'ON', 'OFF')
                .withDescription(
                    'If the heat sink is not fully opened within ' +
                        'two weeks or is not used for a long time, the valve will be blocked due to silting up and the heat sink will not be ' +
                        'able to be used. To ensure normal use of the heat sink, the controller will automatically open the valve fully every ' +
                        'two weeks. It will run for 30 seconds per time with the screen displaying "Ad", then return to its normal working state ' +
                        'again.',
                ),
            e
                .binary('frost_protection', ea.STATE_SET, 'ON', 'OFF')
                .withDescription(
                    'When the room temperature is lower than 5 °C, the valve opens; when the temperature rises to 8 °C, the valve closes.',
                ),
            e.numeric('error', ea.STATE).withDescription('If NTC is damaged, "Er" will be on the TRV display.'),
        ],
        meta: {
            tuyaDatapoints: [
                [3, 'system_mode', tuya.valueConverterBasic.lookup({heat: tuya.enum(1), off: tuya.enum(0)})],
                [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                [5, 'local_temperature', tuya.valueConverter.divideBy10],
                [7, 'child_lock', tuya.valueConverter.lockUnlock],
                [28, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
                [29, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
                [30, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
                [31, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
                [32, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
                [33, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
                [34, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
                [35, null, tuya.valueConverter.errorOrBatteryLow],
                [36, 'frost_protection', tuya.valueConverter.onOff],
                [39, 'scale_protection', tuya.valueConverter.onOff],
                [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
            ],
        },
    }

module.exports =  definition;

where to insert??

@loodvin
Copy link

loodvin commented Dec 14, 2024

Hi, here is my config. the minimum I need. But I'm not sure about the battery.

  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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');                                                                                     
  const e = exposes.presets;                                                                                                                                       
  const ea = exposes.access;                                                                                                                                       
  const tuya = require('zigbee-herdsman-converters/lib/tuya');                                                                                                     
                                                                                                                                                                   
  const definition = {                                                                                                                                             
      // Since a lot of Tuya devices use the same modelID, but use different datapoints                                                                            
      // it's necessary to provide a fingerprint instead of a zigbeeModel                                                                                          
      fingerprint: [                                                                                                                                               
          {                                                                                                                                                        
              // The model ID from: Device with modelID 'TS0601' is not supported                                                                                  
              // You may need to add \u0000 at the end of the name in some cases                                                                                   
              modelID: 'TS0601',                                                                                                                                   
              // This can be different as they change it for different batches                                                                      
              manufacturerName: '_TZE204_qyr2m29i',                                                                                                                
          },                                                                                                                                                       
      ],                                                                                                                                                           
      model: 'TRV801Z',                                                                                                                                            
      vendor: 'Moes',                                                                                                                                              
      description: 'Moes old TRV/zigbee model',                                                                                                                    
      fromZigbee: [tuya.fz.datapoints],                                                                                                                            
      toZigbee: [tuya.tz.datapoints],                                                                                                                              
      onEvent: tuya.onEventSetLocalTime,                                                                                                                           
      configure: tuya.configureMagicPacket,                                                                                                                        
      exposes: [ 
              e.child_lock(),
              e.position(),
              e                                                                                                                                                    
                  .climate()                                                                                                                                       
                  .withLocalTemperature(ea.STATE)
                  .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET)
                  .withLocalTemperatureCalibration(-10, 10, 0.1, ea.STATE_SET)  
                  .withPreset(                                                                                                                                     
                      ['OFF', 'Anti-frost', 'Eco', 'Comfort', 'Auto', 'ON'],                                                                                                             
                  )
                  .withRunningState(['idle', 'heat'], ea.STATE)
                  .withSystemMode(['auto', 'heat', 'off'], ea.STATE),
              e.comfort_temperature().withValueMin(5).withValueMax(30),
              e.eco_temperature().withValueMin(5).withValueMax(30),
              e.holiday_temperature().withValueMin(5).withValueMax(30),    
              e.enum('display_brightness', ea.STATE_SET, ['high', 'medium', 'low']).withDescription('Display brightness'),
              e.enum('screen_orientation', ea.STATE_SET, ['up', 'down']).withDescription('Screen orientation'),
              e.battery(),
          ],
          meta: {
              tuyaDatapoints: [
                  [7, 'child_lock', tuya.valueConverter.lockUnlock],
                  [5, 'local_temperature', tuya.valueConverter.divideBy10],
                  [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                  [121, 'holiday_temperature', tuya.valueConverter.divideBy10],
                  [119, 'comfort_temperature', tuya.valueConverter.divideBy10],
                  [120, 'eco_temperature', tuya.valueConverter.divideBy10],
                  [114, 'position', tuya.valueConverter.divideBy10],
                  [111, 'display_brightness', tuya.valueConverterBasic.lookup({'high': tuya.enum(0), 'medium': tuya.enum(1), 'low': tuya.enum(2)})],
                  [6, 'battery', tuya.valueConverter.raw],
                  [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
                  [2, 'preset', tuya.valueConverterBasic.lookup({ 'OFF': tuya.enum(0), 'Anti-frost': tuya.enum(1), 'Eco': tuya.enum(2), 'Comfort': tuya.enum(3), 'Auto': tuya.enum(4), 'ON': tuya.enum(5)})],
                  [3, 'running_state', tuya.valueConverterBasic.lookup({heat: 1, idle: 0})],
                  [2, 'system_mode', tuya.valueConverter.thermostatSystemModeAndPreset('system_mode')],
                  [113, 'screen_orientation', tuya.valueConverterBasic.lookup({
                      'up': tuya.enum(0), 'down': tuya.enum(1),
                  })],
              ],
          },
  
      extend: [
          // A preferred new way of extending functionality.
      ],
  };
  
  module.exports = definition;

@Christophersonius
Copy link

Cześć, oto mój config. minimum, którego potrzebuję. Ale nie jestem pewien co do baterii.

  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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');                                                                                     
  const e = exposes.presets;                                                                                                                                       
  const ea = exposes.access;                                                                                                                                       
  const tuya = require('zigbee-herdsman-converters/lib/tuya');                                                                                                     
                                                                                                                                                                   
  const definition = {                                                                                                                                             
      // Since a lot of Tuya devices use the same modelID, but use different datapoints                                                                            
      // it's necessary to provide a fingerprint instead of a zigbeeModel                                                                                          
      fingerprint: [                                                                                                                                               
          {                                                                                                                                                        
              // The model ID from: Device with modelID 'TS0601' is not supported                                                                                  
              // You may need to add \u0000 at the end of the name in some cases                                                                                   
              modelID: 'TS0601',                                                                                                                                   
              // This can be different as they change it for different batches                                                                      
              manufacturerName: '_TZE204_qyr2m29i',                                                                                                                
          },                                                                                                                                                       
      ],                                                                                                                                                           
      model: 'TRV801Z',                                                                                                                                            
      vendor: 'Moes',                                                                                                                                              
      description: 'Moes old TRV/zigbee model',                                                                                                                    
      fromZigbee: [tuya.fz.datapoints],                                                                                                                            
      toZigbee: [tuya.tz.datapoints],                                                                                                                              
      onEvent: tuya.onEventSetLocalTime,                                                                                                                           
      configure: tuya.configureMagicPacket,                                                                                                                        
      exposes: [ 
              e.child_lock(),
              e.position(),
              e                                                                                                                                                    
                  .climate()                                                                                                                                       
                  .withLocalTemperature(ea.STATE)
                  .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET)
                  .withLocalTemperatureCalibration(-10, 10, 0.1, ea.STATE_SET)  
                  .withPreset(                                                                                                                                     
                      ['OFF', 'Anti-frost', 'Eco', 'Comfort', 'Auto', 'ON'],                                                                                                             
                  )
                  .withRunningState(['idle', 'heat'], ea.STATE)
                  .withSystemMode(['auto', 'heat', 'off'], ea.STATE),
              e.comfort_temperature().withValueMin(5).withValueMax(30),
              e.eco_temperature().withValueMin(5).withValueMax(30),
              e.holiday_temperature().withValueMin(5).withValueMax(30),    
              e.enum('display_brightness', ea.STATE_SET, ['high', 'medium', 'low']).withDescription('Display brightness'),
              e.enum('screen_orientation', ea.STATE_SET, ['up', 'down']).withDescription('Screen orientation'),
              e.battery(),
          ],
          meta: {
              tuyaDatapoints: [
                  [7, 'child_lock', tuya.valueConverter.lockUnlock],
                  [5, 'local_temperature', tuya.valueConverter.divideBy10],
                  [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                  [121, 'holiday_temperature', tuya.valueConverter.divideBy10],
                  [119, 'comfort_temperature', tuya.valueConverter.divideBy10],
                  [120, 'eco_temperature', tuya.valueConverter.divideBy10],
                  [114, 'position', tuya.valueConverter.divideBy10],
                  [111, 'display_brightness', tuya.valueConverterBasic.lookup({'high': tuya.enum(0), 'medium': tuya.enum(1), 'low': tuya.enum(2)})],
                  [6, 'battery', tuya.valueConverter.raw],
                  [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
                  [2, 'preset', tuya.valueConverterBasic.lookup({ 'OFF': tuya.enum(0), 'Anti-frost': tuya.enum(1), 'Eco': tuya.enum(2), 'Comfort': tuya.enum(3), 'Auto': tuya.enum(4), 'ON': tuya.enum(5)})],
                  [3, 'running_state', tuya.valueConverterBasic.lookup({heat: 1, idle: 0})],
                  [2, 'system_mode', tuya.valueConverter.thermostatSystemModeAndPreset('system_mode')],
                  [113, 'screen_orientation', tuya.valueConverterBasic.lookup({
                      'up': tuya.enum(0), 'down': tuya.enum(1),
                  })],
              ],
          },
  
      extend: [
          // A preferred new way of extending functionality.
      ],
  };
  
  module.exports = definition;

Can you tell me where to put this code, in what file and directory?

@loodvin
Copy link

loodvin commented Dec 19, 2024

Can you tell me where to put this code, in what file and directory?

In the configuration.yaml file add :

   external_converters:
      - moes_valve_ZTRV801.js

Create a file moes_valve_ZTRV801.js, put the code in it. This file should be placed in the same folder where the configuration.yaml file is.

@Christophersonius
Copy link

Can you tell me where to put this code, in what file and directory?

In the configuration.yaml file add :

   external_converters:
      - moes_valve_ZTRV801.js

Create a file moes_valve_ZTRV801.js, put the code in it. This file should be placed in the same folder where the configuration.yaml file is.

thanks, work! :)

@pimvanelsen
Copy link

pimvanelsen commented Dec 20, 2024

Hi all,

I contacted Moes and got the DPIDs and protocol for the "_TZE204_qyr2m29i" version. Hopes this will help you guys...not sure how to get percentage wise the battery report. i need that. so who can add/help
ZigBee Smart TRV_10_23.xlsx
pjyzigbee 801.pdf

@loodvin
Copy link

loodvin commented Dec 20, 2024

Hi all,

I contacted Moes and got the DPIDs and protocol for the "_TZE204_qyr2m29i" version. Hopes this will help you guys...not sure how to get percentage wise the battery report. i need that. so who can add/help ZigBee Smart TRV_10_23.xlsx pjyzigbee 801.pdf

Hi. Most likely the id in excel does not relate to TZE204_qyr2m29i.

@pimvanelsen
Copy link

pimvanelsen commented Dec 20, 2024

Hi all,
I contacted Moes and got the DPIDs and protocol for the "_TZE204_qyr2m29i" version. Hopes this will help you guys...not sure how to get percentage wise the battery report. i need that. so who can add/help ZigBee Smart TRV_10_23.xlsx pjyzigbee 801.pdf

Hi. Most likely the id in excel does not relate to TZE204_qyr2m29i.

Could be but i asked especially for this version with this in the manufacturer description "_TZE204_qyr2m29i". But if someone can add the function to read out the battery percentage, i can test it...

@pimvanelsen
Copy link

OK, bought a zigbee tuya gateway and followed steps to get DPIDS as described on Find Tuya Data Points

got this list out...so who can help with the external converter....i really like to have battery percentage out....on Tuya smart app when i operate the device you can see percentage....but how to get it out in HA (want to have a script that send me a message in HA)

2:"Mode"
3:"Working status"
4:"Target temperature"
5:"Current temperature"
6:"Battery"
7:"Child lock"
9:"Max. limit temperature"
10:"Min. limit temperature"
14:"Open window"
15:"Window status"
35:"Fault alarm"
47:"Room sensor calibration"
102:"Weekly program 1"
103:"Weekly program 2"
104:"Weekly program 3"
105:"Weekly program 4"
106:"Weekly program 5"
107:"Weekly program 6"
108:"Weekly program 7"
109:"Model"
110:"Motor thrust"
111:"Display brightness"
112:"App command timestamp"
113:"Screen orientation"
114:"Valve"
115:"Switch deviation (energy-saving mode only)"
116:"Motor data"
117:"Vacation duration"
118:"Boost mode duration"
119:"Comfort mode temperature"
120:"Energy saving mode temperature"
121:"Antifreeze mode temperature"
122:"Antifreeze enable"
123:"Air pressure index"
124:"Temperature mode start time"
125:"Function points"
126:"App support features"
127:"System mode"
 

@loodvin
Copy link

loodvin commented Dec 21, 2024

Hi, in my code the battery works and is displayed in %

@loodvin
Copy link

loodvin commented Dec 21, 2024

new code

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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');                                                                                     
const e = exposes.presets;                                                                                                                                       
const ea = exposes.access;                                                                                                                                       
const tuya = require('zigbee-herdsman-converters/lib/tuya');                                                                                                     
                                                                                                                                                                 
const definition = {                                                                                                                                             
    // Since a lot of Tuya devices use the same modelID, but use different datapoints                                                                            
    // it's necessary to provide a fingerprint instead of a zigbeeModel                                                                                          
    fingerprint: [                                                                                                                                               
        {                                                                                                                                                        
            // The model ID from: Device with modelID 'TS0601' is not supported                                                                                  
            // You may need to add \u0000 at the end of the name in some cases                                                                                   
            modelID: 'TS0601',                                                                                                                                   
            // This can be different as they change it for different batches                                                                      
            manufacturerName: '_TZE204_qyr2m29i',                                                                                                                
        },                                                                                                                                                       
    ],                                                                                                                                                           
    model: 'TRV801Z',                                                                                                                                            
    vendor: 'Moes',                                                                                                                                              
    description: 'Thermostatic radiator valve.',                                                                                                                    
    fromZigbee: [tuya.fz.datapoints],                                                                                                                            
    toZigbee: [tuya.tz.datapoints],                                                                                                                              
    onEvent: tuya.onEventSetLocalTime,                                                                                                                           
    configure: tuya.configureMagicPacket, 
    whiteLabel: [tuya.whitelabel('Moes', 'TRV801Z', 'Thermostatic radiator valve', ['_TZE204_qyr2m29i'])],
    exposes: [
            e.child_lock(),
            e.max_temperature(),
            e.min_temperature(),
            e.position(),
            e.window_detection(),
            e.binary('window', ea.STATE, 'OPEN', 'CLOSE').withDescription('Window status closed or open '),
            e                                                                                                                                                    
                  .climate()                                                                                                                                       
                  .withLocalTemperature(ea.STATE)
                  .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET)
                  .withLocalTemperatureCalibration(-10, 10, 0.1, ea.STATE_SET)  
                  .withPreset(                                                                                                                                     
                      ['OFF', 'Anti-frost', 'Eco', 'Comfort', 'Auto', 'ON'],                                                                                                             
                  )
                  .withRunningState(['idle', 'heat'], ea.STATE)
                  .withSystemMode(['auto', 'heat', 'off'], ea.STATE),
            ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
            e.comfort_temperature().withValueMin(5).withValueMax(30).withDescription('Comfort mode temperature'),
            e.eco_temperature().withValueMin(5).withValueMax(30).withDescription('Eco mode temperature'),
            e.holiday_temperature().withValueMin(5).withValueMax(30).withDescription('Antifreeze mode temperature'),
            e.enum('display_brightness', ea.STATE_SET, ['high', 'medium', 'low']).withDescription('Display brightness'),
            e.enum('screen_orientation', ea.STATE_SET, ['up', 'down']).withDescription('Screen orientation'),
			e
                .enum('hysteresis', ea.STATE_SET, ['comfort', 'eco'])
                .withDescription(
                    'Hysteresis - comfort > switches off/on exactly at reached ' +
                        'temperature with valve smooth from 0 to 100%, eco > 0.5 degrees above or below, valve either 0 or 100%',
                ),
            e.enum('motor_thrust', ea.STATE_SET, ['strong', 'middle', 'weak']),
			e.battery(),
        ],
        meta: {
            tuyaDatapoints: [
                [2, 'preset', tuya.valueConverterBasic.lookup({ 'OFF': tuya.enum(0), 'Anti-frost': tuya.enum(1), 'Eco': tuya.enum(2), 'Comfort': tuya.enum(3), 'Auto': tuya.enum(4), 'ON': tuya.enum(5)})],
		[2, 'system_mode', tuya.valueConverter.thermostatSystemModeAndPreset('system_mode')],
		[3, 'running_state', tuya.valueConverterBasic.lookup({heat: 1, idle: 0})],
                [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                [5, 'local_temperature', tuya.valueConverter.divideBy10],
                [6, 'battery', tuya.valueConverter.raw],
                [7, 'child_lock', tuya.valueConverter.lockUnlock],
                [9, 'max_temperature', tuya.valueConverter.divideBy10],
                [10, 'min_temperature', tuya.valueConverter.divideBy10],
                [14, 'window_detection', tuya.valueConverterBasic.lookup({ ON: true, OFF: false })],
                [15, 'window', tuya.valueConverterBasic.lookup({ CLOSE: tuya.enum(0), OPEN: tuya.enum(1)})],
                [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
                [102, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(1)],
                [103, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(2)],
                [104, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(3)],
                [105, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(4)],
                [106, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(5)],
                [107, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(6)],
                [108, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(7)],
                [110, 'motor_thrust', tuya.valueConverterBasic.lookup({strong: tuya.enum(0), middle: tuya.enum(1), weak: tuya.enum(2)})],
                [111, 'display_brightness', tuya.valueConverterBasic.lookup({'high': tuya.enum(0), 'medium': tuya.enum(1), 'low': tuya.enum(2)})],   
                [113, 'screen_orientation', tuya.valueConverterBasic.lookup({'up': tuya.enum(0), 'down': tuya.enum(1)})],
                [114, 'position', tuya.valueConverter.divideBy10],
                [119, 'comfort_temperature', tuya.valueConverter.divideBy10],
                [120, 'eco_temperature', tuya.valueConverter.divideBy10],
                [121, 'holiday_temperature', tuya.valueConverter.divideBy10],
		[127, 'hysteresis', tuya.valueConverterBasic.lookup({ comfort: tuya.enum(0), eco: tuya.enum(1)})],
            ],
        },


    extend: [
        // A preferred new way of extending functionality.
    ],
};

module.exports = definition;

image

@pimvanelsen
Copy link

hi Loodvin, weird, in mine it did not. Your converter gave indeed the most functions but when i used the TRV in Node Red and tried to read out state (which is in payload of the object) the value was incorrect...

Converter of SP2FET did that correct....

As i do not understand much how to fix that state i combine yours, the one from SP2FET (regarding climate configuration) and the tuya,js. I see you worked yours as well...will try that...mine is working for me (but yours looks better as i look at climate configuration/setup)

here was mine

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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
// Since a lot of Tuya devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// This can be different as they change it for different batches
manufacturerName: '_TZE204_qyr2m29i',
},
],
model: 'TRV801Z',
vendor: 'Moes',
description: 'Moes old TRV/zigbee model',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints],
onEvent: tuya.onEventSetLocalTime,
configure: tuya.configureMagicPacket,
exposes: [
e.battery(),
e.child_lock(),
e.max_temperature(),
e.min_temperature(),
e.position(),
e.window_detection(),
e.binary('window', ea.STATE, 'OPEN', 'CLOSE').withDescription('Window status closed or open '),
e.enum('mode', ea.STATE_SET, ['standby', 'antifrost', 'eco', 'comfort', 'auto', 'on']).withDescription('Mode'),
e
.climate()
.withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET)
.withLocalTemperature(ea.STATE)
.withSystemMode(['heat', 'off'], ea.STATE)
.withLocalTemperatureCalibration(-30, 30, 0.1, ea.STATE_SET),
...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
e.comfort_temperature().withValueMin(5).withValueMax(30).withDescription('Comfort mode temperature'),
e.eco_temperature().withValueMin(5).withValueMax(30).withDescription('Eco mode temperature'),
e.enum('display_brightness', ea.STATE_SET, ['high', 'medium', 'low']).withDescription('Display brightness'),
e.enum('screen_orientation', ea.STATE_SET, ['up', 'down']).withDescription('Screen orientation'),
e
.enum('system_mode', ea.STATE_SET, ['comfort', 'eco'])
.withDescription(
'Hysteresis - comfort > switches off/on exactly at reached ' +
'temperature with valve smooth from 0 to 100%, eco > 0.5 degrees above or below, valve either 0 or 100%',
),
e.enum('motor_thrust', ea.STATE_SET, ['strong', 'middle', 'weak']),
],
meta: {
tuyaDatapoints: [
[
2,
'mode',
tuya.valueConverterBasic.lookup({
standby: tuya.enum(0),
antifrost: tuya.enum(1),
eco: tuya.enum(2),
comfort: tuya.enum(3),
auto: tuya.enum(4),
on: tuya.enum(5),
}),
],
[3, 'working_status', tuya.valueConverterBasic.lookup({heat: tuya.enum(1), off: tuya.enum(0)})],
[4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
[5, 'local_temperature', tuya.valueConverter.divideBy10],
[6, 'battery', tuya.valueConverter.raw],
[
7,
'child_lock',
tuya.valueConverterBasic.lookup({
LOCK: true,
UNLOCK: false,
}),
],
[9, 'max_temperature', tuya.valueConverter.divideBy10],
[10, 'min_temperature', tuya.valueConverter.divideBy10],
[
14,
'window_detection',
tuya.valueConverterBasic.lookup({
ON: true,
OFF: false,
}),
],
[
15,
'window',
tuya.valueConverterBasic.lookup({
CLOSE: tuya.enum(0),
OPEN: tuya.enum(1),
}),
],
[47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
[102, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(1)],
[103, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(2)],
[104, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(3)],
[105, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(4)],
[106, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(5)],
[107, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(6)],
[108, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(7)],
[
110,
'motor_thrust',
tuya.valueConverterBasic.lookup({
strong: tuya.enum(0),
middle: tuya.enum(1),
weak: tuya.enum(2),
}),
],
[
111,
'display_brightness',
tuya.valueConverterBasic.lookup({
high: tuya.enum(0),
medium: tuya.enum(1),
low: tuya.enum(2),
}),
],
[
113,
'screen_orientation',
tuya.valueConverterBasic.lookup({
up: tuya.enum(0),
down: tuya.enum(2),
}),
],
[114, 'position', tuya.valueConverter.divideBy10],
[119, 'comfort_temperature', tuya.valueConverter.divideBy10],
[120, 'eco_temperature', tuya.valueConverter.divideBy10],
[
127,
'system_mode',
tuya.valueConverterBasic.lookup({
comfort: tuya.enum(0),
eco: tuya.enum(1),
}),
],
],
},

  extend: [
      // A preferred new way of extending functionality.
  ],

};

module.exports = definition;

@pimvanelsen
Copy link

weird upon saving my indent/spaces dissapeared

@pimvanelsen
Copy link

new code

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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');                                                                                     
const e = exposes.presets;                                                                                                                                       
const ea = exposes.access;                                                                                                                                       
const tuya = require('zigbee-herdsman-converters/lib/tuya');                                                                                                     
                                                                                                                                                                 
const definition = {                                                                                                                                             
    // Since a lot of Tuya devices use the same modelID, but use different datapoints                                                                            
    // it's necessary to provide a fingerprint instead of a zigbeeModel                                                                                          
    fingerprint: [                                                                                                                                               
        {                                                                                                                                                        
            // The model ID from: Device with modelID 'TS0601' is not supported                                                                                  
            // You may need to add \u0000 at the end of the name in some cases                                                                                   
            modelID: 'TS0601',                                                                                                                                   
            // This can be different as they change it for different batches                                                                      
            manufacturerName: '_TZE204_qyr2m29i',                                                                                                                
        },                                                                                                                                                       
    ],                                                                                                                                                           
    model: 'TRV801Z',                                                                                                                                            
    vendor: 'Moes',                                                                                                                                              
    description: 'Thermostatic radiator valve.',                                                                                                                    
    fromZigbee: [tuya.fz.datapoints],                                                                                                                            
    toZigbee: [tuya.tz.datapoints],                                                                                                                              
    onEvent: tuya.onEventSetLocalTime,                                                                                                                           
    configure: tuya.configureMagicPacket, 
    whiteLabel: [tuya.whitelabel('Moes', 'TRV801Z', 'Thermostatic radiator valve', ['_TZE204_qyr2m29i'])],
    exposes: [
            e.child_lock(),
            e.max_temperature(),
            e.min_temperature(),
            e.position(),
            e.window_detection(),
            e.binary('window', ea.STATE, 'OPEN', 'CLOSE').withDescription('Window status closed or open '),
            e                                                                                                                                                    
                  .climate()                                                                                                                                       
                  .withLocalTemperature(ea.STATE)
                  .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET)
                  .withLocalTemperatureCalibration(-10, 10, 0.1, ea.STATE_SET)  
                  .withPreset(                                                                                                                                     
                      ['OFF', 'Anti-frost', 'Eco', 'Comfort', 'Auto', 'ON'],                                                                                                             
                  )
                  .withRunningState(['idle', 'heat'], ea.STATE)
                  .withSystemMode(['auto', 'heat', 'off'], ea.STATE),
            ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
            e.comfort_temperature().withValueMin(5).withValueMax(30).withDescription('Comfort mode temperature'),
            e.eco_temperature().withValueMin(5).withValueMax(30).withDescription('Eco mode temperature'),
            e.holiday_temperature().withValueMin(5).withValueMax(30).withDescription('Antifreeze mode temperature'),
            e.enum('display_brightness', ea.STATE_SET, ['high', 'medium', 'low']).withDescription('Display brightness'),
            e.enum('screen_orientation', ea.STATE_SET, ['up', 'down']).withDescription('Screen orientation'),
			e
                .enum('hysteresis', ea.STATE_SET, ['comfort', 'eco'])
                .withDescription(
                    'Hysteresis - comfort > switches off/on exactly at reached ' +
                        'temperature with valve smooth from 0 to 100%, eco > 0.5 degrees above or below, valve either 0 or 100%',
                ),
            e.enum('motor_thrust', ea.STATE_SET, ['strong', 'middle', 'weak']),
			e.battery(),
        ],
        meta: {
            tuyaDatapoints: [
                [2, 'preset', tuya.valueConverterBasic.lookup({ 'OFF': tuya.enum(0), 'Anti-frost': tuya.enum(1), 'Eco': tuya.enum(2), 'Comfort': tuya.enum(3), 'Auto': tuya.enum(4), 'ON': tuya.enum(5)})],
		[2, 'system_mode', tuya.valueConverter.thermostatSystemModeAndPreset('system_mode')],
		[3, 'running_state', tuya.valueConverterBasic.lookup({heat: 1, idle: 0})],
                [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                [5, 'local_temperature', tuya.valueConverter.divideBy10],
                [6, 'battery', tuya.valueConverter.raw],
                [7, 'child_lock', tuya.valueConverter.lockUnlock],
                [9, 'max_temperature', tuya.valueConverter.divideBy10],
                [10, 'min_temperature', tuya.valueConverter.divideBy10],
                [14, 'window_detection', tuya.valueConverterBasic.lookup({ ON: true, OFF: false })],
                [15, 'window', tuya.valueConverterBasic.lookup({ CLOSE: tuya.enum(0), OPEN: tuya.enum(1)})],
                [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
                [102, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(1)],
                [103, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(2)],
                [104, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(3)],
                [105, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(4)],
                [106, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(5)],
                [107, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(6)],
                [108, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(7)],
                [110, 'motor_thrust', tuya.valueConverterBasic.lookup({strong: tuya.enum(0), middle: tuya.enum(1), weak: tuya.enum(2)})],
                [111, 'display_brightness', tuya.valueConverterBasic.lookup({'high': tuya.enum(0), 'medium': tuya.enum(1), 'low': tuya.enum(2)})],   
                [113, 'screen_orientation', tuya.valueConverterBasic.lookup({'up': tuya.enum(0), 'down': tuya.enum(1)})],
                [114, 'position', tuya.valueConverter.divideBy10],
                [119, 'comfort_temperature', tuya.valueConverter.divideBy10],
                [120, 'eco_temperature', tuya.valueConverter.divideBy10],
                [121, 'holiday_temperature', tuya.valueConverter.divideBy10],
		[127, 'hysteresis', tuya.valueConverterBasic.lookup({ comfort: tuya.enum(0), eco: tuya.enum(1)})],
            ],
        },


    extend: [
        // A preferred new way of extending functionality.
    ],
};

module.exports = definition;

image

WoW, this one is really fully working, many thanks

@loodvin
Copy link

loodvin commented Dec 22, 2024

After your post with the ID, I went to https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/devices/tuya.ts , and
I saw our device, I think it wasn't there before.
Of course, I tried it, but there were errors in operation and display.
I redid it and posted what I got.
It seems to work correctly. If the problem is with the battery display, then try removing the batteries and turning it on again, it helped me.

@pimvanelsen
Copy link

No, batteries are doing fine now, and the tuya.ts did not have the

e
.climate()
.withLocalTemperature(ea.STATE)
.withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET)
.withLocalTemperatureCalibration(-10, 10, 0.1, ea.STATE_SET)
.withPreset(
['OFF', 'Anti-frost', 'Eco', 'Comfort', 'Auto', 'ON'],
)
.withRunningState(['idle', 'heat'], ea.STATE)
.withSystemMode(['auto', 'heat', 'off'], ea.STATE),
...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),

This really did the trick, again thanks

@talo77
Copy link

talo77 commented Dec 22, 2024

Thank you for your work. It works perfectly for me

@pimvanelsen
Copy link

@loodvin one thing i noticed. in HA the climate card works beautiful,

image

but on a Tile card with entity state set to shown.....it shows "unknown -" while for my other thermostat (other brand) it does not
image

Do you know how to fix?

@loodvin
Copy link

loodvin commented Dec 22, 2024

@pimvanelsen have you tried that?
image

@loodvin
Copy link

loodvin commented Dec 22, 2024

image

@pimvanelsen
Copy link

Yes, that worked....Many, Many thx again

image

loodvin added a commit to loodvin/zigbee-herdsman-converters that referenced this issue Dec 23, 2024
@schugth
Copy link

schugth commented Dec 26, 2024

new code

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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');                                                                                     
const e = exposes.presets;                                                                                                                                       
const ea = exposes.access;                                                                                                                                       
const tuya = require('zigbee-herdsman-converters/lib/tuya');                                                                                                     
                                                                                                                                                                 
const definition = {                                                                                                                                             
    // Since a lot of Tuya devices use the same modelID, but use different datapoints                                                                            
    // it's necessary to provide a fingerprint instead of a zigbeeModel                                                                                          
    fingerprint: [                                                                                                                                               
        {                                                                                                                                                        
            // The model ID from: Device with modelID 'TS0601' is not supported                                                                                  
            // You may need to add \u0000 at the end of the name in some cases                                                                                   
            modelID: 'TS0601',                                                                                                                                   
            // This can be different as they change it for different batches                                                                      
            manufacturerName: '_TZE204_qyr2m29i',                                                                                                                
        },                                                                                                                                                       
    ],                                                                                                                                                           
    model: 'TRV801Z',                                                                                                                                            
    vendor: 'Moes',                                                                                                                                              
    description: 'Thermostatic radiator valve.',                                                                                                                    
    fromZigbee: [tuya.fz.datapoints],                                                                                                                            
    toZigbee: [tuya.tz.datapoints],                                                                                                                              
    onEvent: tuya.onEventSetLocalTime,                                                                                                                           
    configure: tuya.configureMagicPacket, 
    whiteLabel: [tuya.whitelabel('Moes', 'TRV801Z', 'Thermostatic radiator valve', ['_TZE204_qyr2m29i'])],
    exposes: [
            e.child_lock(),
            e.max_temperature(),
            e.min_temperature(),
            e.position(),
            e.window_detection(),
            e.binary('window', ea.STATE, 'OPEN', 'CLOSE').withDescription('Window status closed or open '),
            e                                                                                                                                                    
                  .climate()                                                                                                                                       
                  .withLocalTemperature(ea.STATE)
                  .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET)
                  .withLocalTemperatureCalibration(-10, 10, 0.1, ea.STATE_SET)  
                  .withPreset(                                                                                                                                     
                      ['OFF', 'Anti-frost', 'Eco', 'Comfort', 'Auto', 'ON'],                                                                                                             
                  )
                  .withRunningState(['idle', 'heat'], ea.STATE)
                  .withSystemMode(['auto', 'heat', 'off'], ea.STATE),
            ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
            e.comfort_temperature().withValueMin(5).withValueMax(30).withDescription('Comfort mode temperature'),
            e.eco_temperature().withValueMin(5).withValueMax(30).withDescription('Eco mode temperature'),
            e.holiday_temperature().withValueMin(5).withValueMax(30).withDescription('Antifreeze mode temperature'),
            e.enum('display_brightness', ea.STATE_SET, ['high', 'medium', 'low']).withDescription('Display brightness'),
            e.enum('screen_orientation', ea.STATE_SET, ['up', 'down']).withDescription('Screen orientation'),
			e
                .enum('hysteresis', ea.STATE_SET, ['comfort', 'eco'])
                .withDescription(
                    'Hysteresis - comfort > switches off/on exactly at reached ' +
                        'temperature with valve smooth from 0 to 100%, eco > 0.5 degrees above or below, valve either 0 or 100%',
                ),
            e.enum('motor_thrust', ea.STATE_SET, ['strong', 'middle', 'weak']),
			e.battery(),
        ],
        meta: {
            tuyaDatapoints: [
                [2, 'preset', tuya.valueConverterBasic.lookup({ 'OFF': tuya.enum(0), 'Anti-frost': tuya.enum(1), 'Eco': tuya.enum(2), 'Comfort': tuya.enum(3), 'Auto': tuya.enum(4), 'ON': tuya.enum(5)})],
		[2, 'system_mode', tuya.valueConverter.thermostatSystemModeAndPreset('system_mode')],
		[3, 'running_state', tuya.valueConverterBasic.lookup({heat: 1, idle: 0})],
                [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                [5, 'local_temperature', tuya.valueConverter.divideBy10],
                [6, 'battery', tuya.valueConverter.raw],
                [7, 'child_lock', tuya.valueConverter.lockUnlock],
                [9, 'max_temperature', tuya.valueConverter.divideBy10],
                [10, 'min_temperature', tuya.valueConverter.divideBy10],
                [14, 'window_detection', tuya.valueConverterBasic.lookup({ ON: true, OFF: false })],
                [15, 'window', tuya.valueConverterBasic.lookup({ CLOSE: tuya.enum(0), OPEN: tuya.enum(1)})],
                [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1],
                [102, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(1)],
                [103, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(2)],
                [104, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(3)],
                [105, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(4)],
                [106, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(5)],
                [107, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(6)],
                [108, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDP_TRV602Z_WithDayNumber(7)],
                [110, 'motor_thrust', tuya.valueConverterBasic.lookup({strong: tuya.enum(0), middle: tuya.enum(1), weak: tuya.enum(2)})],
                [111, 'display_brightness', tuya.valueConverterBasic.lookup({'high': tuya.enum(0), 'medium': tuya.enum(1), 'low': tuya.enum(2)})],   
                [113, 'screen_orientation', tuya.valueConverterBasic.lookup({'up': tuya.enum(0), 'down': tuya.enum(1)})],
                [114, 'position', tuya.valueConverter.divideBy10],
                [119, 'comfort_temperature', tuya.valueConverter.divideBy10],
                [120, 'eco_temperature', tuya.valueConverter.divideBy10],
                [121, 'holiday_temperature', tuya.valueConverter.divideBy10],
		[127, 'hysteresis', tuya.valueConverterBasic.lookup({ comfort: tuya.enum(0), eco: tuya.enum(1)})],
            ],
        },


    extend: [
        // A preferred new way of extending functionality.
    ],
};

module.exports = definition;

image

WoW, this one is really fully working, many thanks

@loodvin, @pimvanelsen, thank you for your excellent work.
The Moes TRV works great with your converter code.
I use HA and the only problem I have in my setup: the time schedule does not work. Neither in system mode 'auto' nor in preset mode 'auto'.
In 'heat' mode I can program automations.
Do you have an idea to solve the schedule problem?
Thanks

@loodvin
Copy link

loodvin commented Dec 27, 2024

@loodvin, @pimvanelsen, thank you for your excellent work. The Moes TRV works great with your converter code. I use HA and the only problem I have in my setup: the time schedule does not work. Neither in system mode 'auto' nor in preset mode 'auto'. In 'heat' mode I can program automations. Do you have an idea to solve the schedule problem? Thanks

Hi. I don't need this function. I haven't tested it or used it. I copied the code from what was already written before me. I'll try to come up with something.

@JK-SW
Copy link
Author

JK-SW commented Dec 28, 2024

Thanks guys, you are awesome. The last code works perfect for me (I dont use itegrated scheduler though). It is even more feature rich than my previous, same looking, already supported TRV. Thanks again!

@dietmarczekay
Copy link

I use OH and facing the same problem, the schedules for days did not work in any preset mode.

@loodvin
Copy link

loodvin commented Dec 28, 2024

I tried everything related to the schedule, but nothing worked. I'll try again after the new year, but I don't have the device in my hands right now.

@schugth
Copy link

schugth commented Dec 29, 2024 via email

@dietmarczekay
Copy link

I use the z2m web gui and switching to "Auto" sets the current heating setpoint temperature to the "Eco" preset temperature

@dietmarczekay
Copy link

I updated today to v2.0.0 the valves are detected in a correct way. setting the mode to auto, the device sets the temperature set point to holiday temperature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new device support New device support request
Projects
None yet
Development

No branches or pull requests