Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion src/devices/nodon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,13 +304,66 @@ export const definitions: DefinitionWithExtend[] = [
vendor: "NodOn",
description: "Energy monitoring sensor",
extend: [
m.identify(),
m.electricityMeter({
acFrequency: true,
powerFactor: true,
producedEnergy: true,
configureReporting: false,
}),
],
exposes: [e.power_apparent()],
toZigbee: [
{
key: ["energy_reset"],
convertSet: async (entity, _key, _value, _meta) => {
// genBasic/resetFactDefault resets all cluster attributes to factory defaults.
// Network membership, bindings and configureReporting are not affected (ZCL spec).
await entity.command("genBasic", "resetFactDefault", {});
return {state: {}};
},
},
],
exposes: [
e.enum("energy_reset", ea.SET, ["reset"]).withDescription("Reset all energy counters to 0").withCategory("config"),
e.power_apparent(),
],
configure: async (device, coordinatorEndpoint) => {
const endpoint = device.getEndpoint(1);

// Explicit bind — not done by m.electricityMeter because configureReporting: false

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we not set configureReporting: true?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During my tests with the external converter, I observed that a single configureReporting call with 6+ haElectricalMeasurement attributes returns status=FAIL on our device. Splitting into batches of ≤ 5 attributes solved that.

The custom configure also reads multiplier/divisor attributes before the first configureReporting call, so ZHC has the correct scaling factors cached when the first reports arrive.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During my tests with the external converter, I observed that a single configureReporting call with 6+ haElectricalMeasurement attributes returns status=FAIL on our device. Splitting into batches of ≤ 5 attributes solved that.

For this I propose to add an argument to m.electricityMeter to change this behaviour.

so ZHC has the correct scaling factors cached when the first reports arrive.

I think we should also do this in the m.electricityMeter , read divisor/multiplier before doing the configureReporting

await endpoint.bind("haElectricalMeasurement", coordinatorEndpoint);
await endpoint.bind("seMetering", coordinatorEndpoint);

await endpoint.read("haElectricalMeasurement", [
"acVoltageMultiplier",
"acVoltageDivisor",
"acCurrentMultiplier",
"acCurrentDivisor",
"acPowerMultiplier",
"acPowerDivisor",
"acFrequencyMultiplier",
"acFrequencyDivisor",
]);
await endpoint.read("seMetering", ["multiplier", "divisor"]);

// Split into batches of ≤5 to stay within the ~85-byte ZCL frame limit
await endpoint.configureReporting("haElectricalMeasurement", [
{attribute: "acFrequency", minimumReportInterval: 30, maximumReportInterval: 3600, reportableChange: 500}, // 5 Hz
{attribute: "rmsVoltage", minimumReportInterval: 30, maximumReportInterval: 3600, reportableChange: 2300}, // 23 V
{attribute: "rmsCurrent", minimumReportInterval: 10, maximumReportInterval: 3600, reportableChange: 100}, // 1 A
{attribute: "activePower", minimumReportInterval: 10, maximumReportInterval: 3600, reportableChange: 250}, // 250 W
{attribute: "apparentPower", minimumReportInterval: 10, maximumReportInterval: 3600, reportableChange: 250}, // 250 VA
]);
await endpoint.configureReporting("haElectricalMeasurement", [
{attribute: "powerFactor", minimumReportInterval: 60, maximumReportInterval: 3600, reportableChange: 20}, // 0.20
]);
await endpoint.configureReporting("seMetering", [
{attribute: "currentSummDelivered", minimumReportInterval: 300, maximumReportInterval: 3600, reportableChange: 100}, // 0.1 kWh
]);
await endpoint.configureReporting("seMetering", [
{attribute: "currentSummReceived", minimumReportInterval: 300, maximumReportInterval: 3600, reportableChange: 100}, // 0.1 kWh
]);
},
ota: true,
},
{
Expand Down