Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔹
https://www.zigbee2mqtt.io
GNU General Public License v3.0
12.13k stars 1.68k forks source link

ROB_200-040-0 thermostat gets detected as HK-LN-HEATER-A #15972

Closed jws1992 closed 1 year ago

jws1992 commented 1 year ago

What happened?

Upon including the ROB_200-040-0 floor heating thermostat into Z2M, it recognised the device as a Sunricher HK-LN-HEATER-A, which is not supported. Thus, Z2M disables it and it is not visible in Home Assistant.

Friendly name: 0x1fff000300000079 Description: Last seen: 3 minutes ago Availability: [Disabled] Device type: Router Zigbee Model: HK-LN-HEATER-A Zigbee Manufacturer: Sunricher Support status: Not supported IEEE Address: 0x1fff000300000079 Network address: 0x2655 Firmware build date: NULL Firmware version: 6.9.1.0_r4 Power: Interview completed: True

What did you expect to happen?

For Z2M to recognise the device as ROB_200-040-0, and enable it with the correct parameters.

How to reproduce it (minimal and precise)

Include the ROB_200-040-0 in the zigbee network

Zigbee2MQTT version

1.29.0

Adapter firmware version

20211217

Adapter

SONOFF Zigbee 3.0 dongle

Debug log

2023-01-05 21:36:04Received message from unsupported device with Zigbee model 'HK-LN-HEATER-A' and manufacturer name 'Sunricher' 2023-01-05 21:36:04Please see: https://www.zigbee2mqtt.io/advanced/support-new-devices/01_support_new_devices.html

pitkaha commented 1 year ago

Getting the same problem with same thermostat and same adapter, Z2M version is 1.29.1. Just wanted to add that the thermostat, https://www.robbshop.nl/en/robb-smarrt-zigbee-thermostat is a Sunricher SR-ZG9092A clone, which should be working with Z2M https://www.zigbee2mqtt.io/devices/SR-ZG9092A.html.

pitkaha commented 1 year ago

Getting this to work a little, but hitting a wall even though I think I have all the pieces to make it work all the way. I can control the thermostat and get a bunch of entities. But it won't push changes in values to HA, I have to refresh manually from Z2M to get current temperature for example. Power, Current, Voltage and Energy are not working at all.

Have done the following so far:

Adding a new device with following code in configuration.yaml

external_converters:
  - robbsmart.js

Adding file robbsmart.js into same folder and following code into it (toZigbee, fromZigbee and exposes copied from SR-ZG9092A):

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 definition = {
    zigbeeModel: ['HK-LN-HEATER-A'],
    model: 'ROB_200-040-0',
    vendor: 'ROBB',
    description: 'Robb Smart Thermostat',
    fromZigbee: [fz.thermostat, fz.namron_thermostat, fz.metering, fz.electrical_measurement, fz.namron_hvac_user_interface],
    toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_occupancy,
        tz.thermostat_local_temperature_calibration, tz.thermostat_local_temperature, tz.thermostat_outdoor_temperature,
        tz.thermostat_system_mode, tz.thermostat_control_sequence_of_operation, tz.thermostat_running_state,
        tz.namron_thermostat, tz.namron_thermostat_child_lock],
    exposes: [
        exposes.numeric('outdoor_temperature', ea.STATE_GET).withUnit('°C')
            .withDescription('Current temperature measured from the floor sensor'),
        exposes.climate()
            .withSetpoint('occupied_heating_setpoint', 0, 40, 0.1)
            .withSetpoint('unoccupied_heating_setpoint', 0, 40, 0.1)
            .withLocalTemperature()
            .withLocalTemperatureCalibration(-3, 3, 0.1)
            .withSystemMode(['off', 'auto', 'heat'])
            .withRunningState(['idle', 'heat']),
        exposes.binary('away_mode', ea.ALL, 'ON', 'OFF')
            .withDescription('Enable/disable away mode'),
        exposes.binary('child_lock', ea.ALL, 'UNLOCK', 'LOCK')
            .withDescription('Enables/disables physical input on the device'),
        e.power(), e.current(), e.voltage(), e.energy(),
        exposes.enum('lcd_brightness', ea.ALL, ['low', 'mid', 'high'])
            .withDescription('OLED brightness when operating the buttons.  Default: Medium.'),
        exposes.enum('button_vibration_level', ea.ALL, ['off', 'low', 'high'])
            .withDescription('Key beep volume and vibration level.  Default: Low.'),
        exposes.enum('floor_sensor_type', ea.ALL, ['10k', '15k', '50k', '100k', '12k'])
            .withDescription('Type of the external floor sensor.  Default: NTC 10K/25.'),
        exposes.enum('sensor', ea.ALL, ['air', 'floor', 'both'])
            .withDescription('The sensor used for heat control.  Default: Room Sensor.'),
        exposes.enum('powerup_status', ea.ALL, ['default', 'last_status'])
            .withDescription('The mode after a power reset.  Default: Previous Mode.'),
        exposes.numeric('floor_sensor_calibration', ea.ALL)
            .withUnit('°C')
            .withValueMin(-3).withValueMax(3).withValueStep(0.1)
            .withDescription('The tempearatue calibration for the exernal floor sensor, between -3 and 3 in 0.1°C.  Default: 0.'),
        exposes.numeric('dry_time', ea.ALL)
            .withUnit('min')
            .withValueMin(5).withValueMax(100)
            .withDescription('The duration of Dry Mode, between 5 and 100 minutes.  Default: 5.'),
        exposes.enum('mode_after_dry', ea.ALL, ['off', 'manual', 'auto', 'away'])
            .withDescription('The mode after Dry Mode.  Default: Auto.'),
        exposes.enum('temperature_display', ea.ALL, ['room', 'floor'])
            .withDescription('The temperature on the display.  Default: Room Temperature.'),
        exposes.numeric('window_open_check', ea.ALL)
            .withUnit('°C')
            .withValueMin(0).withValueMax(8).withValueStep(0.5)
            .withDescription('The threshold to detect window open, between 0.0 and 8.0 in 0.5 °C.  Default: 0 (disabled).'),
        exposes.numeric('hysterersis', ea.ALL)
            .withUnit('°C')
            .withValueMin(0.5).withValueMax(2).withValueStep(0.1)
            .withDescription('Hysteresis setting, between 0.5 and 2 in 0.1 °C.  Default: 0.5.'),
        exposes.enum('display_auto_off_enabled', ea.ALL, ['disabled', 'enabled']),
        exposes.numeric('alarm_airtemp_overvalue', ea.ALL)
            .withUnit('°C')
            .withValueMin(20).withValueMax(60)
            .withDescription('Room temperature alarm threshold, between 20 and 60 in °C.  0 means disabled.  Default: 45.'),
    ],
};

module.exports = definition;

When I try to copy whole config from Sunricher SR-ZG9092A (lines 383-605, sunricher.js) which is the same thermostat, Zigbee2MQTT won't start at all with following code in robbsmart.js:

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 definition = {
    zigbeeModel: ['HK-LN-HEATER-A'],
    model: 'ROB_200-040-0',
    vendor: 'ROBB',
    description: 'Touch thermostat',
    fromZigbee: [fz.thermostat, fz.namron_thermostat, fz.metering, fz.electrical_measurement, fz.namron_hvac_user_interface],
    toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_occupancy,
        tz.thermostat_local_temperature_calibration, tz.thermostat_local_temperature, tz.thermostat_outdoor_temperature,
        tz.thermostat_system_mode, tz.thermostat_control_sequence_of_operation, tz.thermostat_running_state,
        tz.namron_thermostat, tz.namron_thermostat_child_lock],
    exposes: [
        exposes.numeric('outdoor_temperature', ea.STATE_GET).withUnit('°C')
            .withDescription('Current temperature measured from the floor sensor'),
        exposes.climate()
            .withSetpoint('occupied_heating_setpoint', 0, 40, 0.1)
            .withSetpoint('unoccupied_heating_setpoint', 0, 40, 0.1)
            .withLocalTemperature()
            .withLocalTemperatureCalibration(-3, 3, 0.1)
            .withSystemMode(['off', 'auto', 'heat'])
            .withRunningState(['idle', 'heat']),
        exposes.binary('away_mode', ea.ALL, 'ON', 'OFF')
            .withDescription('Enable/disable away mode'),
        exposes.binary('child_lock', ea.ALL, 'UNLOCK', 'LOCK')
            .withDescription('Enables/disables physical input on the device'),
        e.power(), e.current(), e.voltage(), e.energy(),
        exposes.enum('lcd_brightness', ea.ALL, ['low', 'mid', 'high'])
            .withDescription('OLED brightness when operating the buttons.  Default: Medium.'),
        exposes.enum('button_vibration_level', ea.ALL, ['off', 'low', 'high'])
            .withDescription('Key beep volume and vibration level.  Default: Low.'),
        exposes.enum('floor_sensor_type', ea.ALL, ['10k', '15k', '50k', '100k', '12k'])
            .withDescription('Type of the external floor sensor.  Default: NTC 10K/25.'),
        exposes.enum('sensor', ea.ALL, ['air', 'floor', 'both'])
            .withDescription('The sensor used for heat control.  Default: Room Sensor.'),
        exposes.enum('powerup_status', ea.ALL, ['default', 'last_status'])
            .withDescription('The mode after a power reset.  Default: Previous Mode.'),
        exposes.numeric('floor_sensor_calibration', ea.ALL)
            .withUnit('°C')
            .withValueMin(-3).withValueMax(3).withValueStep(0.1)
            .withDescription('The tempearatue calibration for the exernal floor sensor, between -3 and 3 in 0.1°C.  Default: 0.'),
        exposes.numeric('dry_time', ea.ALL)
            .withUnit('min')
            .withValueMin(5).withValueMax(100)
            .withDescription('The duration of Dry Mode, between 5 and 100 minutes.  Default: 5.'),
        exposes.enum('mode_after_dry', ea.ALL, ['off', 'manual', 'auto', 'away'])
            .withDescription('The mode after Dry Mode.  Default: Auto.'),
        exposes.enum('temperature_display', ea.ALL, ['room', 'floor'])
            .withDescription('The temperature on the display.  Default: Room Temperature.'),
        exposes.numeric('window_open_check', ea.ALL)
            .withUnit('°C')
            .withValueMin(0).withValueMax(8).withValueStep(0.5)
            .withDescription('The threshold to detect window open, between 0.0 and 8.0 in 0.5 °C.  Default: 0 (disabled).'),
        exposes.numeric('hysterersis', ea.ALL)
            .withUnit('°C')
            .withValueMin(0.5).withValueMax(2).withValueStep(0.1)
            .withDescription('Hysteresis setting, between 0.5 and 2 in 0.1 °C.  Default: 0.5.'),
        exposes.enum('display_auto_off_enabled', ea.ALL, ['disabled', 'enabled']),
        exposes.numeric('alarm_airtemp_overvalue', ea.ALL)
            .withUnit('°C')
            .withValueMin(20).withValueMax(60)
            .withDescription('Room temperature alarm threshold, between 20 and 60 in °C.  0 means disabled.  Default: 45.'),
    ],
    onEvent: async (type, data, device, options) => {
        if (type === 'stop') {
            clearInterval(globalStore.getValue(device, 'time'));
            globalStore.clearValue(device, 'time');
        } else if (!globalStore.hasValue(device, 'time')) {
            const endpoint = device.getEndpoint(1);
            const hours24 = 1000 * 60 * 60 * 24;
            // Device does not ask for the time with binding, therefore we write the time every 24 hours
            const interval = setInterval(async () => syncTime(endpoint), hours24);
            globalStore.putValue(device, 'time', interval);
        }
    },
    configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        const binds = [
            'genBasic', 'genIdentify', 'hvacThermostat', 'seMetering', 'haElectricalMeasurement', 'genAlarms',
            'msOccupancySensing', 'genTime', 'hvacUserInterfaceCfg',
        ];
        await reporting.bind(endpoint, coordinatorEndpoint, binds);

        // standard ZCL attributes
        await reporting.thermostatTemperature(endpoint);
        await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
        await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
        try {
            await reporting.thermostatKeypadLockMode(endpoint);
        } catch (error) {
            // Fails for some
            // https://github.com/Koenkk/zigbee2mqtt/issues/15025
            logger.debug(`Failed to setup keypadLockout reporting`);
        }

        await endpoint.configureReporting('hvacThermostat', [{
            attribute: 'occupancy',
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null,
        }]);

        await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier']);
        await endpoint.read('haElectricalMeasurement', ['acCurrentDivisor']);
        await endpoint.read('seMetering', ['multiplier', 'divisor']);

        await reporting.activePower(endpoint, {min: 30, change: 10}); // Min report change 10W
        await reporting.rmsCurrent(endpoint, {min: 30, change: 50}); // Min report change 0.05A
        await reporting.rmsVoltage(endpoint, {min: 30, change: 20}); // Min report change 2V
        await reporting.readMeteringMultiplierDivisor(endpoint);
        await reporting.currentSummDelivered(endpoint);

        // Custom attributes
        const options = {manufacturerCode: 0x1224}; // Sunricher Manufacturer Code

        // OperateDisplayLcdBrightnesss
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1000, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // ButtonVibrationLevel
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1001, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // FloorSensorType
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1002, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // ControlType
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1003, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // PowerUpStatus
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1004, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // FloorSensorCalibration
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1005, type: 0x28},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // DryTime
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1006, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // ModeAfterDry
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1007, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // TemperatureDisplay
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1008, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // WindowOpenCheck
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1009, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);

        // Hysterersis
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x100A, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);

        // DisplayAutoOffEnable
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x100B, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);

        // AlarmAirTempOverValue
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x2001, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // Away Mode Set
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x2002, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);

        // Device does not asks for the time with binding, we need to write time during configure
        syncTime(endpoint);

        // Trigger initial read
        await endpoint.read('hvacThermostat', ['systemMode', 'runningState', 'occupiedHeatingSetpoint']);
        await endpoint.read('hvacThermostat', [0x1000, 0x1001, 0x1002, 0x1003], options);
        await endpoint.read('hvacThermostat', [0x1004, 0x1005, 0x1006, 0x1007], options);
        await endpoint.read('hvacThermostat', [0x1008, 0x1009, 0x100A, 0x100B], options);
        await endpoint.read('hvacThermostat', [0x2001, 0x2002], options);
    },
};

module.exports = definition;

What am I doing wrong? If I understood correctly other way to make this work could be adding something like fingerprint: [{modelID: 'HK-LN-HEATER-A', manufacturerName: 'Sunricher'}], to sunricher.js under SR-ZG9092A, but don't know how to test this.

Heres a screenshot how the thermostat shows up in Z2M with first code:

Screenshot 2023-01-13 at 10 00 59
Koenkk commented 1 year ago

@pitkaha you need to have the configure to setup the device to push values to z2m. What error do you get when using the configure?

pitkaha commented 1 year ago

@Koenkk Okay, thanks, I figured that the second, longer config would do that.

With the longer config Zigbee2MQTT logs show following error:

ReferenceError: globalStore is not defined
    at Object.onEvent (/app/data/extension/externally-loaded.js:74:16)
    at OnEvent.callOnEvent (/app/lib/extension/onEvent.ts:47:37)
    at OnEvent.start (/app/lib/extension/onEvent.ts:10:18)
    at Controller.callExtensions (/app/lib/controller.ts:316:40)
    at Controller.start (/app/lib/controller.ts:153:9)
    at start (/app/index.js:107:5)
Koenkk commented 1 year ago

At the top of the file, add const globalStore = require('zigbee-herdsman-converters/lib/store');

pitkaha commented 1 year ago

Great, thanks, now Z2M boots normally. I'll have to test the thermostat when I get home, will report back.

pitkaha commented 1 year ago

@Koenkk Seems like everything else is working nicely and updating to Z2M, thanks. Only energy usage in kWh is missing. Thermostat itself shows reasonable looking numbers in kWh, but those won't show up in Z2M. Power, current and voltage are visible and change according to thermostats heating status.

Configuration has these lines for electricity-related fields. Working fields have values for min report changes, should currentSummDelivered have those as well? Any other ideas?

        await reporting.activePower(endpoint, {min: 30, change: 10}); // Min report change 10W
        await reporting.rmsCurrent(endpoint, {min: 30, change: 50}); // Min report change 0.05A
        await reporting.rmsVoltage(endpoint, {min: 30, change: 20}); // Min report change 2V
        await reporting.readMeteringMultiplierDivisor(endpoint);
        await reporting.currentSummDelivered(endpoint);
Koenkk commented 1 year ago

No that shouldn't be the case. What if you read the currentSumDelivered (seMetering) cluster from the z2m frontend -> dev console?

pitkaha commented 1 year ago

@Koenkk That gives me 2023-01-18 16:27:51Read result of 'seMetering': {"currentSummDelivered":[0,156]}. Just added a second identical thermostat, that gives 2023-01-18 16:28:41Read result of 'seMetering': {"currentSummDelivered":[0,4]}

Edit: New values after an hour, both thermostat on heat the whole time: Original thermostat, load about 105W 2023-01-18 17:27:49Read result of 'seMetering': {"currentSummDelivered":[0,157]}. Second thermostat, load about 1050W 2023-01-18 17:28:59Read result of 'seMetering': {"currentSummDelivered":[0,15]}.

2h: 2023-01-18 18:34:30Read result of 'seMetering': {"currentSummDelivered":[0,158]} 2023-01-18 18:35:02Read result of 'seMetering': {"currentSummDelivered":[0,26]}

Don't really know what the values mean but could be kWh multiplied by 0,1? Power seems to be off by factor of 10 as well, current shows 0 on first thermostat, second gives values that look like mA really.

Screenshot 2023-01-18 at 17 34 23 Screenshot 2023-01-18 at 17 35 41

Edit: Also first thermostat is showing 15,7 kWh energy used on its own screen. Can't verify other values, as the thermostat only shows counters when its off. Power seems to be correct, as the second floor heating should be about 1000W, and the first one is about 1/10 of the area.

Koenkk commented 1 year ago

Can you provide the debug log when triggering the reconfigure from the z2m frontend? (press yellow reconfigure button)

See https://www.zigbee2mqtt.io/guide/usage/debug.html on how to enable debug logging.

pitkaha commented 1 year ago

@Koenkk I get this:

Debug 2023-01-19 08:37:05Received MQTT message on 'zigbee2mqtt/bridge/request/device/configure' with data '{"id":"Termostaatti YlÀvessa","transaction":"eg8u5-1"}'
Info 2023-01-19 08:37:05Configuring 'Termostaatti YlÀvessa'
Debug 2023-01-19 08:37:08Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2094}' from endpoint 1 with groupID 0
Info 2023-01-19 08:37:08MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"OFF","button_vibration_level":"low","child_lock":"UNLOCK","current":437,"display_auto_off_enabled":"disabled","dry_time":45,"energy":null,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":116,"local_temperature":20.94,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":18.68,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":12,"voltage":0,"window_open_check":0}'
Error 2023-01-19 08:37:09Failed to configure 'Termostaatti YlÀvessa', attempt 4 (ReferenceError: constants is not defined at Object.configure (/app/data/extension/externally-loaded.js:106:36) at Configure.configure (/app/lib/extension/configure.ts:117:13) at Configure.onMQTTMessage (/app/lib/extension/configure.ts:55:21))
Info 2023-01-19 08:37:09MQTT publish: topic 'zigbee2mqtt/bridge/response/device/configure', payload '{"data":{"id":"Termostaatti YlÀvessa"},"error":"Failed to configure (constants is not defined)","status":"error","transaction":"eg8u5-1"}'

This kind of error also shows up from time to time:

Error 2023-01-19 08:43:57Failed to configure 'Termostaatti YlÀvessa', attempt 3 (ReferenceError: constants is not defined at Object.configure (/app/data/extension/externally-loaded.js:106:36) at Configure.configure (/app/lib/extension/configure.ts:117:13))
Debug 2023-01-19 08:43:58Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2213}' from endpoint 1 with groupID 0
Koenkk commented 1 year ago

Try adding this add the top of your converter and see if it fixes the issue: const constants = require('zigbee-herdsman-converters/lib/constants');

pitkaha commented 1 year ago

@Koenkk Good news, current and voltage are now correct (voltage * current = power is true), and one of the thermostats shows energy with same 4.2kWh as the device itself. Other one still shows null. Tried to reconfigure, boot Z2M, boot HA, still null.

edit: went to take a screenshot and now the energy is there, i guess the value needed to change for it to update?

Screenshot 2023-01-19 at 22 36 55 Screenshot 2023-01-19 at 22 20 04

After reconfiguring the one with null kWh gives:

Debug 2023-01-19 22:21:00Received MQTT message on 'zigbee2mqtt/bridge/request/device/configure' with data '{"id":"Termostaatti YlÀvessa","transaction":"tlu4b-1"}'
Info 2023-01-19 22:21:00Configuring 'Termostaatti YlÀvessa'
Debug 2023-01-19 22:21:02Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentMultiplier":1,"acVoltageDivisor":10,"acVoltageMultiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:21:02Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentDivisor":1000}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:21:02Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:21:03Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2300}' from endpoint 1 with groupID 0
Info 2023-01-19 22:21:03MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"OFF","button_vibration_level":"low","child_lock":"UNLOCK","current":0.44,"display_auto_off_enabled":"disabled","dry_time":45,"energy":null,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":98,"local_temperature":23,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":25.5,"outdoor_temperature":18.68,"power":102,"powerup_status":"last_status","running_state":"heat","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":12,"voltage":0,"window_open_check":0}'
Debug 2023-01-19 22:21:03Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Error 2023-01-19 22:21:03Failed to configure 'Termostaatti YlÀvessa', attempt 4 (ReferenceError: options is not defined at Object.configure (/app/data/extension/externally-loaded.js:127:9) at Configure.configure (/app/lib/extension/configure.ts:117:13) at Configure.onMQTTMessage (/app/lib/extension/configure.ts:55:21))
Info 2023-01-19 22:21:03MQTT publish: topic 'zigbee2mqtt/bridge/response/device/configure', payload '{"data":{"id":"Termostaatti YlÀvessa"},"error":"Failed to configure (options is not defined)","status":"error","transaction":"tlu4b-1"}'

After boot the working one gives following logs:

Debug 2023-01-19 22:28:00Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentDivisor":1000}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:00Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:00Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Error 2023-01-19 22:28:00Failed to configure 'Termostaatti Eteinen', attempt 1 (ReferenceError: options is not defined at Object.configure (/app/data/extension/externally-loaded.js:127:9) at Configure.configure (/app/lib/extension/configure.ts:117:13))
Debug 2023-01-19 22:28:01Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentMultiplier":1,"acVoltageDivisor":10,"acVoltageMultiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:01Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentDivisor":1000}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:01Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:01Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Error 2023-01-19 22:28:01Failed to configure 'Termostaatti YlÀvessa', attempt 1 (ReferenceError: options is not defined at Object.configure (/app/data/extension/externally-loaded.js:127:9) at Configure.configure (/app/lib/extension/configure.ts:117:13) at Immediate.<anonymous> (/app/lib/extension/configure.ts:69:17))
Info 2023-01-19 22:28:01Configuring 'Termostaatti Eteinen'
Debug 2023-01-19 22:28:01Received Zigbee message from 'Termostaatti Eteinen', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2345}' from endpoint 1 with groupID 0
Info 2023-01-19 22:28:01MQTT publish: topic 'zigbee2mqtt/Termostaatti Eteinen', payload '{"alarm_airtemp_overvalue":0,"away_mode":"OFF","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":5,"energy":4.2,"floor_sensor_calibration":0,"floor_sensor_type":"10k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":94,"local_temperature":23.45,"local_temperature_calibration":0,"mode_after_dry":"auto","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":0,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"air","system_mode":"heat","temperature_display":"room","unoccupied_heating_setpoint":10,"voltage":0,"window_open_check":0}'
Debug 2023-01-19 22:28:03Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentMultiplier":1,"acVoltageDivisor":10,"acVoltageMultiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:03Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentDivisor":1000}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:03Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:03Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Error 2023-01-19 22:28:03Failed to configure 'Termostaatti Eteinen', attempt 2 (ReferenceError: options is not defined at Object.configure (/app/data/extension/externally-loaded.js:127:9) at Configure.configure (/app/lib/extension/configure.ts:117:13) at Immediate.<anonymous> (/app/lib/extension/configure.ts:69:17))
Debug 2023-01-19 22:28:03Received Zigbee message from 'Termostaatti Eteinen', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2299}' from endpoint 1 with groupID 0
Info 2023-01-19 22:28:03Configuring 'Termostaatti Eteinen'
Info 2023-01-19 22:28:03MQTT publish: topic 'zigbee2mqtt/Termostaatti Eteinen', payload '{"alarm_airtemp_overvalue":0,"away_mode":"OFF","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":5,"energy":4.2,"floor_sensor_calibration":0,"floor_sensor_type":"10k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":98,"local_temperature":22.99,"local_temperature_calibration":0,"mode_after_dry":"auto","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":0,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"air","system_mode":"heat","temperature_display":"room","unoccupied_heating_setpoint":10,"voltage":0,"window_open_check":0}'
Debug 2023-01-19 22:28:04Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentMultiplier":1,"acVoltageDivisor":10,"acVoltageMultiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:04Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentDivisor":1000}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:04Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-19 22:28:04Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Error 2023-01-19 22:28:04Failed to configure 'Termostaatti Eteinen', attempt 3 (ReferenceError: options is not defined at Object.configure (/app/data/extension/externally-loaded.js:127:9) at Configure.configure (/app/lib/extension/configure.ts:117:13))

Also some errors that come up time to time:

Error 2023-01-19 22:12:11Failed to configure 'Termostaatti YlÀvessa', attempt 2 (ReferenceError: options is not defined at Object.configure (/app/data/extension/externally-loaded.js:127:9) at Configure.configure (/app/lib/extension/configure.ts:117:13))
Debug 2023-01-19 22:12:11Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentMultiplier":1,"acVoltageDivisor":10,"acVoltageMultiplier":1}' from endpoint 1 with groupID 0

Debug 2023-01-19 22:15:41Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Error 2023-01-19 22:15:41Failed to configure 'Termostaatti YlÀvessa', attempt 3 (ReferenceError: options is not defined at Object.configure (/app/data/extension/externally-loaded.js:127:9) at Configure.configure (/app/lib/extension/configure.ts:117:13))
Koenkk commented 1 year ago

Can you post the converter as you have it now? Failed to configure should not occur. And yes it can take some time before the device starts reporting the energy value (its value first needs to change before the device reports it).

pitkaha commented 1 year ago

@Koenkk Here you go. Only thing I added at least on purpose outside additions in this conversation is on rows 24-25

        exposes.numeric('local_temperature', ea.STATE_GET).withUnit('°C')
            .withDescription('Current temperature measured from the room sensor'),

which seems to work, gives me thermostats room temperature as an entity that was missing.

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 globalStore = require('zigbee-herdsman-converters/lib/store');
const constants = require('zigbee-herdsman-converters/lib/constants');

const definition = {
    zigbeeModel: ['HK-LN-HEATER-A'],
    model: 'ROB_200-040-0',
    vendor: 'ROBB',
    description: 'Touch thermostat',
    fromZigbee: [fz.thermostat, fz.namron_thermostat, fz.metering, fz.electrical_measurement, fz.namron_hvac_user_interface],
    toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_occupancy,
        tz.thermostat_local_temperature_calibration, tz.thermostat_local_temperature, tz.thermostat_outdoor_temperature,
        tz.thermostat_system_mode, tz.thermostat_control_sequence_of_operation, tz.thermostat_running_state,
        tz.namron_thermostat, tz.namron_thermostat_child_lock],
    exposes: [
        exposes.numeric('outdoor_temperature', ea.STATE_GET).withUnit('°C')
            .withDescription('Current temperature measured from the floor sensor'),
        exposes.numeric('local_temperature', ea.STATE_GET).withUnit('°C')
            .withDescription('Current temperature measured from the room sensor'),
        exposes.climate()
            .withSetpoint('occupied_heating_setpoint', 0, 40, 0.1)
            .withSetpoint('unoccupied_heating_setpoint', 0, 40, 0.1)
            .withLocalTemperature()
            .withLocalTemperatureCalibration(-3, 3, 0.1)
            .withSystemMode(['off', 'auto', 'heat'])
            .withRunningState(['idle', 'heat']),
        exposes.binary('away_mode', ea.ALL, 'ON', 'OFF')
            .withDescription('Enable/disable away mode'),
        exposes.binary('child_lock', ea.ALL, 'UNLOCK', 'LOCK')
            .withDescription('Enables/disables physical input on the device'),
        e.power(), e.current(), e.voltage(), e.energy(),
        exposes.enum('lcd_brightness', ea.ALL, ['low', 'mid', 'high'])
            .withDescription('OLED brightness when operating the buttons.  Default: Medium.'),
        exposes.enum('button_vibration_level', ea.ALL, ['off', 'low', 'high'])
            .withDescription('Key beep volume and vibration level.  Default: Low.'),
        exposes.enum('floor_sensor_type', ea.ALL, ['10k', '15k', '50k', '100k', '12k'])
            .withDescription('Type of the external floor sensor.  Default: NTC 10K/25.'),
        exposes.enum('sensor', ea.ALL, ['air', 'floor', 'both'])
            .withDescription('The sensor used for heat control.  Default: Room Sensor.'),
        exposes.enum('powerup_status', ea.ALL, ['default', 'last_status'])
            .withDescription('The mode after a power reset.  Default: Previous Mode.'),
        exposes.numeric('floor_sensor_calibration', ea.ALL)
            .withUnit('°C')
            .withValueMin(-3).withValueMax(3).withValueStep(0.1)
            .withDescription('The tempearatue calibration for the exernal floor sensor, between -3 and 3 in 0.1°C.  Default: 0.'),
        exposes.numeric('dry_time', ea.ALL)
            .withUnit('min')
            .withValueMin(5).withValueMax(100)
            .withDescription('The duration of Dry Mode, between 5 and 100 minutes.  Default: 5.'),
        exposes.enum('mode_after_dry', ea.ALL, ['off', 'manual', 'auto', 'away'])
            .withDescription('The mode after Dry Mode.  Default: Auto.'),
        exposes.enum('temperature_display', ea.ALL, ['room', 'floor'])
            .withDescription('The temperature on the display.  Default: Room Temperature.'),
        exposes.numeric('window_open_check', ea.ALL)
            .withUnit('°C')
            .withValueMin(0).withValueMax(8).withValueStep(0.5)
            .withDescription('The threshold to detect window open, between 0.0 and 8.0 in 0.5 °C.  Default: 0 (disabled).'),
        exposes.numeric('hysterersis', ea.ALL)
            .withUnit('°C')
            .withValueMin(0.5).withValueMax(2).withValueStep(0.1)
            .withDescription('Hysteresis setting, between 0.5 and 2 in 0.1 °C.  Default: 0.5.'),
        exposes.enum('display_auto_off_enabled', ea.ALL, ['disabled', 'enabled']),
        exposes.numeric('alarm_airtemp_overvalue', ea.ALL)
            .withUnit('°C')
            .withValueMin(20).withValueMax(60)
            .withDescription('Room temperature alarm threshold, between 20 and 60 in °C.  0 means disabled.  Default: 45.'),
    ],
    onEvent: async (type, data, device, options) => {
        if (type === 'stop') {
            clearInterval(globalStore.getValue(device, 'time'));
            globalStore.clearValue(device, 'time');
        } else if (!globalStore.hasValue(device, 'time')) {
            const endpoint = device.getEndpoint(1);
            const hours24 = 1000 * 60 * 60 * 24;
            // Device does not ask for the time with binding, therefore we write the time every 24 hours
            const interval = setInterval(async () => syncTime(endpoint), hours24);
            globalStore.putValue(device, 'time', interval);
        }
    },
    configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        const binds = [
            'genBasic', 'genIdentify', 'hvacThermostat', 'seMetering', 'haElectricalMeasurement', 'genAlarms',
            'msOccupancySensing', 'genTime', 'hvacUserInterfaceCfg',
        ];
        await reporting.bind(endpoint, coordinatorEndpoint, binds);

        // standard ZCL attributes
        await reporting.thermostatTemperature(endpoint);
        await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
        await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
        try {
            await reporting.thermostatKeypadLockMode(endpoint);
        } catch (error) {
            // Fails for some
            // https://github.com/Koenkk/zigbee2mqtt/issues/15025
            logger.debug(`Failed to setup keypadLockout reporting`);
        }

        await endpoint.configureReporting('hvacThermostat', [{
            attribute: 'occupancy',
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null,
        }]);

        await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier']);
        await endpoint.read('haElectricalMeasurement', ['acCurrentDivisor']);
        await endpoint.read('seMetering', ['multiplier', 'divisor']);

        await reporting.activePower(endpoint, {min: 30, change: 10}); // Min report change 10W
        await reporting.rmsCurrent(endpoint, {min: 30, change: 50}); // Min report change 0.05A
        await reporting.rmsVoltage(endpoint, {min: 30, change: 20}); // Min report change 2V
        await reporting.readMeteringMultiplierDivisor(endpoint);
        await reporting.currentSummDelivered(endpoint);

        // OperateDisplayLcdBrightnesss
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1000, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // ButtonVibrationLevel
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1001, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // FloorSensorType
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1002, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // ControlType
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1003, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // PowerUpStatus
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1004, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // FloorSensorCalibration
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1005, type: 0x28},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // DryTime
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1006, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // ModeAfterDry
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1007, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // TemperatureDisplay
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1008, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // WindowOpenCheck
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1009, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);

        // Hysterersis
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x100A, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);

        // DisplayAutoOffEnable
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x100B, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);

        // AlarmAirTempOverValue
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x2001, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // Away Mode Set
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x2002, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);

        // Device does not asks for the time with binding, we need to write time during configure
        syncTime(endpoint);

        // Trigger initial read
        await endpoint.read('hvacThermostat', ['systemMode', 'runningState', 'occupiedHeatingSetpoint']);
        await endpoint.read('hvacThermostat', [0x1000, 0x1001, 0x1002, 0x1003], options);
        await endpoint.read('hvacThermostat', [0x1004, 0x1005, 0x1006, 0x1007], options);
        await endpoint.read('hvacThermostat', [0x1008, 0x1009, 0x100A, 0x100B], options);
        await endpoint.read('hvacThermostat', [0x2001, 0x2002], options);
    },
};

module.exports = definition;
Koenkk commented 1 year ago

This part was removed:

        // Custom attributes
        const options = {manufacturerCode: 0x1224}; // Sunricher Manufacturer Code

which was in the second converter of https://github.com/Koenkk/zigbee2mqtt/issues/15972#issuecomment-1381449543

pitkaha commented 1 year ago

Okay, thanks, added that back in, still getting error on config:

Debug 2023-01-22 10:26:17Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:26:17Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:26:17Received Zigbee message from 'Termostaatti Eteinen', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":1731}' from endpoint 1 with groupID 0
Info 2023-01-22 10:26:17MQTT publish: topic 'zigbee2mqtt/Termostaatti Eteinen', payload '{"alarm_airtemp_overvalue":0,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":5,"energy":4.2,"floor_sensor_calibration":0,"floor_sensor_type":"10k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":76,"local_temperature":17.31,"local_temperature_calibration":0,"mode_after_dry":"auto","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":0,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"air","system_mode":"heat","temperature_display":"room","unoccupied_heating_setpoint":10,"voltage":0,"window_open_check":0}'
Error 2023-01-22 10:26:18Failed to configure 'Termostaatti Eteinen', attempt 2 (ReferenceError: syncTime is not defined at Object.configure (/app/data/extension/externally-loaded.js:229:9) at Configure.configure (/app/lib/extension/configure.ts:117:13))

And with reconfiguring almost the same with both thermostats:

Info 2023-01-22 10:28:23Configuring 'Termostaatti Eteinen'
Debug 2023-01-22 10:28:24Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentMultiplier":1,"acVoltageDivisor":10,"acVoltageMultiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:28:24Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentDivisor":1000}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:28:24Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:28:25Received Zigbee message from 'Termostaatti Eteinen', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:28:25Received Zigbee message from 'Termostaatti Eteinen', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":1732}' from endpoint 1 with groupID 0
Info 2023-01-22 10:28:25MQTT publish: topic 'zigbee2mqtt/Termostaatti Eteinen', payload '{"alarm_airtemp_overvalue":0,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":5,"energy":4.2,"floor_sensor_calibration":0,"floor_sensor_type":"10k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":76,"local_temperature":17.32,"local_temperature_calibration":0,"mode_after_dry":"auto","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":0,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"air","system_mode":"heat","temperature_display":"room","unoccupied_heating_setpoint":10,"voltage":0,"window_open_check":0}'
Error 2023-01-22 10:28:25Failed to configure 'Termostaatti Eteinen', attempt 4 (ReferenceError: syncTime is not defined at Object.configure (/app/data/extension/externally-loaded.js:229:9) at Configure.configure (/app/lib/extension/configure.ts:117:13) at Configure.onMQTTMessage (/app/lib/extension/configure.ts:55:21))
Koenkk commented 1 year ago

Above const definition = { add:

async function syncTime(endpoint) {
    try {
        const time = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000 + ((new Date()).getTimezoneOffset() * -1) * 60);
        const values = {time: time};
        await endpoint.write('genTime', values);
    } catch (error) {/* Do nothing*/}
}
pitkaha commented 1 year ago

Looks good, thank you! No errors, gives successfully configured.

Info 2023-01-22 10:50:18Configuring 'Termostaatti YlÀvessa'
Debug 2023-01-22 10:50:19Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentMultiplier":1,"acVoltageDivisor":10,"acVoltageMultiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:50:19Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'haElectricalMeasurement', data '{"acCurrentDivisor":1000}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:50:19Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:50:20Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'seMetering', data '{"divisor":10,"multiplier":1}' from endpoint 1 with groupID 0
Debug 2023-01-22 10:50:20Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2042}' from endpoint 1 with groupID 0
Info 2023-01-22 10:50:20MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":17.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":112,"local_temperature":20.42,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":18.68,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":12,"voltage":0,"window_open_check":0}'
Debug 2023-01-22 10:50:21Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'hvacThermostat', data '{"occupiedHeatingSetpoint":1700,"runningState":0,"systemMode":4}' from endpoint 1 with groupID 0
Info 2023-01-22 10:50:21MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":17.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":109,"local_temperature":20.42,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":18.68,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":12,"voltage":0,"window_open_check":0}'
Debug 2023-01-22 10:50:21Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'hvacThermostat', data '{"4096":1,"4097":1,"4098":2,"4099":1}' from endpoint 1 with groupID 0
Info 2023-01-22 10:50:21MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":17.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":109,"local_temperature":20.42,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":18.68,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":12,"voltage":0,"window_open_check":0}'
Debug 2023-01-22 10:50:21Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'hvacThermostat', data '{"4100":1,"4101":0,"4102":45,"4103":1}' from endpoint 1 with groupID 0
Info 2023-01-22 10:50:21MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":17.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":109,"local_temperature":20.42,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":18.68,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":12,"voltage":0,"window_open_check":0}'
Debug 2023-01-22 10:50:21Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'hvacThermostat', data '{"4104":1,"4105":0,"4106":5,"4107":0}' from endpoint 1 with groupID 0
Info 2023-01-22 10:50:21MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":17.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":109,"local_temperature":20.42,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":18.68,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":12,"voltage":0,"window_open_check":0}'
Debug 2023-01-22 10:50:21Received Zigbee message from 'Termostaatti YlÀvessa', type 'readResponse', cluster 'hvacThermostat', data '{"8193":32,"8194":1}' from endpoint 1 with groupID 0
Info 2023-01-22 10:50:21MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":17.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":109,"local_temperature":20.42,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":18.68,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":12,"voltage":0,"window_open_check":0}'
Info 2023-01-22 10:50:21Successfully configured 'Termostaatti YlÀvessa'

Few little problems left. Thermostat on home assistant takes temperature from local_temperature. Haven't figured out how to change it to outdoor_temperature. Tried to change it in binding,

Screenshot 2023-01-22 at 11 13 57

but changing localTemp to outdoorTemp doesn't seems to do anything, have rebooted HA and Z2M. Any tips?

Also both thermostats are turning on away mode seemingly randomly but at the same time, can't find any setting for it, nor any timers or anything, any clue? This changes setting for thermostat. Google wasn't much of help, seems that away mode is connected to occupancy. Don't have any automations either. Is it possible that this is on HA side? Don't have any automations regarding away/home on HA at all.

Screenshot 2023-01-22 at 11 27 24 Screenshot 2023-01-22 at 11 36 46

Last thing is that when I added.

        exposes.numeric('local_temperature', ea.STATE_GET).withUnit('°C')
            .withDescription('Current temperature measured from the room sensor'),

I got the entity working as intended, but 'local_temperature' comes up twice under Exposes. Doesn't really bother me but just something I noticed

Screenshot 2023-01-22 at 11 31 12
Koenkk commented 1 year ago

Few little problems left. Thermostat on home assistant takes temperature from local_temperature. Haven't figured out how to change it to outdoor_temperature. Tried to change it in binding,

The local temperature should be used, why do you want the outdoor temperature?

Also both thermostats are turning on away mode seemingly randomly but at the same time, can't find any setting for it, nor any timers or anything, any clue?

Looks specific for this thermostat, I haven't seen this with others yet.

pitkaha commented 1 year ago

Few little problems left. Thermostat on home assistant takes temperature from local_temperature. Haven't figured out how to change it to outdoor_temperature. Tried to change it in binding,

The local temperature should be used, why do you want the outdoor temperature?

Outdoor_temperature is temperature from the sensor that is installed into the floor next to the heating elements. Some of the thermostats are not in the same room with the floor heating, because of the humidity I suppose, so local temperature won't rise when the heating is on. This type of installation is common at least where I live (Finland). Most of the thermostats use external sensor with electric floor heating, but not all. I guess best option would be for the user to be able to pick which temperature would be sent to HA with climate data with each thermostat.

Also both thermostats are turning on away mode seemingly randomly but at the same time, can't find any setting for it, nor any timers or anything, any clue?

Looks specific for this thermostat, I haven't seen this with others yet.

Yep, could be something with my HA as well, have to look into it when I get my setup finished.

MischaDing commented 1 year ago

Few little problems left. Thermostat on home assistant takes temperature from local_temperature. Haven't figured out how to change it to outdoor_temperature. Tried to change it in binding,

The local temperature should be used, why do you want the outdoor temperature?

Outdoor_temperature is temperature from the sensor that is installed into the floor next to the heating elements. Some of the thermostats are not in the same room with the floor heating, because of the humidity I suppose, so local temperature won't rise when the heating is on. This type of installation is common at least where I live (Finland). Most of the thermostats use external sensor with electric floor heating, but not all. I guess best option would be for the user to be able to pick which temperature would be sent to HA with climate data with each thermostat.

Also both thermostats are turning on away mode seemingly randomly but at the same time, can't find any setting for it, nor any timers or anything, any clue?

Looks specific for this thermostat, I haven't seen this with others yet.

Yep, could be something with my HA as well, have to look into it when I get my setup finished.

In the settings of the device there is an option on which temperature sensor the heat control should responding to. This should also toggle the temperature given to HA thermostat.

pitkaha commented 1 year ago

Few little problems left. Thermostat on home assistant takes temperature from local_temperature. Haven't figured out how to change it to outdoor_temperature. Tried to change it in binding,

The local temperature should be used, why do you want the outdoor temperature?

Outdoor_temperature is temperature from the sensor that is installed into the floor next to the heating elements. Some of the thermostats are not in the same room with the floor heating, because of the humidity I suppose, so local temperature won't rise when the heating is on. This type of installation is common at least where I live (Finland). Most of the thermostats use external sensor with electric floor heating, but not all. I guess best option would be for the user to be able to pick which temperature would be sent to HA with climate data with each thermostat.

Also both thermostats are turning on away mode seemingly randomly but at the same time, can't find any setting for it, nor any timers or anything, any clue?

Looks specific for this thermostat, I haven't seen this with others yet.

Yep, could be something with my HA as well, have to look into it when I get my setup finished.

In the settings of the device there is an option on which temperature sensor the heat control should responding to. This should also toggle the temperature given to HA thermostat.

@MischaDing You mean in the Z2M under exposes for the device? sensor and temperature_display can be changed between floor and room sensor. Those both switch the settings on the device itself, but not on the Home Assistants thermostats, at least for me. Have tried all combinations and with reboots between them.

Does your thermostat stay on normal mode or does it jump to away mode by itself?

pitkaha commented 1 year ago

@Koenkk mind to take a look?

Have been working on the away mode problem little by little. Installed a third thermostat, but didn't connect it to Z2M for a few days, no problems with away mode. After connecting to Z2M it started going to away mode same time with the other two, still seemingly randomly. Have tried to turn off all the thermostats one by one, the other two left on still go to away mode randomly at the same time.

Here is HA log at the time te away mode turns on. Before this was something with lamps, after this the other two thermostats with basically same logs going to away mode as well.

To me this looks like the away mode is coming from MQTT or Z2M, doesn't look like HA is turning it on, or do I read it all wrong? Also would not think that it's the thermostats either, as they function normally by themselves.

2023-02-13 17:05:56.464 DEBUG (Thread-2 (_thread_main)) [paho.mqtt.client] Received PUBLISH (d0, q0, r0, m0), 'zigbee2mqtt/Termostaatti YlÀvessa', ...  (653 bytes)
2023-02-13 17:05:56.465 DEBUG (MainThread) [homeassistant.components.mqtt.client] Received message on zigbee2mqtt/Termostaatti YlÀvessa (qos=0): b'{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}'
2023-02-13 17:05:56.465 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'select.termostaatti_ylavessa_lcd_brightness', 'name': 'Termostaatti YlÀvessa lcd brightness', 'this': <template TemplateStateFromEntityId(select.termostaatti_ylavessa_lcd_brightness)>} and Template("{{ value_json.lcd_brightness }}")
2023-02-13 17:05:56.465 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'select.termostaatti_ylavessa_button_vibration_level', 'name': 'Termostaatti YlÀvessa button vibration level', 'this': <template TemplateStateFromEntityId(select.termostaatti_ylavessa_button_vibration_level)>} and Template("{{ value_json.button_vibration_level }}")
2023-02-13 17:05:56.465 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'select.termostaatti_ylavessa_floor_sensor_type', 'name': 'Termostaatti YlÀvessa floor sensor type', 'this': <template TemplateStateFromEntityId(select.termostaatti_ylavessa_floor_sensor_type)>} and Template("{{ value_json.floor_sensor_type }}")
2023-02-13 17:05:56.465 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'select.termostaatti_ylavessa_sensor', 'name': 'Termostaatti YlÀvessa sensor', 'this': <template TemplateStateFromEntityId(select.termostaatti_ylavessa_sensor)>} and Template("{{ value_json.sensor }}")
2023-02-13 17:05:56.465 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'select.termostaatti_ylavessa_powerup_status', 'name': 'Termostaatti YlÀvessa powerup status', 'this': <template TemplateStateFromEntityId(select.termostaatti_ylavessa_powerup_status)>} and Template("{{ value_json.powerup_status }}")
2023-02-13 17:05:56.466 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'select.termostaatti_ylavessa_mode_after_dry', 'name': 'Termostaatti YlÀvessa mode after dry', 'this': <template TemplateStateFromEntityId(select.termostaatti_ylavessa_mode_after_dry)>} and Template("{{ value_json.mode_after_dry }}")
2023-02-13 17:05:56.466 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'select.termostaatti_ylavessa_temperature_display', 'name': 'Termostaatti YlÀvessa temperature display', 'this': <template TemplateStateFromEntityId(select.termostaatti_ylavessa_temperature_display)>} and Template("{{ value_json.temperature_display }}")
2023-02-13 17:05:56.466 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'select.termostaatti_ylavessa_display_auto_off_enabled', 'name': 'Termostaatti YlÀvessa display auto off enabled', 'this': <template TemplateStateFromEntityId(select.termostaatti_ylavessa_display_auto_off_enabled)>} and Template("{{ value_json.display_auto_off_enabled }}")
2023-02-13 17:05:56.466 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'sensor.termostaatti_ylavessa_outdoor_temperature', 'name': 'Termostaatti YlÀvessa outdoor temperature', 'this': <template TemplateStateFromEntityId(sensor.termostaatti_ylavessa_outdoor_temperature)>} with default value 'default' and Template("{{ value_json.outdoor_temperature }}")
2023-02-13 17:05:56.466 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'sensor.termostaatti_ylavessa_power', 'name': 'Termostaatti YlÀvessa power', 'this': <template TemplateStateFromEntityId(sensor.termostaatti_ylavessa_power)>} with default value 'default' and Template("{{ value_json.power }}")
2023-02-13 17:05:56.466 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'sensor.termostaatti_ylavessa_energy', 'name': 'Termostaatti YlÀvessa energy', 'this': <template TemplateStateFromEntityId(sensor.termostaatti_ylavessa_energy)>} with default value 'default' and Template("{{ value_json.energy }}")
2023-02-13 17:05:56.466 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'sensor.termostaatti_ylavessa_local_temperature', 'name': 'Termostaatti YlÀvessa local temperature', 'this': <template TemplateStateFromEntityId(sensor.termostaatti_ylavessa_local_temperature)>} with default value 'default' and Template("{{ value_json.local_temperature }}")
2023-02-13 17:05:56.466 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'switch.termostaatti_ylavessa_away_mode', 'name': 'Termostaatti YlÀvessa away_mode', 'this': <template TemplateStateFromEntityId(switch.termostaatti_ylavessa_away_mode)>} and Template("{{ value_json.away_mode }}")
2023-02-13 17:05:56.467 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'switch.termostaatti_ylavessa_child_lock', 'name': 'Termostaatti YlÀvessa child_lock', 'this': <template TemplateStateFromEntityId(switch.termostaatti_ylavessa_child_lock)>} and Template("{{ value_json.child_lock }}")
2023-02-13 17:05:56.467 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'number.termostaatti_ylavessa_local_temperature_calibration', 'name': 'Termostaatti YlÀvessa local temperature calibration', 'this': <template TemplateStateFromEntityId(number.termostaatti_ylavessa_local_temperature_calibration)>} and Template("{{ value_json.local_temperature_calibration }}")
2023-02-13 17:05:56.467 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'number.termostaatti_ylavessa_floor_sensor_calibration', 'name': 'Termostaatti YlÀvessa floor sensor calibration', 'this': <template TemplateStateFromEntityId(number.termostaatti_ylavessa_floor_sensor_calibration)>} and Template("{{ value_json.floor_sensor_calibration }}")
2023-02-13 17:05:56.467 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'number.termostaatti_ylavessa_dry_time', 'name': 'Termostaatti YlÀvessa dry time', 'this': <template TemplateStateFromEntityId(number.termostaatti_ylavessa_dry_time)>} and Template("{{ value_json.dry_time }}")
2023-02-13 17:05:56.467 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'number.termostaatti_ylavessa_window_open_check', 'name': 'Termostaatti YlÀvessa window open check', 'this': <template TemplateStateFromEntityId(number.termostaatti_ylavessa_window_open_check)>} and Template("{{ value_json.window_open_check }}")
2023-02-13 17:05:56.467 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'number.termostaatti_ylavessa_hysterersis', 'name': 'Termostaatti YlÀvessa hysterersis', 'this': <template TemplateStateFromEntityId(number.termostaatti_ylavessa_hysterersis)>} and Template("{{ value_json.hysterersis }}")
2023-02-13 17:05:56.468 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'climate.termostaatti_ylavessa', 'name': 'Termostaatti YlÀvessa', 'this': <template TemplateStateFromEntityId(climate.termostaatti_ylavessa)>} and Template("{% set values = {None:None,'idle':'off','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json.running_state] }}")
2023-02-13 17:05:56.468 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'number.termostaatti_ylavessa_alarm_airtemp_overvalue', 'name': 'Termostaatti YlÀvessa alarm airtemp overvalue', 'this': <template TemplateStateFromEntityId(number.termostaatti_ylavessa_alarm_airtemp_overvalue)>} and Template("{{ value_json.alarm_airtemp_overvalue }}")
2023-02-13 17:05:56.468 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'climate.termostaatti_ylavessa', 'name': 'Termostaatti YlÀvessa', 'this': <template TemplateStateFromEntityId(climate.termostaatti_ylavessa)>} and Template("{{ value_json.local_temperature }}")
2023-02-13 17:05:56.468 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'climate.termostaatti_ylavessa', 'name': 'Termostaatti YlÀvessa', 'this': <template TemplateStateFromEntityId(climate.termostaatti_ylavessa)>} and Template("{{ value_json.occupied_heating_setpoint }}")
2023-02-13 17:05:56.468 DEBUG (MainThread) [homeassistant.components.mqtt.models] Rendering incoming payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":24.1,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":123,"local_temperature":25.13,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":true,"occupied_heating_setpoint":17,"outdoor_temperature":19.61,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":15,"voltage":0,"window_open_check":0}' with variables {'entity_id': 'climate.termostaatti_ylavessa', 'name': 'Termostaatti YlÀvessa', 'this': <template TemplateStateFromEntityId(climate.termostaatti_ylavessa)>} and Template("{{ value_json.system_mode }}")
2023-02-13 17:05:56.468 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=switch.termostaatti_ylavessa_away_mode, old_state=<state switch.termostaatti_ylavessa_away_mode=off; friendly_name=Termostaatti YlÀvessa away_mode @ 2023-02-13T15:17:03.718760+02:00>, new_state=<state switch.termostaatti_ylavessa_away_mode=on; friendly_name=Termostaatti YlÀvessa away_mode @ 2023-02-13T17:05:56.468698+02:00>>
2023-02-13 17:05:56.469 DEBUG (Recorder) [homeassistant.components.recorder.core] Processing task: EventTask(event=<Event state_changed[L]: entity_id=switch.termostaatti_ylavessa_away_mode, old_state=<state switch.termostaatti_ylavessa_away_mode=off; friendly_name=Termostaatti YlÀvessa away_mode @ 2023-02-13T15:17:03.718760+02:00>, new_state=<state switch.termostaatti_ylavessa_away_mode=on; friendly_name=Termostaatti YlÀvessa away_mode @ 2023-02-13T17:05:56.468698+02:00>>)
2023-02-13 17:05:56.469 DEBUG (MainThread) [homeassistant.components.google_assistant.report_state] Scheduling report state for switch.termostaatti_ylavessa_away_mode: {'online': True, 'on': True}

Also Z2M logs look like this when away mode turns on:

Debug 2023-02-02 10:15:12Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'hvacThermostat', data '{"occupancy":0}' from endpoint 1 with groupID 0
Info 2023-02-02 10:15:12MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"OFF","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":20.2,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":98,"local_temperature":23.81,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":17.19,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":20,"voltage":0,"window_open_check":0}'
Debug 2023-02-02 10:15:12Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'hvacThermostat', data '{"8194":1}' from endpoint 1 with groupID 0
Info 2023-02-02 10:15:12MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":20.2,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":98,"local_temperature":23.81,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":17.19,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":20,"voltage":0,"window_open_check":0}'
Debug 2023-02-02 10:15:14Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'hvacThermostat', data '{"runningState":1}' from endpoint 1 with groupID 0
Info 2023-02-02 10:15:14MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":45,"energy":20.2,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":87,"local_temperature":23.81,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":17.19,"power":0,"powerup_status":"last_status","running_state":"heat","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":20,"voltage":0,"window_open_check":0}'
Debug 2023-02-02 10:15:14Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'haElectricalMeasurement', data '{"activePower":72,"rmsCurrent":337,"rmsVoltage":2360}' from endpoint 1 with groupID 0
Info 2023-02-02 10:15:14MQTT publish: topic 'zigbee2mqtt/Termostaatti YlÀvessa', payload '{"alarm_airtemp_overvalue":32,"away_mode":"ON","button_vibration_level":"low","child_lock":"UNLOCK","current":0.34,"display_auto_off_enabled":"disabled","dry_time":45,"energy":20.2,"floor_sensor_calibration":0,"floor_sensor_type":"15k","hysterersis":0.5,"lcd_brightness":"mid","linkquality":94,"local_temperature":23.81,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":17,"outdoor_temperature":17.19,"power":72,"powerup_status":"last_status","running_state":"heat","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":20,"voltage":236,"window_open_check":0}'

Tried also removing this line from Z2M Reporting, but it didn't have any effect.

Screenshot 2023-02-13 at 20 53 31
Koenkk commented 1 year ago

Debug 2023-02-02 10:15:12Received Zigbee message from 'Termostaatti YlÀvessa', type 'attributeReport', cluster 'hvacThermostat', data '{"8194":1}' from endpoint 1 with groupID 0

Received zigbee message means it comes from the device, so this looks like some beaviour inside the firmware, does it also happen with the original hub?

pitkaha commented 1 year ago

Okay thanks @Koenkk . Thermostats don't have a hub. The seller said that they have tested these with ZHA with no problems. Don't have a second coordinator so can't really test that either, but getting a second one to test is on the list.

Still even if its coming from the thermostat the other ones seem to mirror the change so there is some kind of communication They are around the house, one in a metal breaker box and they still go to away mode at the same time.

Is it possible to just disable communications that include away mode and occupancy? Would at least see where its coming from. Tried it with powering thermostats off one by one but didn't get anything meaningful out of it, but still.

Seems like 8194 of the away mode has been little problematic before. https://github.com/zigpy/zha-device-handlers/issues/1341

Koenkk commented 1 year ago

They are around the house, one in a metal breaker box and they still go to away mode at the same time

That's strange (you are expecting that it has no signal right?). Received zigbee message indicates that something has been received from the device so I'm quite sure it is still sending messages.

pitkaha commented 1 year ago

They are around the house, one in a metal breaker box and they still go to away mode at the same time

That's strange (you are expecting that it has no signal right?). Received zigbee message indicates that something has been received from the device so I'm quite sure it is still sending messages.

No it has a good signal, I mean more like it cannot be sensing occupancy by itself, but as far as I know it doesn't have a motion sensor or anything.

I've been wondering could the thermostats somehow look for occupancy from motion sensors in some of the rooms, but that would be weird as they don't share any automations or anything.

Also ordered a second sonoff adapter to test these on ZHA.

chrizmania commented 1 year ago

hi @pitkaha !
I am very curious if you have already tried whether the ROB_200-040-0 thermostat works with ZHA.

pitkaha commented 1 year ago

hi @pitkaha ! I am very curious if you have already tried whether the ROB_200-040-0 thermostat works with ZHA.

Just got second coordinator up and running yesterday. It works, but the integration with ZHA is really basic and limiting vs Z2M. Thankfully it stays out of away mode which was the biggest problem for me with Z2M.

ZHA doesn't recognise outdoor temperature, the one coming from external sensor, or at least I haven't got it to work. This is pretty big flaw for me at least.

So would stay on Z2M if possible.

Here are the entities visible:

ZHA

Screenshot 2023-03-01 at 11 09 27

Z2M

Screenshot 2023-03-01 at 11 10 24
chrizmania commented 1 year ago

Thanks @pitkaha, That's quite a difference indeed. Thanks for finding out! But sounds like workable for my situation with ZHA and Conbee II stick. Just want the thermostat to act on the floor temperature from sensor instead of ambient temperature. I doubt between this ROB_200-040-0 thermostat and a simple manual Thermostat controlled by a shelly 1PM.

pitkaha commented 1 year ago

Thanks @pitkaha, That's quite a difference indeed. Thanks for finding out! But sounds like workable for my situation with ZHA and Conbee II stick. Just want the thermostat to act on the floor temperature from sensor instead of ambient temperature. I doubt between this ROB_200-040-0 thermostat and a simple manual Thermostat controlled by a shelly 1PM.

Hmm at least for me ZHA doesn't give temperature from the floor sensor at all. Z2M does, sensor.***_outdoor_temperature, but haven't found a way to get it show on HA's virtual thermostats. I suppose it is doable, haven't gotten to it yet, it is usable as an entity at least. There is a temperature addon for 1PM, that should work as well.

ruant commented 1 year ago

I'm having the exact same issue with 3 of these https://www.zigbee2mqtt.io/devices/4512737_4512738.html

I also get these messages in the log when the away_mode activates.

debug 2023-03-22 22:12:17: Received Zigbee message from 'Thermostat - Basement - Hallway', type 'attributeReport', cluster 'hvacThermostat', data '{"occupancy":0}' from endpoint 1 with groupID null
info  2023-03-22 22:12:17: MQTT publish: topic 'zigbee2mqtt/Thermostat - Basement - Hallway', payload '{"alarm_airtemp_overvalue":27,"away_mode":"OFF","button_vibration_level":"off","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":5,"energy":73.4,"floor_sensor_calibration":0,"floor_sensor_type":"10k","hysterersis":0.5,"last_seen":"2023-03-22T21:12:17.558Z","lcd_brightness":"mid","linkquality":95,"local_temperature":20.77,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":23,"outdoor_temperature":22.65,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":7,"update":{"installed_version":18,"latest_version":18,"state":"idle"},"update_available":false,"voltage":0,"window_open_check":1.5}'
debug 2023-03-22 22:12:17: Received Zigbee message from 'Thermostat - Basement - Hallway', type 'attributeReport', cluster 'hvacThermostat', data '{"8194":1}' from endpoint 1 with groupID null
info  2023-03-22 22:12:17: MQTT publish: topic 'zigbee2mqtt/Thermostat - Basement - Hallway', payload '{"alarm_airtemp_overvalue":27,"away_mode":"ON","button_vibration_level":"off","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":5,"energy":73.4,"floor_sensor_calibration":0,"floor_sensor_type":"10k","hysterersis":0.5,"last_seen":"2023-03-22T21:12:17.629Z","lcd_brightness":"mid","linkquality":87,"local_temperature":20.77,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":23,"outdoor_temperature":22.65,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":7,"update":{"installed_version":18,"latest_version":18,"state":"idle"},"update_available":false,"voltage":0,"window_open_check":1.5}'

They all go into away_mode at the same time too, so this has to be something with z2m?..

Has anyone been able to figure out the issue?

ruant commented 1 year ago

I'm not familiar with how z2m actually works and how specific the "code" can be per device, but maybe this could shed some light on the issue?

Since Zigbee does not have away mode, the attribute Occupancy (occupied or unoccupied) of Thermostat (0x0201)
and attribute Occupancy of received OccupancySensing (0x0406) are required to judge whether it is away mode.
1) if the device receives other devices’ or the gateway’s report: the Bit 0 of the value of attribute Occupancy (0x0000) of
OccupancySensing Cluster (0x0406) is 1, which means occupied, then the operation mode of the thermostat, the
attribute SystemMode(0x001c)=0x04(heat) of Thermostat (0x0201), meanwhile the value of attribute Occupancy
(0x0002) of Thermostat (0x0201) is 0. It means the Away Mode is activated, and the thermostat UI will display.
2) if the gateway send command to modify the attribute SystemMode(0x001c) of Thermostat (0x0201), the thermostat
will quit Away Mode. Meanwhile the value of attribute Occupancy (0x0002) of Thermostat (0x0201) is 1.
3) The proprietary attribute 0x2002(Manufacturer Code=0x1224) of the cluster 0x0201 can be modified to configure
whether it is away mode or at home.
Note: Away Mode uses attribute UnOccupiedHeatingSetpoint to set temperature.
Other modes uses attribute OccupiedHeatingSetpoint to set temperature

Found that in the manual: https://www.elektroimportoren.no/docs/lib/4512737-Brukerveiledning-5.pdf

pitkaha commented 1 year ago

I'm having the exact same issue with 3 of these https://www.zigbee2mqtt.io/devices/4512737_4512738.html

I also get these messages in the log when the away_mode activates.

debug 2023-03-22 22:12:17: Received Zigbee message from 'Thermostat - Basement - Hallway', type 'attributeReport', cluster 'hvacThermostat', data '{"occupancy":0}' from endpoint 1 with groupID null
info  2023-03-22 22:12:17: MQTT publish: topic 'zigbee2mqtt/Thermostat - Basement - Hallway', payload '{"alarm_airtemp_overvalue":27,"away_mode":"OFF","button_vibration_level":"off","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":5,"energy":73.4,"floor_sensor_calibration":0,"floor_sensor_type":"10k","hysterersis":0.5,"last_seen":"2023-03-22T21:12:17.558Z","lcd_brightness":"mid","linkquality":95,"local_temperature":20.77,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":23,"outdoor_temperature":22.65,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":7,"update":{"installed_version":18,"latest_version":18,"state":"idle"},"update_available":false,"voltage":0,"window_open_check":1.5}'
debug 2023-03-22 22:12:17: Received Zigbee message from 'Thermostat - Basement - Hallway', type 'attributeReport', cluster 'hvacThermostat', data '{"8194":1}' from endpoint 1 with groupID null
info  2023-03-22 22:12:17: MQTT publish: topic 'zigbee2mqtt/Thermostat - Basement - Hallway', payload '{"alarm_airtemp_overvalue":27,"away_mode":"ON","button_vibration_level":"off","child_lock":"UNLOCK","current":0,"display_auto_off_enabled":"disabled","dry_time":5,"energy":73.4,"floor_sensor_calibration":0,"floor_sensor_type":"10k","hysterersis":0.5,"last_seen":"2023-03-22T21:12:17.629Z","lcd_brightness":"mid","linkquality":87,"local_temperature":20.77,"local_temperature_calibration":0,"mode_after_dry":"manual","occupancy":false,"occupied_heating_setpoint":23,"outdoor_temperature":22.65,"power":0,"powerup_status":"last_status","running_state":"idle","sensor":"floor","system_mode":"heat","temperature_display":"floor","unoccupied_heating_setpoint":7,"update":{"installed_version":18,"latest_version":18,"state":"idle"},"update_available":false,"voltage":0,"window_open_check":1.5}'

They all go into away_mode at the same time too, so this has to be something with z2m?..

Has anyone been able to figure out the issue?

I couldn't figure it out, the logs from the time it happens are in a message above. All three at the same time. Bought a second coordinator to run on ZHA with the thermostats. No problems with away mode any more, so I would think its something to do with Z2M as well. Sadly ZHA is pretty limited, so if you find a solution please let me know.

pitkaha commented 1 year ago

I'm not familiar with how z2m actually works and how specific the "code" can be per device, but maybe this could shed some light on the issue?

Since Zigbee does not have away mode, the attribute Occupancy (occupied or unoccupied) of Thermostat (0x0201)
and attribute Occupancy of received OccupancySensing (0x0406) are required to judge whether it is away mode.
1) if the device receives other devices’ or the gateway’s report: the Bit 0 of the value of attribute Occupancy (0x0000) of
OccupancySensing Cluster (0x0406) is 1, which means occupied, then the operation mode of the thermostat, the
attribute SystemMode(0x001c)=0x04(heat) of Thermostat (0x0201), meanwhile the value of attribute Occupancy
(0x0002) of Thermostat (0x0201) is 0. It means the Away Mode is activated, and the thermostat UI will display.
2) if the gateway send command to modify the attribute SystemMode(0x001c) of Thermostat (0x0201), the thermostat
will quit Away Mode. Meanwhile the value of attribute Occupancy (0x0002) of Thermostat (0x0201) is 1.
3) The proprietary attribute 0x2002(Manufacturer Code=0x1224) of the cluster 0x0201 can be modified to configure
whether it is away mode or at home.
Note: Away Mode uses attribute UnOccupiedHeatingSetpoint to set temperature.
Other modes uses attribute OccupiedHeatingSetpoint to set temperature

Found that in the manual: https://www.elektroimportoren.no/docs/lib/4512737-Brukerveiledning-5.pdf

Pretty similar stuff in ZG9092A manual as well: https://github.com/zigpy/zha-device-handlers/issues/1341

ruant commented 1 year ago

@pitkaha What would be interesting to check is if you have any occupancy sensors in your ZHA network? If the thermostat some how picks up random zigbee unit states from the network and uses that?

Did you have any on z2m while having the away mode issue? If so, maybe try to move those over to ZHA too, and test if the away mode issue starts up again.

Since point 1 from the docs points to this...

1) `if the device receives other devices’ or the gateway’s report: the Bit 0 of the value of attribute Occupancy (0x0000) of OccupancySensing Cluster (0x0406) is 1, which means occupied, then the operation mode of the thermostat, the attribute SystemMode(0x001c)=0x04(heat) of Thermostat (0x0201), meanwhile the value of attribute Occupancy (0x0002) of Thermostat (0x0201) is 0. It means the Away Mode is activated, and the thermostat UI will display.

pitkaha commented 1 year ago

@pitkaha What would be interesting to check is if you have any occupancy sensors in your ZHA network? If the thermostat some how picks up random zigbee unit states from the network and uses that?

Did you have any on z2m while having the away mode issue? If so, maybe try to move those over to ZHA too, and test if the away mode issue starts up again.

Since point 1 from the docs points to this...

  1. `if the device receives other devices’ or the gateway’s report: the Bit 0 of the value of attribute Occupancy (0x0000) of OccupancySensing Cluster (0x0406) is 1, which means occupied, then the operation mode of the thermostat, the attribute SystemMode(0x001c)=0x04(heat) of Thermostat (0x0201), meanwhile the value of attribute Occupancy (0x0002) of Thermostat (0x0201) is 0. It means the Away Mode is activated, and the thermostat UI will display.

I have six motion sensors on Z2M when having the issue. Thought about the same, tried to find corresponding changes in occupancy from logs but couldn't find anything matching, but it is possible that I missed it as well, bit out of my skill level. On ZHA there is only those three thermostats, no problems so far, but ZHA is pretty limited.

ruant commented 1 year ago

@pitkaha Could you test moving one of the motion sensors over into the ZHA driven network? To see if the thermostats start switching into away mode then.

If that is that case, then we would know 100% for sure that the thermostats gets affected by other devices in the network.

ruant commented 1 year ago

I received a new firmware for my Namron Thermostat yesterday over email. I flashed one on my network joined Thermostats, hopefully this fixes the away_mode issue.

Not sure if it's gonna work for other "branded" version of this thermostat product tho.

pitkaha commented 1 year ago

@pitkaha Could you test moving one of the motion sensors over into the ZHA driven network? To see if the thermostats start switching into away mode then.

If that is that case, then we would know 100% for sure that the thermostats gets affected by other devices in the network.

I don't have any motion sensors that would be easily transferable to ZHA, but I have one extra coming next week, I'll throw that on ZHA.

I received a new firmware for my Namron Thermostat yesterday over email. I flashed one on my network joined Thermostats, hopefully this fixes the away_mode issue.

Not sure if it's gonna work for other "branded" version of this thermostat product tho.

Hmm which firmware are you on now and whats the new one?

ruant commented 1 year ago

It said I was on 18, the new one said 22. Did the flashing last night, still haven't had any issues with away_mode yet. đŸ€ž Had to tweak the zigbee2mqtt code a little bit with the new firmware (had to remove a occupancy reporting from being configured)

pitkaha commented 1 year ago

It said I was on 18, the new one said 22. Did the flashing last night, still haven't had any issues with away_mode yet. đŸ€ž Had to tweak the zigbee2mqtt code a little bit with the new firmware (had to remove a occupancy reporting from being configured)

IMG_4877 Do you have 18 and 22 here?

I've had the motion sensor on ZHA for about a day, and away_mode is back. You are still clear of away_mode?

ruant commented 1 year ago

@pitkaha The one I updated is completely fine now. Had to adjust the z2m code a little tho, but that's it.

The one not updated (but in the network) is still triggering away_mode now and then.

The third one I got (not connected to the network) is also fine.

Conclusion: The firmware upgrade works fine. At least for these Namron branded ones. If these will work for other "branded" versions of this Thermostat I don't know. Not sure how the OTA file contains which models it should be applied to or not. But I guess it should be possible to contact the brand you got and ask for them to contact the "upstream" brand (the one actually making the product) and have them send the firmware.

I'll send and email to the person I've talking to and ask if it's OK I add the firmware to OTA repo in z2m. I'll ping you and add the firmware here if I'm allowed to publish it.

Before

image

After

image

pitkaha commented 1 year ago

@ruant Okay, thanks, thats really helpful. The firmware seems to be availble on Namron site https://www.namron.com/products/namron-zigbee-touch-termostat-16a-hvit/ under documentation. Did you update it trough Z2M with local OTA? Can you paste your Z2M config so I can see what modifications you did, as I will hopefully eventually need those as well? I'll contact the manufacturer.

Also if somebody else is wondering how to use the temperature from floor sensor to control the thermostat I found a workaround. https://better-thermostat.org lets you choose any temperature entity to control your virtual thermostat in HA, also totally external temperature sensors work.

ruant commented 1 year ago

Converter: https://github.com/Koenkk/zigbee-herdsman-converters/pull/5681 Firmware: https://github.com/Koenkk/zigbee-OTA/pull/294

pitkaha commented 1 year ago

Hi @Koenkk , mind to take a look?

To recap, with Ruants help it now seems like the problem with away_mode has something to do with devices Zigbee firmware. I tested with second coordinator and ZHA, and as soon as there is motion sensor in the same zigbee network the problem starts to appear. Ruant was able to update the Zigbee firmware of his Namrons from V18.00 to V22.00 which fixed the problem, I'm at V20.00 and manufacturer says its probably not possible to update it.

As the devices are pretty much identical I was thinking about taking a risk with one thermostats and try to push Namrons V22.00 to it. Only thing stopping me is getting OTA to work. Copied Namrons converter, which works just fine if I remove the line with OTA, ota: ota.zigbeeOTA,, with that line in the converter Z2M won't boot. Without the line I get following logs from manual check and update, not surprising really, same with the original converter:

Info 2023-04-29 13:16:47MQTT publish: topic 'zigbee2mqtt/bridge/response/device/ota_update/check', payload '{"data":{"id":"0x1fff000300000068"},"error":"Device '0x1fff000300000068' does not support OTA updates","status":"error"}'
Error 2023-04-29 13:16:47Device '0x1fff000300000068' does not support OTA updates
Info 2023-04-29 13:18:08MQTT publish: topic 'zigbee2mqtt/bridge/response/device/ota_update/update', payload '{"data":{"id":"0x1fff000300000068"},"error":"Device '0x1fff000300000068' does not support OTA updates","status":"error"}'
Error 2023-04-29 13:18:08Device '0x1fff000300000068' does not support OTA updates

I have following in my config: ota: zigbee_ota_override_index_location: my_index.json and my_index.json:

[
    {
        "url": "ROBBV22.ota"
    }
]

, ROBBV22.ota is the update file from Namrons site which is in the same folder, just renamed.

Here is the converter that won't boot with the line about OTA, line 235, works just fine without it.

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 globalStore = require('zigbee-herdsman-converters/lib/store');
const constants = require('zigbee-herdsman-converters/lib/constants');

async function syncTime(endpoint) {
    try {
        const time = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000 + ((new Date()).getTimezoneOffset() * -1) * 60);
        const values = {time: time};
        await endpoint.write('genTime', values);
    } catch (error) {/* Do nothing*/}
}

const definition = {
    zigbeeModel: ['4512737', '4512738', 'HK-LN-HEATER-A'],
    model: '4512737/4512738',
    vendor: 'Namron',
    description: 'Touch termostat',
    fromZigbee: [fz.thermostat, fz.namron_thermostat, fz.metering, fz.electrical_measurement,
        fz.namron_hvac_user_interface],
    toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_occupancy,
        tz.thermostat_local_temperature_calibration, tz.thermostat_local_temperature, tz.thermostat_outdoor_temperature,
        tz.thermostat_system_mode, tz.thermostat_control_sequence_of_operation, tz.thermostat_running_state,
        tz.namron_thermostat_child_lock, tz.namron_thermostat],
    exposes: [
        e.local_temperature(),
        exposes.numeric('outdoor_temperature', ea.STATE_GET).withUnit('°C')
            .withDescription('Current temperature measured from the floor sensor'),
        exposes.climate()
            .withSetpoint('occupied_heating_setpoint', 0, 40, 0.1)
            .withLocalTemperature()
            .withLocalTemperatureCalibration(-3, 3, 0.1)
            .withSystemMode(['off', 'auto', 'dry', 'heat'])
            .withRunningState(['idle', 'heat']),
        exposes.binary('away_mode', ea.ALL, 'ON', 'OFF')
            .withDescription('Enable/disable away mode'),
        exposes.binary('child_lock', ea.ALL, 'LOCK', 'UNLOCK')
            .withDescription('Enables/disables physical input on the device'),
        e.power(), e.current(), e.voltage(), e.energy(),
        exposes.enum('lcd_brightness', ea.ALL, ['low', 'mid', 'high'])
            .withDescription('OLED brightness when operating the buttons.  Default: Medium.'),
        exposes.enum('button_vibration_level', ea.ALL, ['off', 'low', 'high'])
            .withDescription('Key beep volume and vibration level.  Default: Low.'),
        exposes.enum('floor_sensor_type', ea.ALL, ['10k', '15k', '50k', '100k', '12k'])
            .withDescription('Type of the external floor sensor.  Default: NTC 10K/25.'),
        exposes.enum('sensor', ea.ALL, ['air', 'floor', 'both'])
            .withDescription('The sensor used for heat control.  Default: Room Sensor.'),
        exposes.enum('powerup_status', ea.ALL, ['default', 'last_status'])
            .withDescription('The mode after a power reset.  Default: Previous Mode.'),
        exposes.numeric('floor_sensor_calibration', ea.ALL)
            .withUnit('°C')
            .withValueMin(-3).withValueMax(3).withValueStep(0.1)
            .withDescription('The tempearatue calibration for the exernal floor sensor, between -3 and 3 in 0.1°C.  Default: 0.'),
        exposes.numeric('dry_time', ea.ALL)
            .withUnit('min')
            .withValueMin(5).withValueMax(100)
            .withDescription('The duration of Dry Mode, between 5 and 100 minutes.  Default: 5.'),
        exposes.enum('mode_after_dry', ea.ALL, ['off', 'manual', 'auto', 'away'])
            .withDescription('The mode after Dry Mode.  Default: Auto.'),
        exposes.enum('temperature_display', ea.ALL, ['room', 'floor'])
            .withDescription('The temperature on the display.  Default: Room Temperature.'),
        exposes.numeric('window_open_check', ea.ALL)
            .withUnit('°C')
            .withValueMin(1.5).withValueMax(4).withValueStep(0.5)
            .withDescription('The threshold to detect window open, between 1.5 and 4 in 0.5 °C.  Default: 0 (disabled).'),
        exposes.numeric('hysterersis', ea.ALL)
            .withUnit('°C')
            .withValueMin(0.5).withValueMax(5).withValueStep(0.1)
            .withDescription('Hysteresis setting, between 0.5 and 5 in 0.1 °C.  Default: 0.5.'),
        exposes.enum('display_auto_off_enabled', ea.ALL, ['enabled', 'disabled']),
        exposes.numeric('alarm_airtemp_overvalue', ea.ALL)
            .withUnit('°C')
            .withValueMin(0).withValueMax(35)
            .withDescription('Floor temperature over heating threshold, range is 0-35, unit is 1ÂșC, ' +
            '0 means this function is disabled, default value is 27.'),
    ],
    onEvent: async (type, data, device, options) => {
        const endpoint = device.getEndpoint(1);
        if (type === 'stop') {
            clearInterval(globalStore.getValue(device, 'time'));
            globalStore.clearValue(device, 'time');
        } else if (!globalStore.hasValue(device, 'time')) {
            const hours24 = 1000 * 60 * 60 * 24;
            const interval = setInterval(async () => {
                try {
                    // Device does not asks for the time with binding, therefore we write the time every 24 hours
                    const time = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000 + ((new Date())
                        .getTimezoneOffset() * -1) * 60);
                    const values = {time: time};
                    await endpoint.write('genTime', values);
                } catch (error) {/* Do nothing*/}
            }, hours24);
            globalStore.putValue(device, 'time', interval);
        }
    },
    configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        const binds = [
            'genBasic', 'genIdentify', 'hvacThermostat', 'seMetering', 'haElectricalMeasurement', 'genAlarms',
            'msOccupancySensing', 'genTime', 'hvacUserInterfaceCfg',
        ];
        await reporting.bind(endpoint, coordinatorEndpoint, binds);

        // standard ZCL attributes
        await reporting.thermostatTemperature(endpoint, {min: 0, change: 50});
        await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
        await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
        await reporting.thermostatKeypadLockMode(endpoint);

        // Metering
        await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier']);
        await endpoint.read('haElectricalMeasurement', ['acCurrentDivisor']);
        await reporting.rmsVoltage(endpoint, {min: 10, change: 20}); // Voltage - Min change of 2v
        await reporting.rmsCurrent(endpoint, {min: 10, change: 10}); // A - z2m displays only the first decimals, so change of 10 (0,01)
        await reporting.activePower(endpoint, {min: 10, change: 15}); // W - Min change of 1,5W
        await reporting.currentSummDelivered(endpoint, {min: 300}); // Report KWH every 5min
        await reporting.readMeteringMultiplierDivisor(endpoint);

        // Custom attributes
        const options = {manufacturerCode: 0x1224};

        // OperateDisplayLcdBrightnesss
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1000, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // ButtonVibrationLevel
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1001, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // FloorSensorType
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1002, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // ControlType
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1003, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // PowerUpStatus
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1004, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // FloorSensorCalibration
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1005, type: 0x28},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // DryTime
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1006, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // ModeAfterDry
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1007, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // TemperatureDisplay
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1008, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // WindowOpenCheck
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1009, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);

        // Hysterersis
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x100A, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // DisplayAutoOffEnable
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x100B, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);

        // AlarmAirTempOverValue
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x2001, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // Away Mode Set
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x2002, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);

        // Trigger initial read
        await endpoint.read('hvacThermostat', ['systemMode', 'runningState', 'occupiedHeatingSetpoint']);
        await endpoint.read('hvacThermostat', [0x1000, 0x1001, 0x1002, 0x1003], options);
        await endpoint.read('hvacThermostat', [0x1004, 0x1005, 0x1006, 0x1007], options);
        await endpoint.read('hvacThermostat', [0x1008, 0x1009, 0x100A, 0x100B], options);
        await endpoint.read('hvacThermostat', [0x2001, 0x2002], options);
    },
    ota: ota.zigbeeOTA,
};

module.exports = definition;

Is the idea just impossible or what am I doing wrong with the converter? Any workarounds?

EDIT:

Tried to change the first rows of the converter to the same ones as Namrons converter, still Z2M won't boot.

const herdsman = require('zigbee-herdsman');
const exposes = require('../lib/exposes');
const fz = require('../converters/fromZigbee');
const tz = require('../converters/toZigbee');
const constants = require('../lib/constants');
const reporting = require('../lib/reporting');
const globalStore = require('../lib/store');
const ota = require('../lib/ota');
const utils = require('../lib/utils');
const extend = require('../lib/extend');
const ea = exposes.access;
const e = exposes.presets;

async function syncTime(endpoint) {
    try {
        const time = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000 + ((new Date()).getTimezoneOffset() * -1) * 60);
        const values = {time: time};
        await endpoint.write('genTime', values);
    } catch (error) {/* Do nothing*/}
}

const definition = {
    zigbeeModel: ['4512737', '4512738', 'HK-LN-HEATER-A'],
    model: '4512737/4512738',
    vendor: 'Namron',
    description: 'Touch termostat',
    fromZigbee: [fz.thermostat, fz.namron_thermostat, fz.metering, fz.electrical_measurement,
        fz.namron_hvac_user_interface],
    toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_occupancy,
        tz.thermostat_local_temperature_calibration, tz.thermostat_local_temperature, tz.thermostat_outdoor_temperature,
        tz.thermostat_system_mode, tz.thermostat_control_sequence_of_operation, tz.thermostat_running_state,
        tz.namron_thermostat_child_lock, tz.namron_thermostat],
    exposes: [
        e.local_temperature(),
        exposes.numeric('outdoor_temperature', ea.STATE_GET).withUnit('°C')
            .withDescription('Current temperature measured from the floor sensor'),
        exposes.climate()
            .withSetpoint('occupied_heating_setpoint', 0, 40, 0.1)
            .withLocalTemperature()
            .withLocalTemperatureCalibration(-3, 3, 0.1)
            .withSystemMode(['off', 'auto', 'dry', 'heat'])
            .withRunningState(['idle', 'heat']),
        exposes.binary('away_mode', ea.ALL, 'ON', 'OFF')
            .withDescription('Enable/disable away mode'),
        exposes.binary('child_lock', ea.ALL, 'LOCK', 'UNLOCK')
            .withDescription('Enables/disables physical input on the device'),
        e.power(), e.current(), e.voltage(), e.energy(),
        exposes.enum('lcd_brightness', ea.ALL, ['low', 'mid', 'high'])
            .withDescription('OLED brightness when operating the buttons.  Default: Medium.'),
        exposes.enum('button_vibration_level', ea.ALL, ['off', 'low', 'high'])
            .withDescription('Key beep volume and vibration level.  Default: Low.'),
        exposes.enum('floor_sensor_type', ea.ALL, ['10k', '15k', '50k', '100k', '12k'])
            .withDescription('Type of the external floor sensor.  Default: NTC 10K/25.'),
        exposes.enum('sensor', ea.ALL, ['air', 'floor', 'both'])
            .withDescription('The sensor used for heat control.  Default: Room Sensor.'),
        exposes.enum('powerup_status', ea.ALL, ['default', 'last_status'])
            .withDescription('The mode after a power reset.  Default: Previous Mode.'),
        exposes.numeric('floor_sensor_calibration', ea.ALL)
            .withUnit('°C')
            .withValueMin(-3).withValueMax(3).withValueStep(0.1)
            .withDescription('The tempearatue calibration for the exernal floor sensor, between -3 and 3 in 0.1°C.  Default: 0.'),
        exposes.numeric('dry_time', ea.ALL)
            .withUnit('min')
            .withValueMin(5).withValueMax(100)
            .withDescription('The duration of Dry Mode, between 5 and 100 minutes.  Default: 5.'),
        exposes.enum('mode_after_dry', ea.ALL, ['off', 'manual', 'auto', 'away'])
            .withDescription('The mode after Dry Mode.  Default: Auto.'),
        exposes.enum('temperature_display', ea.ALL, ['room', 'floor'])
            .withDescription('The temperature on the display.  Default: Room Temperature.'),
        exposes.numeric('window_open_check', ea.ALL)
            .withUnit('°C')
            .withValueMin(1.5).withValueMax(4).withValueStep(0.5)
            .withDescription('The threshold to detect window open, between 1.5 and 4 in 0.5 °C.  Default: 0 (disabled).'),
        exposes.numeric('hysterersis', ea.ALL)
            .withUnit('°C')
            .withValueMin(0.5).withValueMax(5).withValueStep(0.1)
            .withDescription('Hysteresis setting, between 0.5 and 5 in 0.1 °C.  Default: 0.5.'),
        exposes.enum('display_auto_off_enabled', ea.ALL, ['enabled', 'disabled']),
        exposes.numeric('alarm_airtemp_overvalue', ea.ALL)
            .withUnit('°C')
            .withValueMin(0).withValueMax(35)
            .withDescription('Floor temperature over heating threshold, range is 0-35, unit is 1ÂșC, ' +
            '0 means this function is disabled, default value is 27.'),
    ],
    onEvent: async (type, data, device, options) => {
        const endpoint = device.getEndpoint(1);
        if (type === 'stop') {
            clearInterval(globalStore.getValue(device, 'time'));
            globalStore.clearValue(device, 'time');
        } else if (!globalStore.hasValue(device, 'time')) {
            const hours24 = 1000 * 60 * 60 * 24;
            const interval = setInterval(async () => {
                try {
                    // Device does not asks for the time with binding, therefore we write the time every 24 hours
                    const time = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000 + ((new Date())
                        .getTimezoneOffset() * -1) * 60);
                    const values = {time: time};
                    await endpoint.write('genTime', values);
                } catch (error) {/* Do nothing*/}
            }, hours24);
            globalStore.putValue(device, 'time', interval);
        }
    },
    configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        const binds = [
            'genBasic', 'genIdentify', 'hvacThermostat', 'seMetering', 'haElectricalMeasurement', 'genAlarms',
            'msOccupancySensing', 'genTime', 'hvacUserInterfaceCfg',
        ];
        await reporting.bind(endpoint, coordinatorEndpoint, binds);

        // standard ZCL attributes
        await reporting.thermostatTemperature(endpoint, {min: 0, change: 50});
        await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
        await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
        await reporting.thermostatKeypadLockMode(endpoint);

        // Metering
        await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier']);
        await endpoint.read('haElectricalMeasurement', ['acCurrentDivisor']);
        await reporting.rmsVoltage(endpoint, {min: 10, change: 20}); // Voltage - Min change of 2v
        await reporting.rmsCurrent(endpoint, {min: 10, change: 10}); // A - z2m displays only the first decimals, so change of 10 (0,01)
        await reporting.activePower(endpoint, {min: 10, change: 15}); // W - Min change of 1,5W
        await reporting.currentSummDelivered(endpoint, {min: 300}); // Report KWH every 5min
        await reporting.readMeteringMultiplierDivisor(endpoint);

        // Custom attributes
        const options = {manufacturerCode: 0x1224};

        // OperateDisplayLcdBrightnesss
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1000, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // ButtonVibrationLevel
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1001, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // FloorSensorType
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1002, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // ControlType
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1003, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // PowerUpStatus
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1004, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // FloorSensorCalibration
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1005, type: 0x28},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // DryTime
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1006, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // ModeAfterDry
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1007, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // TemperatureDisplay
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1008, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);
        // WindowOpenCheck
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x1009, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);

        // Hysterersis
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x100A, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // DisplayAutoOffEnable
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x100B, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);

        // AlarmAirTempOverValue
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x2001, type: 0x20},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: 0}],
        options);
        // Away Mode Set
        await endpoint.configureReporting('hvacThermostat', [{
            attribute: {ID: 0x2002, type: 0x30},
            minimumReportInterval: 0,
            maximumReportInterval: constants.repInterval.HOUR,
            reportableChange: null}],
        options);

        // Trigger initial read
        await endpoint.read('hvacThermostat', ['systemMode', 'runningState', 'occupiedHeatingSetpoint']);
        await endpoint.read('hvacThermostat', [0x1000, 0x1001, 0x1002, 0x1003], options);
        await endpoint.read('hvacThermostat', [0x1004, 0x1005, 0x1006, 0x1007], options);
        await endpoint.read('hvacThermostat', [0x1008, 0x1009, 0x100A, 0x100B], options);
        await endpoint.read('hvacThermostat', [0x2001, 0x2002], options);
    },
    ota: ota.zigbeeOTA,
};

module.exports = definition;
Koenkk commented 1 year ago

Device '0x1fff000300000068' does not support OTA updates

This means the device does not have an OTA endpoint (indicating that it doesn't support OTA updates). What you can try is to manually add the OTA point in the z2m data/database.db file. To do this, stop z2m, add 25 to outClusterList of this device in data/database.db, start z2m.

This of course does not add the OTA endpoint to the device itself, but it is worth a try.

pitkaha commented 1 year ago

Device '0x1fff000300000068' does not support OTA updates

This means the device does not have an OTA endpoint (indicating that it doesn't support OTA updates). What you can try is to manually add the OTA point in the z2m data/database.db file. To do this, stop z2m, add 25 to outClusterList of this device in data/database.db, start z2m.

This of course does not add the OTA endpoint to the device itself, but it is worth a try.

Thanks. Added the 25, with

{"id":72,"type":"Router","ieeeAddr":"0x1fff000300000068","nwkAddr":49544,"manufId":4644,"manufName":"Sunricher","powerSource":"Mains (single phase)","modelId":"HK-LN-HEATER-A","epList":[1,2,242],"endpoints":{"1":{"profId":260,"epId":1,"devId":769,"inClusterList":[0,3,4,5,9,10,513,516,1794,2820],"outClusterList":[25,1030],"clusters":{"genBasic":{"attributes":{"modelId":"HK-LN-HEATER-A","manufacturerName":"Sunricher","powerSource":1,"zclVersion":3,"appVersion":20,"stackVersion":0,"hwVersion":1,"dateCode":"NULL","swBuildId":"6.9.1.0_r4"}},"haElectricalMeasurement":{"attributes":{"4096":16,"acVoltageMultiplier":1,"acVoltageDivisor":10,"acCurrentMultiplier":1,"acCurrentDivisor":1000,"rmsVoltage":0,"activePower":0,"rmsCurrent":0,"acCurrentOverload":16000}},"seMetering":{"attributes":{"multiplier":1,"divisor":10,"currentSummDelivered":[0,0]}},"hvacThermostat":{"attributes":{"4096":1,"4097":1,"4098":1,"4099":0,"4100":1,"4101":0,"4102":5,"4103":2,"4104":0,"4105":0,"4106":5,"4107":0,"8193":27,"8194":0,"localTemp":1775,"systemMode":4,"runningState":0,"occupiedHeatingSetpoint":1400,"occupancy":1,"unoccupiedHeatingSetpoint":600,"outdoorTemp":0,"localTemperatureCalibration":0}},"hvacUserInterfaceCfg":{"attributes":{"keypadLockout":0,"tempDisplayMode":0}}},"binds":[{"cluster":0,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1},{"cluster":3,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1},{"cluster":513,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1},{"cluster":1794,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1},{"cluster":2820,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1},{"cluster":9,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1},{"cluster":1030,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1},{"cluster":10,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1},{"cluster":516,"type":"endpoint","deviceIeeeAddress":"0x00124b0029dae7b3","endpointID":1}],"configuredReportings":[{"cluster":513,"attrId":2,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":0,"minRepIntval":0,"maxRepIntval":3600,"repChange":50},{"cluster":513,"attrId":18,"minRepIntval":0,"maxRepIntval":3600,"repChange":10},{"cluster":513,"attrId":20,"minRepIntval":0,"maxRepIntval":3600,"repChange":10},{"cluster":516,"attrId":1,"minRepIntval":10,"maxRepIntval":3600,"repChange":null},{"cluster":2820,"attrId":1285,"minRepIntval":10,"maxRepIntval":3600,"repChange":20},{"cluster":2820,"attrId":1288,"minRepIntval":10,"maxRepIntval":3600,"repChange":10},{"cluster":2820,"attrId":1291,"minRepIntval":10,"maxRepIntval":3600,"repChange":15},{"cluster":1794,"attrId":0,"minRepIntval":300,"maxRepIntval":3600,"repChange":[1,1]},{"cluster":513,"attrId":4096,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":4097,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":4098,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":4099,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":4100,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":4101,"minRepIntval":0,"maxRepIntval":3600,"repChange":0},{"cluster":513,"attrId":4102,"minRepIntval":0,"maxRepIntval":3600,"repChange":0},{"cluster":513,"attrId":4103,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":4104,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":4105,"minRepIntval":0,"maxRepIntval":3600,"repChange":0},{"cluster":513,"attrId":4106,"minRepIntval":0,"maxRepIntval":3600,"repChange":0},{"cluster":513,"attrId":4107,"minRepIntval":0,"maxRepIntval":3600,"repChange":null},{"cluster":513,"attrId":8193,"minRepIntval":0,"maxRepIntval":3600,"repChange":0},{"cluster":513,"attrId":8194,"minRepIntval":0,"maxRepIntval":3600,"repChange":null}],"meta":{}},"2":{"profId":260,"epId":2,"devId":7,"inClusterList":[0,3],"outClusterList":[3,25],"clusters":{"genBasic":{"attributes":{"stackVersion":0}}},"binds":[],"configuredReportings":[],"meta":{}},"242":{"profId":41440,"epId":242,"devId":97,"inClusterList":[],"outClusterList":[33],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":20,"stackVersion":0,"hwVersion":1,"dateCode":"NULL","swBuildId":"6.9.1.0_r4","zclVersion":3,"interviewCompleted":true,"meta":{"configured":1860275025},"lastSeen":1682841548949,"defaultSendRequestWhen":"immediate"}

Z2M boots nicely, but still gives

Info 2023-04-30 11:51:45MQTT publish: topic 'zigbee2mqtt/bridge/response/device/ota_update/update', payload '{"data":{"id":"0x1fff000300000068"},"error":"Device '0x1fff000300000068' does not support OTA updates","status":"error"}'
Error 2023-04-30 11:51:45Device '0x1fff000300000068' does not support OTA updates

with both check and update.

Adding either or both OTA-lines (ota: ota.zigbeeOTA, and/or const ota = require('../lib/ota');) to converter still keeps Z2M from booting.

Any tips or tricks to force the update or is it possible that the device is just not updateable?

EDIT: Also noticed that someone had added HK-LN-HEATER-A to Sunricher SR-ZG9092A converter, so tested without external converter. Thermostat is configured as ZG9092A and seems to work fine, update still gives the same error, even with 25 in outClusterList.

Koenkk commented 1 year ago

Adding either or both OTA-lines ( ota: ota.zigbeeOTA, and/or const ota = require('../lib/ota');) to converter still keeps Z2M from booting.

Both lines should be present, but you should use onst ota = require('zigbee-herdsman-converters/lib/ota'); instead of onst ota = require('../lib/ota');