Zigbee Thermostat cluster undefined

Hi,

I’m working on an App that connects to a Zigbee thermostat device (Danfoss Ally). I have successfully retrieved the “localTemperature” from the device, but struggling with pairing capabilities.

I’m trying to use the “Thermostat” cluster from “zigbee-clusters” but it is undefined when using it. Do I need to do some sort of initialization or what goes wrong?

The line " console.log(CLUSTER.ThermostatCluster); //Outputs ‘undefined’" shows that the parameter is undefined and the line afterwards therefore fails.

See code below.

Peter

Code (POC):

const { ZigBeeDevice } = require("homey-zigbeedriver");
const { CLUSTER } = require('zigbee-clusters');
const { debug } = require("zigbee-clusters");

// Enable debug logging of all relevant Zigbee communication
debug(true);

class Device extends ZigBeeDevice {

  async onNodeInit({ zclNode }) {

    // Read the "localTemperature" attribute from the "thermostat" cluster
    const currentTemperatureValue = await zclNode.endpoints[1].clusters.thermostat.readAttributes(
      "localTemperature"
    );

    console.log(currentTemperatureValue); //Works fine

    console.log(CLUSTER.ThermostatCluster); //Outputs 'undefined'
    
    this.registerCapability("measure_temperature", CLUSTER.ThermostatCluster, {
      report: 'localTemperature',
      reportParser: value => value / 100,
      get: 'localTemperature',
      getParser: value => value / 100
  });
  }
}

module.exports = Device;
const { ThermostatCluster, CLUSTER } = require('zigbee-clusters');

console.log(ThermostatCluster, CLUSTER.THERMOSTAT);

Perfect, thank you.

I thought it was initialized together with the Cluster object.

But this works.

Hi Peter,
i am working on the same problem like you post few days before… I have a Thermostat device, but i am o the start line with that. I am not able to read the local temperature from this device. I have t osay, i am tottaly new in this world of programming, but i am trying to lern as fast as i can…
I made driver for my Thermostat device TZE200_2atgdho ID TS0601. In the first step i added "capabilities: measure_temperature, but i dont have any value from that. I found our topic, and you wrote, you are able to viev the local Temperature. Cann you post your code from driver.compose.json?
It can verry help me, with this problem. Manny thanks, Pavel

Another thing, here is my log of clusters:

[class ThermostatCluster extends Cluster] {
  attributes: {
    clusterRevision: { id: 65533, type: uint16 },
    attributeReportingStatus: { id: 65534, type: enum8 },
    localTemperature: { id: 0, type: int16 },
    outdoorTemperature: { id: 1, type: int16 },
    occupancy: { id: 2, type: map8 },
    absMinHeatSetpointLimit: { id: 3, type: int16 },
    absMaxHeatSetpointLimit: { id: 4, type: int16 },
    absMinCoolSetpointLimit: { id: 5, type: int16 },
    absMaxCoolSetpointLimit: { id: 6, type: int16 },
    pICoolingDemand: { id: 7, type: uint8 },
    pIHeatingDemand: { id: 8, type: uint8 },
    localTemperatureCalibration: { id: 16, type: int8 },
    occupiedCoolingSetpoint: { id: 17, type: int16 },
    occupiedHeatingSetpoint: { id: 18, type: int16 },
    unoccupiedCoolingSetpoint: { id: 19, type: int16 },
    unoccupiedHeatingSetpoint: { id: 20, type: int16 },
    minHeatSetpointLimit: { id: 21, type: int16 },
    maxHeatSetpointLimit: { id: 22, type: int16 },
    minCoolSetpointLimit: { id: 23, type: int16 },
    maxCoolSetpointLimit: { id: 24, type: int16 },
    minSetpointDeadBand: { id: 25, type: int8 },
    remoteSensing: { id: 26, type: map8 },
    controlSequenceOfOperation: { id: 27, type: enum8 },
    systemMode: { id: 28, type: enum8 },
    alarmMask: { id: 29, type: map8 }

Hi Pavel.

My driver.compose.json;

{
  "name": {
    "en": "Thermostat"
  },
  "class": "thermostat",
  "capabilities": [
    "measure_temperature",
    "measure_battery"
  ],
  "platforms": [
    "local"
  ],
  "connectivity": [
    "zigbee"
  ],
  "zigbee": {
    "manufacturerName": "Danfoss",
    "productId": ["eTRV0100"],
    "endpoints": {
      "1": {
        "clusters": [1, 513],
        "bindings": [0]
      }
    }
  },
  "images": {
    "small": "{{driverAssetsPath}}/images/small.png",
    "large": "{{driverAssetsPath}}/images/large.png",
    "xlarge": "{{driverAssetsPath}}/images/xlarge.png"
  }
}

And the device implementation looks like this (note retrieving the local temperature is just to try it):

const { ZigBeeDevice } = require("homey-zigbeedriver");
const { CLUSTER, ThermostatCluster, PowerConfigurationCluster } = require('zigbee-clusters');
const { debug } = require("zigbee-clusters");

// Enable debug logging of all relevant Zigbee communication
debug(true);

class ThermostatDevice extends ZigBeeDevice {

  async onNodeInit({ zclNode }) {

    // Read the "localTemperature" attribute from the "thermostat" cluster
    const currentTemperatureValue = await zclNode.endpoints[1].clusters.thermostat.readAttributes(
      "localTemperature"
    );
   
      this.registerCapability("measure_temperature", ThermostatCluster, {
        get: 'localTemperature',
        report: 'localTemperature',
        getParser(value) {
          var localTemperature = value / 100;

          this.setCapabilityValue('measure_temperature', localTemperature).catch(this.error);        
   
          return localTemperature;
        },
        reportParser(value) {
          var localTemperature = value / 100;

          this.setCapabilityValue('measure_temperature', localTemperature).catch(this.error);        
   
          return localTemperature;
        },
        reportOpts: {
          configureAttributeReporting: {
            minInterval: 0, // No minimum reporting interval
            maxInterval: 60000, // Maximally every ~16 hours
            minChange: 1, // Report when value changed by 5
          },
        },
        endpoint: 1, // Default is 1
        getOpts: {
          getOnStart: true,
          getOnOnline: true,
          pollInterval: 30000, // in ms
        },
      });

       // Read the "battery" attribute from the "power" cluster
    const currentBatteryValue = await zclNode.endpoints[1].clusters.powerConfiguration.readAttributes(
      "batteryPercentageRemaining"
    );

    console.log(currentBatteryValue);

    this.setCapabilityValue('measure_battery', (currentBatteryValue.batteryPercentageRemaining / 10)).catch(this.error);        
   
    this.registerCapability("measure_battery", PowerConfigurationCluster, {
        report: 'batteryPercentageRemaining',
        reportParser: value => value / 10,
        get: 'batteryPercentageRemaining',
        getParser: value => value / 10
        });
  }
}

module.exports = ThermostatDevice;

I hope this helps even though I’m also still just trying stuff to see how it works.

Peter

Hi Peter, befor y reply to your post, i tried a lot of solution, BUT - nothing is working in my case…

Step 1, I made a very easy driver.compose.json with capabiliti “measure_temperature”

{
  "id": "termohlavice",
  "name": {
    "en": "Termohlavice"
  },
  "class": "thermostat",
  "_appSpecific":{
    "brand": "Thermo made",
    "modelID": "TS0601"
  },
  "capabilities": [
    "measure_temperature"
    ],
  }, 
  "platforms": [ "local" ],
  "connectivity": [ "zigbee" ],
  "zigbee": {
    "manufacturerName": "_TZE200_2atgpdho",
    "productId": "TS0601",
    "endpoints": {
      "1": {
        "clusters": [0, 4, 5, 61184, 25, 10],
        "bindings": [0]
      }
    },   
    "learnmode": {
      "image": "{{driverAssetsPath}}/images/large.jpeg",
      "instruction": {
        "en": "Zmáčkni na hlavici symbol domečku, poté dlouze podrž a symbolem + najeď na číslo 5.\nDlouze zmáčkni, dokud se nepotvrdí symbol Wifi, poto dlouze podrž, dokud nezačne blikat symbol Wifi. Poté je připraveno k připojení"
      }
    }
  },
  "images": {
    "small": "{{driverAssetsPath}}/images/small.png",
    "large": "{{driverAssetsPath}}/images/large.png",
    "xlarge": "{{driverAssetsPath}}/images/xlarge.png"
  }
}

2, I just coppied your part of code to device.js and i changed some values:

const { ZigBeeDevice } = require("homey-zigbeedriver");
const { CLUSTER, ThermostatCluster, PowerConfigurationCluster } = require('zigbee-clusters');
const { debug } = require("zigbee-clusters");

// Enable debug logging of all relevant Zigbee communication
debug(true);

class ThermostatDevice extends ZigBeeDevice {

  async onNodeInit({ zclNode }) {

    // Read the "localTemperature" attribute from the "thermostat" cluster
    const currentTemperatureValue = await zclNode.endpoints[1].clusters.thermostat.readAttributes(
      "localTemperature"
    );
   
      this.registerCapability("measure_temperature", ThermostatCluster, {
        get: 'localTemperature',
        report: 'localTemperature',
        getParser(value) {
          var localTemperature = value / 100;

          this.setCapabilityValue('measure_temperature', localTemperature).catch(this.error);        
   
          return localTemperature;
        },
        reportParser(value) {
          var localTemperature = value / 100;

          this.setCapabilityValue('measure_temperature', localTemperature).catch(this.error);        
   
          return localTemperature;
        },
        reportOpts: {
          configureAttributeReporting: {
            minInterval: 0, // No minimum reporting interval
            maxInterval: 60000, // Maximally every ~16 hours
            minChange: 1, // Report when value changed by 5
          },
        },
        endpoint: 1, // Default is 1
        getOpts: {
          getOnStart: true,
          getOnOnline: true,
          pollInterval: 30000, // in ms
        },
      });
  }
}

module.exports = ThermostatDevice;

But it does not work :frowning:
I tried some next steps , for example to read some others codes but i am not sure, if i understand well, how to work with my ovn clusters…

Can you help me little please? :slight_smile:

I will continue in this topic…

I have a radiator valve, and i want to develop my driver step by step…

What i made:
1 - i added a new zigbee device and then i made interview with that device. I have this informations:

"ids": {
    "modelId": "TS0601",
    "manufacturerName": "_TZE200_2atgpdho"
  },
  "endpoints": {
    "endpointDescriptors": [
      {
        "endpointId": 1,
        "applicationProfileId": 260,
        "applicationDeviceId": 81,
        "applicationDeviceVersion": 0,
        "_reserved1": 1,
        "inputClusters": [
          0,
          4,
          5,
          61184
        ],
        "outputClusters": [
          25,
          10
        ]
      }
    ],
    "endpoints": {
      "1": {
        "clusters": {
          "basic": {
            "attributes": [
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 0,
                "name": "zclVersion",
                "value": 3
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 1,
                "name": "appVersion",
                "value": 85
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 2,
                "name": "stackVersion",
                "value": 0
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 3,
                "name": "hwVersion",
                "value": 1
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 4,
                "name": "manufacturerName",
                "value": "_TZE200_2atgpdho"
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 5,
                "name": "modelId",
                "value": "TS0601"
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 6,
                "name": "dateCode",
                "value": ""
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 7,
                "name": "powerSource",
                "value": "battery"
              },
              {
                "acl": [
                  "readable",
                  "writable",
                  "reportable"
                ],
                "id": 65502
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 65533,
                "name": "clusterRevision",
                "value": 2
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 65534,
                "name": "attributeReportingStatus",
                "value": "PENDING"
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 65504
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 65505
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 65506
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 65507
              }
            ],
            "commandsGenerated": "UNSUP_GENERAL_COMMAND",
            "commandsReceived": "UNSUP_GENERAL_COMMAND"
          },
          "groups": {
            "attributes": [
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 0,
                "name": "nameSupport",
                "value": {
                  "type": "Buffer",
                  "data": [
                    0
                  ]
                }
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 65533,
                "name": "clusterRevision",
                "value": 2
              }
            ],
            "commandsGenerated": "UNSUP_GENERAL_COMMAND",
            "commandsReceived": "UNSUP_GENERAL_COMMAND"
          },
          "scenes": {
            "attributes": [
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 0
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 1
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 2
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 3
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 4
              },
              {
                "acl": [
                  "readable",
                  "reportable"
                ],
                "id": 65533,
                "name": "clusterRevision",
                "value": 2
              }
            ],
            "commandsGenerated": "UNSUP_GENERAL_COMMAND",
            "commandsReceived": "UNSUP_GENERAL_COMMAND"
          }
        },
        "bindings": {
          "ota": {
            "attributes": [],
            "commandsGenerated": "UNSUP_GENERAL_COMMAND",
            "commandsReceived": "UNSUP_GENERAL_COMMAND"
          },
          "time": {
            "attributes": [],
            "commandsGenerated": "UNSUP_GENERAL_COMMAND",
            "commandsReceived": "UNSUP_GENERAL_COMMAND"
          }
        }
      }
    }
  }

2 step:
I made my own app - based on official homey tutorial. Then i made my own driver inside this app.
driver.compose.json and device.js is on the post before.