Skip to content

Instantly share code, notes, and snippets.

@Koenkk

Koenkk/ext.js Secret

Last active September 25, 2024 18:33
Show Gist options
  • Save Koenkk/3311969512f2e4307dcee8b6a22e1cbb to your computer and use it in GitHub Desktop.
Save Koenkk/3311969512f2e4307dcee8b6a22e1cbb 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 tuya = require('zigbee-herdsman-converters/lib/tuya');
const e = exposes.presets;
const ea = exposes.access;
const legacy = require('zigbee-herdsman-converters/lib/legacy');
const lumi = require('zigbee-herdsman-converters/lib/lumi');
const utils = require('zigbee-herdsman-converters/lib/utils');
const {logger} = require('zigbee-herdsman-converters/lib/logger');
const {develcoModernExtend} = require('zigbee-herdsman-converters/lib/develco');
const {battery, quirkAddEndpointCluster} = require('zigbee-herdsman-converters/lib/modernExtend');
const NS = 'extconverter';
const fzLocal = {
fault_status: {
cluster: 'genBinaryInput',
type: ['attributeReport', 'readResponse'],
convert: (model, msg, publish, options, meta) => {
const result = {};
if (msg.data.reliability !== undefined) {
const lookup = {0: 'no_fault_detected', 7: 'unreliable_other', 8: 'process_error'};
result.reliability = utils.getFromLookup(msg.data['reliability'], lookup);
}
if (msg.data.statusFlags !== undefined) {
result.fault = msg.data['statusFlags'] === 1;
}
return result;
},
},
};
const definition = {
zigbeeModel: ['SMSZB-120', 'GWA1512_SmokeSensor'],
model: 'SMSZB-120',
vendor: 'Develco',
description: 'Smoke detector with siren CUSTOM',
whiteLabel: [
{vendor: 'Frient', model: '94430', description: 'Smart Intelligent Smoke Alarm'},
{vendor: 'Cavius', model: '2103', description: 'RF SMOKE ALARM, 5 YEAR 65MM'},
],
fromZigbee: [fz.ias_smoke_alarm_1_develco, fz.ignore_basic_report, fz.ias_enroll, fz.ias_wd, fzLocal.fault_status],
toZigbee: [tz.warning, tz.ias_max_duration, tz.warning_simple],
// ota: ota.zigbeeOTA,
extend: [
develcoModernExtend.addCustomClusterManuSpecificDevelcoGenBasic(),
develcoModernExtend.readGenBasicPrimaryVersions(),
develcoModernExtend.temperature(), // TODO: ep 38
battery({
voltageToPercentage: {min: 2500, max: 3000},
percentage: true,
voltage: true,
lowStatus: false,
voltageReporting: false,
percentageReporting: false,
}),
],
configure: async (device, coordinatorEndpoint) => {
const endpoint = device.getEndpoint(35);
for (const cluster of ['ssIasZone', 'ssIasWd', 'genBasic', 'genBinaryInput', 'genPowerCfg']) {
try {
await endpoint.bind(cluster, coordinatorEndpoint);
} catch (error) {
if (error.message.includes('TABLE_FULL')) {
// Device throws TABLE_FULL errors even though bind works.
// https://github.com/Koenkk/zigbee2mqtt/issues/23684
logger.debug(`TABLE_FULL error while binding '${cluster}', ignoring...`, NS);
} else {
throw error;
}
}
}
await reporting.batteryPercentageRemaining(endpoint);
await reporting.batteryVoltage(endpoint);
// await reporting.bind(endpoint, coordinatorEndpoint, ['ssIasZone', 'ssIasWd', 'genBasic', 'genBinaryInput']);
await endpoint.read('ssIasZone', ['iasCieAddr', 'zoneState', 'zoneId']);
await endpoint.read('genBinaryInput', ['reliability', 'statusFlags']);
// await endpoint.read('ssIasWd', ['maxDuration']);
},
endpoint: (device) => {
return {default: 35};
},
exposes: [
e.smoke(),
e.battery_low(),
e.test(),
e.numeric('max_duration', ea.ALL).withUnit('s').withValueMin(0).withValueMax(600).withDescription('Duration of Siren'),
e.binary('alarm', ea.SET, 'START', 'OFF').withDescription('Manual Start of Siren'),
e.enum('reliability', ea.STATE, ['no_fault_detected', 'unreliable_other', 'process_error']).withDescription('Indicates reason if any fault'),
e.binary('fault', ea.STATE, true, false).withDescription('Indicates whether the device are in fault state'),
],
};
module.exports = definition;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment