Skip to content

Commit

Permalink
fix: Improve reporting for TuYa TS011F_plug_1 Koenkk/zigbee2mqtt#19977
Browse files Browse the repository at this point in the history
  • Loading branch information
Koenkk committed Dec 17, 2023
1 parent c3dfae6 commit 5f511d3
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 16 deletions.
18 changes: 7 additions & 11 deletions src/devices/tuya.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {ColorMode, colorModeLookup} from '../lib/constants';
import fz from '../converters/fromZigbee';
import tz from '../converters/toZigbee';
import {KeyValue, Definition, Tz, Fz, Expose, KeyValueAny, KeyValueNumberString, KeyValueString} from '../lib/types';
import {onOff} from '../lib/modernExtend';
import {electricityMeter, onOff} from '../lib/modernExtend';

const e = exposes.presets;
const ea = exposes.access;
Expand Down Expand Up @@ -3306,20 +3306,16 @@ const definitions: Definition[] = [
powerOutageMemory: true, indicatorMode: true, childLock: true, onOffFzConverter: fzLocal.TS011F_onoff}),
configure: async (device, coordinatorEndpoint, logger) => {
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
await reporting.rmsVoltage(endpoint, {change: 5});
await reporting.rmsCurrent(endpoint, {change: 50});
await onOff({powerOnBehavior: false}).configure(device, coordinatorEndpoint, logger);

const acCurrentDivisor = device.manufacturerName === '_TZ3000_typdpbpg' ? 2000 : 1000;
await electricityMeter({power: false, voltage: {divisor: 1}, current: {divisor: acCurrentDivisor}, energy: {divisor: 100}});
if (!['_TZ3000_0zfrhq4i', '_TZ3000_okaz9tjs', '_TZ3000_typdpbpg'].includes(device.manufacturerName)) {
// Gives INVALID_DATA_TYPE error for _TZ3000_0zfrhq4i (as well as a few others in issue 20028)
// https://github.com/Koenkk/zigbee2mqtt/discussions/19680#discussioncomment-7667035
await reporting.activePower(endpoint, {change: 10});
await electricityMeter({power: {divisor: 1}, voltage: false, current: false, energy: false})
.configure(device, coordinatorEndpoint, logger);
}
await reporting.currentSummDelivered(endpoint);
const acCurrentDivisor = device.manufacturerName === '_TZ3000_typdpbpg' ? 2000 : 1000;
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor, acCurrentMultiplier: 1});
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
device.save();
},
},
{
Expand Down
19 changes: 14 additions & 5 deletions src/lib/modernExtend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,15 @@ export function onOff(args?: OnOffArgs): ModernExtend {
type MultiplierDivisor = {multiplier?: number, divisor?: number}
interface ElectricityMeterArgs {
cluster?: 'both' | 'metering' | 'electrical',
current?: MultiplierDivisor,
power?: MultiplierDivisor,
voltage?: MultiplierDivisor,
energy?: MultiplierDivisor
current?: false | MultiplierDivisor,
power?: false | MultiplierDivisor,
voltage?: false | MultiplierDivisor,
energy?: false | MultiplierDivisor
}
export function electricityMeter(args?: ElectricityMeterArgs): ModernExtend {
args = {cluster: 'both', ...args};
if (args.cluster === 'metering' && (args.power?.divisor !== args.energy?.divisor || args.power?.multiplier !== args.energy?.multiplier)) {
if (args.cluster === 'metering' && isObject(args.power) && isObject(args.energy) &&
(args.power?.divisor !== args.energy?.divisor || args.power?.multiplier !== args.energy?.multiplier)) {
throw new Error(`When cluster is metering, power and energy divisor/multiplier should be equal`);
}

Expand All @@ -114,6 +115,14 @@ export function electricityMeter(args?: ElectricityMeterArgs): ModernExtend {
},
};

if (args.power === false) {
delete configureLookup.haElectricalMeasurement.power;
delete configureLookup.seMetering.power;
}
if (args.voltage === false) delete configureLookup.haElectricalMeasurement.voltage;
if (args.current === false) delete configureLookup.haElectricalMeasurement.current;
if (args.energy === false) delete configureLookup.seMetering.energy;

if (args.cluster === 'both') {
exposes = [
e.power().withAccess(ea.STATE_GET), e.voltage().withAccess(ea.STATE_GET),
Expand Down

0 comments on commit 5f511d3

Please sign in to comment.