espressif / esp-zigbee-sdk

Espressif Zigbee SDK
Apache License 2.0
178 stars 31 forks source link

Add attribute Metering (0x0702) (TZ-960) #370

Closed DEFAYArnaud closed 5 months ago

DEFAYArnaud commented 5 months ago

Question

Hello,

I wanted to know how to add the attribute "ESP_ZB_ZCL_ATTR_METERING_MULTIPLIER_ID" & "ESP_ZB_ZCL_ATTR_METERING_DIVISOR_ID" in a metering cluster?

Thank you in advance for your reply.

Additional context.

No response

xieqinan commented 5 months ago

@DEFAYArnaud ,

You can call esp_zb_cluster_add_attr() to add the attributes to the specific cluster.

DEFAYArnaud commented 5 months ago

Thank you for your reply. Now I have this error with Zigbee2mqtt. How can I solve it?

seMetering.configReport([{"minimumReportInterval":10,"maximumReportInterval":65000,"reportableChange":[0,100],"attribute":"currentSummDelivered"}], {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Status 'UNREPORTABLE_ATTRIBUTE') at Endpoint.checkStatus (/app/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:316:28) at Endpoint.zclCommand (/app/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:771:26) at Endpoint.configureReporting (/app/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:557:9) at setupAttributes (/app/node_modules/zigbee-herdsman-converters/src/lib/modernExtend.ts:76:13) at result.configure (/app/node_modules/zigbee-herdsman-converters/src/lib/modernExtend.ts:1488:29) at Object.configure (/app/node_modules/zigbee-herdsman-converters/src/index.ts:173:21) at Configure.configure (/app/lib/extension/configure.ts:121:13) at EventEmitter.wrappedCallback (/app/lib/eventBus.ts:174:17))

DEFAYArnaud commented 5 months ago

I've just tried executing esp_zb_zcl_report_attr_cmd_req for the attribute ESP_ZB_ZCL_ATTR_METERING_CURRENT_SUMMATION_DELIVERED_ID but I get this error. :

ESP_ZIGBEE_COMMAND: esp_zb_zcl_report_attr_cmd_req(281): This attribute: 0x0 is not reportable!

How else can I update this attribute?

xieqinan commented 5 months ago

@DEFAYArnaud ,

According to the specification, the ESP_ZB_ZCL_ATTR_METERING_CURRENT_SUMMATION_DELIVERED_ID is not a reportable attribute. As a result, the log message ESP_ZIGBEE_COMMAND: esp_zb_zcl_report_attr_cmd_req(281): This attribute: 0x0 is not reportable! is displayed.

DEFAYArnaud commented 5 months ago

Ok thanks. So how do I update the data for "CURRENT SUMMATION" ?

xieqinan commented 5 months ago

@DEFAYArnaud ,

It would be helpful to provide the application context first. According to the logs below, Z2M considers the CURRENT SUMMATION attribute to be UNREPORTABLE_ATTRIBUTE. Why do you expect it to be reported?

seMetering.configReport([{"minimumReportInterval":10,"maximumReportInterval":65000,"reportableChange":[0,100],"attribute":"currentSummDelivered"}], {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"srcEndpoint":null,"> reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Status 'UNREPORTABLE_ATTRIBUTE')

DEFAYArnaud commented 5 months ago

Thanks for your help. This is to update the energy value. See photo.

Capture d’écran 2024-06-24 à 10 31 17
xieqinan commented 5 months ago

@DEFAYArnaud ,

Understood. Since the CURRENT SUMMATION attribute is not reportable, Z2M should read the attribute value from the meter cluster server or send related commands to retrieve it automatically. Does Z2M perform similar operations?

DEFAYArnaud commented 5 months ago

Thanks again for your help

When I add esp32-C6 to Z2M, the same error appears 3 times:

Failed to configure '0x404ccafffe50cb98', attempt 1 (Error: ZCL command 0x404ccafffe50cb98/1 seMetering.configReport([{"minimumReportInterval":10,"maximumReportInterval":65000,"reportableChange":[0,100],"attribute":"currentSummDelivered"}], {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Status 'UNREPORTABLE_ATTRIBUTE') at Endpoint.checkStatus (/app/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:316:28) at Endpoint.zclCommand (/app/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:771:26) at Endpoint.configureReporting (/app/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:557:9) at setupAttributes (/app/node_modules/zigbee-herdsman-converters/src/lib/modernExtend.ts:76:13) at result.configure (/app/node_modules/zigbee-herdsman-converters/src/lib/modernExtend.ts:1488:29) at Object.configure (/app/node_modules/zigbee-herdsman-converters/src/index.ts:173:21) at Configure.configure (/app/lib/extension/configure.ts:121:13) at EventEmitter.wrappedCallback (/app/lib/eventBus.ts:174:17))

Then at the beginning I have this:

Capture d’écran 2024-06-24 à 11 01 41

And then when I press the button, the value is displayed:

Capture d’écran 2024-06-24 à 11 06 48

Z2M can display the value when I press the button to refresh, but it can't do it automatically.

DEFAYArnaud commented 5 months ago

Here's how to update the Energy value with Z2M:

  1. In the ESP program you need to do a task to update ESP_ZB_ZCL_ATTR_METERING_CURRENT_SUMMATION_DELIVERED_ID like this:

esp_zb_zcl_set_attribute_val(endpoint, ESP_ZB_ZCL_CLUSTER_ID_METERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_METERING_CURRENT_SUMMATION_DELIVERED_ID, &current_summation_delivered, false);

  1. Then in Z2M you need to create a new device and add it to const definition :

onEvent: (type, data, device, options) => { const endpoint = device.getEndpoint(1); <------ Set chosen endpoint if (type === 'stop') { clearInterval(globalStore.getValue(device, 'interval')); globalStore.clearValue(device, 'interval'); } else if (!globalStore.hasValue(device, 'interval')) { const seconds = options && options.measurement_poll_interval ? options.measurement_poll_interval : 30; if (seconds === -1) return; const interval = setInterval(async () => { try { await endpoint.read('seMetering', ['currentSummDelivered']); } catch (error) {/* Do nothing*/} }, seconds*1000); globalStore.putValue(device, 'interval', interval); } },

Thanks again to @xieqinan for his help.