Skip to content

Instantly share code, notes, and snippets.

@Koenkk

Koenkk/ext.js Secret

Created November 12, 2023 20:03
Show Gist options
  • Save Koenkk/09b460e1c99526fa909079f79eda2fc4 to your computer and use it in GitHub Desktop.
Save Koenkk/09b460e1c99526fa909079f79eda2fc4 to your computer and use it in GitHub Desktop.
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 legacy = require('zigbee-herdsman-converters/lib/legacy');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
async function onEventMeasurementPoll(type, data, device, options,
electricalMeasurement=true, metering=false) {
const endpoint = device.getEndpoint(1);
console.log('POLL: START');
if (type === 'stop') {
console.log('POLL: stop');
clearTimeout(globalStore.getValue(device, 'measurement_poll'));
globalStore.clearValue(device, 'measurement_poll');
} else if (!globalStore.hasValue(device, 'measurement_poll')) {
const seconds = utils.toNumber(
options && options.measurement_poll_interval ? options.measurement_poll_interval : 60, 'measurement_poll_interval');
if (seconds === -1) return;
const setTimer = () => {
console.log('POLL: set timer ' + seconds);
const timer = setTimeout(async () => {
console.log('POLL: timer tick');
try {
if (electricalMeasurement) {
console.log('POLL: read1.1');
await endpoint.read('haElectricalMeasurement', ['rmsVoltage', 'rmsCurrent', 'activePower']);
console.log('POLL: read1.2');
}
if (metering) {
console.log('POLL: read2.1');
await endpoint.read('seMetering', ['currentSummDelivered']);
console.log('POLL: read2.2');
}
} catch (error) {
console.log('POLL: error');
}
console.log('POLL: set timer again')
setTimer();
}, seconds * 1000);
globalStore.putValue(device, 'measurement_poll', timer);
};
setTimer();
}
}
const definition = {
zigbeeModel: ['TS0121'],
model: 'TS0121_plug',
description: '10A UK or 16A EU smart plug',
whiteLabel: [
{vendor: 'BlitzWolf', model: 'BW-SHP13'},
{vendor: 'Connecte', model: '4500990'},
{vendor: 'Connecte', model: '4500991'},
{vendor: 'Connecte', model: '4500992'},
{vendor: 'Connecte', model: '4500993'},
],
vendor: 'TuYa',
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, tuya.fz.power_outage_memory,
tuya.fz.indicator_mode],
toZigbee: [tz.on_off, tuya.tz.power_on_behavior_1, tuya.tz.backlight_indicator_mode_1],
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {
acVoltageMultiplier: 1, acVoltageDivisor: 1, acCurrentMultiplier: 1, acCurrentDivisor: 1000, acPowerMultiplier: 1,
acPowerDivisor: 1,
});
try {
await reporting.currentSummDelivered(endpoint);
await reporting.rmsVoltage(endpoint, {change: 5});
await reporting.rmsCurrent(endpoint, {change: 50});
await reporting.activePower(endpoint, {change: 10});
} catch (error) {/* fails for some https://github.com/Koenkk/zigbee2mqtt/issues/11179
and https://github.com/Koenkk/zigbee2mqtt/issues/16864 */}
await endpoint.read('genOnOff', ['onOff', 'moesStartUpOnOff', 'tuyaBacklightMode']);
},
options: [exposes.options.measurement_poll_interval()],
// This device doesn't support reporting correctly.
// https://github.com/Koenkk/zigbee-herdsman-converters/pull/1270
exposes: [e.switch(), e.power(), e.current(), e.voltage(),
e.energy(), e.enum('power_outage_memory', ea.ALL, ['on', 'off', 'restore'])
.withDescription('Recover state after power outage'),
e.enum('indicator_mode', ea.ALL, ['off', 'off/on', 'on/off']).withDescription('LED indicator mode')],
onEvent: (type, data, device, options) => onEventMeasurementPoll(type, data, device, options, true, false),
};
module.exports = definition;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment