Koenkk / zigbee-herdsman-converters

Collection of device converters to be used with zigbee-herdsman
MIT License
880 stars 2.92k forks source link

Help to support custom ESP32C6 device #7802

Closed matteovisotto closed 1 month ago

matteovisotto commented 1 month ago

Hi, I'm creating a custom device using a ESP32C6 and espressif zigbee library. My Cluster definitions are:

char manufname[] = {7, 'M', 'V', 'D', 'e', 'v', 'Z', 'B'};
    char modelid[] = {8, 'P', 'L', 'S', 'Y', 'S', 'Z', 'B', '1'};

    esp_zb_attribute_list_t *esp_zb_basic_cluster = esp_zb_basic_cluster_create(NULL);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, &manufname[0]);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, &modelid[0]);

    esp_zb_attribute_list_t *esp_zb_switch_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_ON_OFF);

    esp_zb_attribute_list_t *esp_zb_water_level_cluster = esp_zb_zcl_attr_list_create(0xfc01);
    esp_zb_cluster_add_attr(esp_zb_water_level_cluster, 0xfc01, 0x0000, ESP_ZB_ZCL_ATTR_TYPE_8BIT, ESP_ZB_ZCL_ATTR_ACCESS_REPORTING, &water_values->current);
    esp_zb_cluster_add_attr(esp_zb_water_level_cluster, 0xfc01, 0x0001, ESP_ZB_ZCL_ATTR_TYPE_8BIT, ESP_ZB_ZCL_ATTR_ACCESS_REPORTING, &water_values->min);
    esp_zb_cluster_add_attr(esp_zb_water_level_cluster, 0xfc01, 0x0002, ESP_ZB_ZCL_ATTR_TYPE_8BIT, ESP_ZB_ZCL_ATTR_ACCESS_REPORTING, &water_values->max);

    esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create();
    esp_zb_cluster_list_add_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_on_off_cluster(esp_zb_cluster_list, esp_zb_switch_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_custom_cluster(esp_zb_cluster_list, esp_zb_water_level_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    esp_zb_ep_list_t *zb_plant_ep_list = esp_zb_ep_list_create();
    esp_zb_ep_list_add_ep(zb_plant_ep_list, esp_zb_cluster_list, HA_PLANT_ENDPOINT, ESP_ZB_AF_HA_PROFILE_ID, ESP_ZB_HA_CUSTOM_ATTR_DEVICE_ID);

    // Register endpoint list
    esp_zb_device_register(zb_plant_ep_list);
    esp_zb_core_action_handler_register(zb_action_handler);

If I write them correctly they should represent a genOnOff cluster to control a switch and a custom cluster in which I report a water level (current, min and max).

I tried to write a custom converter, I saved it in /opt/zigbee2mqtt and using the web ui -> settings -> external converter I add the file name.

When I paired the device it still unsupported and the cluster I see from the app are the follow:

Screenshot 2024-07-26 alle 12 07 36

The converter code is:

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

const fLocal = {
    waterLevel: {
      cluster: '64513', //This part is important
      type: ['readResponse', 'attributeReport'],
      convert: (model, msg, publish, options, meta) => {
        if (msg.data.hasOwnProperty('0')) {
            const waterlevel = parseFloat (msg.data['0']); 
            return {I'waterlevel']: waterlevel};
        }
      },
    },
    minWater: {
        cluster: '64513', //This part is important
        type: ['readResponse', 'attributeReport'],
        convert: (model, msg, publish, options, meta) => {
        if (msg.data.hasOwnProperty('1')) {
              const minWaterLevel = parseFloat (msg.data['1']); 
              return {I'minWaterLevel']: minWaterLevel};
          }
      },
    },
      maxWater: {
        cluster: '64513', //This part is important
        type: ['readResponse', 'attributeReport'],
        convert: (model, msg, publish, options, meta) => {
        if (msg.data.hasOwnProperty('2')) {
              const maxWaterLevel = parseFloat (msg.data['2']); 
              return {I'maxWaterLevel']: maxWaterLevel};
          }
      },
    },
};

const definition = {
    zigbeeModel: ['PLSYSZB1'],
    model: 'PLSYSZB1',
    vendor: 'MVDevZB',
    description: 'Irrigation Plant System',
    extend: [],
    fromZigbee: [fz.on_off, fLocal.waterLevel, fLocal.minWater, fLocal.maxWater], 
    toZigbee: [tz.on_off],
    exposes: [e.switch(), e.numeric ( 'waterLevel', ea.STATE).withLabel( 'Water Level').withUnit ('%').withDescription ('Water level percentage'), e.numeric ( 'minWaterLevel', ea.STATE).withLabel( 'Minimum Water Level').withUnit ('%').withDescription ('Minimum water level'), e.numeric ( 'maxWaterLevel', ea.STATE).withLabel( 'Max Water Level').withUnit ('%').withDescription ('Maximum water level')],
};

module.exports = definition;

Please, someone can help me to fix?

matteovisotto commented 1 month ago

Solved, it is necessary to add the costum cluster in cluster.ts