Hi,
I am trying to develop an app for a smart charger, and most of the basic stuff works. But I can’t seem to get Homey’s energy and power to display in the mobile app.
I can manually read the value of both measure_power and meter_power, to just log them out or use in flow cards. But actually just simply reporting that to Homey does not work.
I might’ve just completely misunderstood how the reporting work, but here is the current code that I am testing with.
'use strict';
const { ZigBeeDevice } = require('homey-zigbeedriver');
const { CLUSTER, debug } = require('zigbee-clusters');
debug(true);
const DIM_TRANSITION_TIME = 2;
class Device extends ZigBeeDevice {
async onNodeInit({ zclNode }) {
/// /////////////////////////////////////////////////////////////////////////////
// Debug log
/// /////////////////////////////////////////////////////////////////////////////
const energyValue = await zclNode.endpoints[1].clusters[CLUSTER.METERING.NAME].readAttributes(['currentSummationDelivered']).catch((err) => {
this.error('Error reading currentSummationDelivered attribute:', err);
return null; // Return null in case of an error
});
this.log('energy value', energyValue);
const powerValue = await zclNode.endpoints[1].clusters[CLUSTER.ELECTRICAL_MEASUREMENT.NAME]
.readAttributes(['activePower'])
.catch((err) => {
this.error('Error reading activePower attribute:', err);
return null; // Return null in case of an error
});
this.log('power value', powerValue);
/// /////////////////////////////////////////////////////////////////////////////
// Register attribute reporting
/// /////////////////////////////////////////////////////////////////////////////
if (this.hasCapability('meter_power')) {
this.registerCapability('meter_power', CLUSTER.METERING);
} else {
this.log('Meter power capability not available on this device.');
}
if (this.hasCapability('measure_power')) {
this.registerCapability('measure_power', CLUSTER.METERING);
} else {
this.log('Measure power capability not available on this device.');
}
await this.configureAttributeReporting([
{
endpointId: 1,
cluster: CLUSTER.METERING,
attributeName: 'currentSummationDelivered',
minInterval: 0,
maxInterval: 300,
minChange: 0,
},
{
endpointId: 1,
cluster: CLUSTER.ELECTRICAL_MEASUREMENT,
attributeName: 'activePower',
minInterval: 0,
maxInterval: 300,
minChange: 0,
},
]).catch((err) => {
this.error(err);
});
// /// /////////////////////////////////////////////////////////////////////////////
// // Register attribute listeners
// /// /////////////////////////////////////////////////////////////////////////////
// zclNode.endpoints[1].clusters[CLUSTER.ON_OFF.NAME].on('attr.onOff', async (value) => {
// this.log('onOff attribute reporting', value);
// });
zclNode.endpoints[1].clusters[CLUSTER.METERING.NAME].on('attr.currentSummationDelivered', async (value) => {
this.log('currentSummationDelivered attribute reporting', value);
});
zclNode.endpoints[1].clusters[CLUSTER.ELECTRICAL_MEASUREMENT.NAME].on('attr.activePower', async (value) => {
this.log('activePower attribute reporting', value);
});
/// /////////////////////////////////////////////////////////////////////////////
// Register onoff capability listener
/// /////////////////////////////////////////////////////////////////////////////
this.registerCapabilityListener('onoff', async (value) => {
this.log('onoff', value);
if (value) {
await zclNode.endpoints[1].clusters.onOff.setOn();
// await this.triggerFlow({
// id: 'charging-starts',
// tokens: {
// energy: this.getCapabilityValue('meter_power'),
// power: this.getCapabilityValue('measure_power'),
// },
// });
this.log('onoff result');
} else {
await zclNode.endpoints[1].clusters.onOff.setOff();
const energy = await this.getEnergy();
this.log('energy', energy);
// const powerValue = await zclNode.endpoints[1].clusters[CLUSTER.ELECTRICAL_MEASUREMENT]
// .readAttributes(['activePower'])
// .catch((err) => {
// this.error('Error reading activePower attribute:', err);
// return null; // Return null in case of an error
// });
// this.log('power value', powerValue);
//
// const energyValue = await zclNode.endpoints[1].clusters[CLUSTER.METERING]
// .readAttributes(['currentSummationDelivered'])
// .catch((err) => {
// this.error('Error reading currentSummationDelivered attribute:', err);
// return null; // Return null in case of an error
// });
// this.log('energy value', energyValue);
//
//
// this.log('power value', value);
// await this.triggerFlow({
// id: 'charging-stops',
// tokens: {
// energy: this.getCapabilityValue('meter_power'),
// power: this.getCapabilityValue('measure_power'),
// },
// });
this.log('onoff result');
}
});
this.registerCapabilityListener('dim', async (value) => {
this.log('dim', value);
if (typeof value === 'number' && value >= 0 && value <= 1) {
await zclNode.endpoints[1].clusters.levelControl.moveToLevel({
level: value * 255,
transitionTime: DIM_TRANSITION_TIME,
});
}
});
}
}
module.exports = Device;
And the driver compose
{
"name": {
"en": "NAME-Smart Charger"
},
"class": "socket",
"capabilities": [
"dim",
"meter_power",
"measure_power",
"onoff"
],
"platforms": [
"local",
"cloud"
],
"zigbee": {
"manufacturerName": "MANUFACTURER_NAME",
"productId": ["NAME"],
"endpoints": {
"1": {
"clusters": [
0,
3,
4,
6,
8,
1794,
2820,
61740,
65261
]
}
},
"learnmode": {
"image": "/drivers/my_driver/assets/learnmode.svg",
"instruction": {
"en": "Hold the button for 10 seconds until the light bar turns pink, then press the button on your device three times"
}
}
},
"pair": [
{
"id": "list_devices",
"template": "list_devices",
"navigation": {
"next": "add_devices"
}
},
{
"id": "add_devices",
"template": "add_devices"
}
],
"images": {
"small": "{{driverAssetsPath}}/images/small.png",
"large": "{{driverAssetsPath}}/images/large.png",
"xlarge": "{{driverAssetsPath}}/images/xlarge.png"
}
}