Skip to content

Commit

Permalink
fix: IKEA VINDSTYRKA uses different DataType for measuredValue (#7450)
Browse files Browse the repository at this point in the history
* feat: add deviceAddCustomCluster modernExtend

* fix: IKEA VINDSTYRKA uses different DataType for measuredValue

* fix(ignore): move SONOFF customCluster to use modernExtend
  • Loading branch information
sjorge authored Apr 28, 2024
1 parent 401cbe2 commit 6d328d1
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 32 deletions.
21 changes: 14 additions & 7 deletions src/devices/ikea.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {Zcl} from 'zigbee-herdsman';
import {Definition} from '../lib/types';
import dataType from 'zigbee-herdsman/dist/zcl/definition/dataType';
import {
onOff, battery, iasZoneAlarm, identify, forcePowerSource,
temperature, humidity, occupancy, illuminance, windowCovering,
commandsOnOff, commandsLevelCtrl, commandsWindowCovering, pm25,
linkQuality, deviceEndpoints, bindCluster,
linkQuality, deviceEndpoints, deviceAddCustomCluster, bindCluster,
} from '../lib/modernExtend';
import {
ikeaConfigureRemote, ikeaLight, ikeaOta,
Expand Down Expand Up @@ -940,13 +940,20 @@ const definitions: Definition[] = [
vendor: 'IKEA',
description: 'VINDSTYRKA air quality and humidity sensor',
extend: [
deviceAddCustomCluster(
'pm25Measurement',
{
ID: 0x042a,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.singlePrec},
},
commands: {},
commandsResponse: {},
},
),
temperature(),
humidity(),
pm25({
// IKEA used conflicting date type on a standart attribute
attribute: {ID: 0x0000, type: dataType.singlePrec},
reporting: {min: '1_MINUTE', max: '2_MINUTES', change: 2},
}),
pm25({reporting: {min: '1_MINUTE', max: '2_MINUTES', change: 2}}),
ikeaVoc(),
identify(),
ikeaOta(),
Expand Down
51 changes: 26 additions & 25 deletions src/devices/sonoff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import fz from '../converters/fromZigbee';
import tz from '../converters/toZigbee';
import * as constants from '../lib/constants';
import * as reporting from '../lib/reporting';
import {binary, enumLookup, forcePowerSource, numeric, onOff, customTimeResponse, battery, ota} from '../lib/modernExtend';
import {
binary, enumLookup, forcePowerSource, numeric, onOff,
customTimeResponse, battery, ota, deviceAddCustomCluster,
} from '../lib/modernExtend';
import {Definition, Fz, KeyValue, KeyValueAny, ModernExtend, Tz} from '../lib/types';
import * as utils from '../lib/utils';
import {logger} from '../lib/logger';
Expand Down Expand Up @@ -803,6 +806,28 @@ const definitions: Definition[] = [
tz.thermostat_running_state,
],
extend: [
deviceAddCustomCluster(
'customSonoffTrvzb',
{
ID: 0xfc11,
attributes: {
childLock: {ID: 0x0000, type: Zcl.DataType.boolean},
tamper: {ID: 0x2000, type: Zcl.DataType.uint8},
illumination: {ID: 0x2001, type: Zcl.DataType.uint8},
openWindow: {ID: 0x6000, type: Zcl.DataType.boolean},
frostProtectionTemperature: {ID: 0x6002, type: Zcl.DataType.int16},
idleSteps: {ID: 0x6003, type: Zcl.DataType.uint16},
closingSteps: {ID: 0x6004, type: Zcl.DataType.uint16},
valveOpeningLimitVoltage: {ID: 0x6005, type: Zcl.DataType.uint16},
valveClosingLimitVoltage: {ID: 0x6006, type: Zcl.DataType.uint16},
valveMotorRunningVoltage: {ID: 0x6007, type: Zcl.DataType.uint16},
valveOpeningDegree: {ID: 0x600B, type: Zcl.DataType.uint8},
valveClosingDegree: {ID: 0x600C, type: Zcl.DataType.uint8},
},
commands: {},
commandsResponse: {},
},
),
binary({
name: 'child_lock',
cluster: 'customSonoffTrvzb',
Expand Down Expand Up @@ -910,30 +935,6 @@ const definitions: Definition[] = [
await endpoint.read('hvacThermostat', ['localTemperatureCalibration']);
await endpoint.read(0xFC11, [0x0000, 0x6000, 0x6002, 0x6003, 0x6004, 0x6005, 0x6006, 0x6007]);
},
onEvent: async (type, data, device, settings, state) => {
const name = 'customSonoffTrvzb';
if (!device.customClusters[name]) {
device.addCustomCluster(name, {
ID: 0xfc11,
attributes: {
childLock: {ID: 0x0000, type: Zcl.DataType.boolean},
tamper: {ID: 0x2000, type: Zcl.DataType.uint8},
illumination: {ID: 0x2001, type: Zcl.DataType.uint8},
openWindow: {ID: 0x6000, type: Zcl.DataType.boolean},
frostProtectionTemperature: {ID: 0x6002, type: Zcl.DataType.int16},
idleSteps: {ID: 0x6003, type: Zcl.DataType.uint16},
closingSteps: {ID: 0x6004, type: Zcl.DataType.uint16},
valveOpeningLimitVoltage: {ID: 0x6005, type: Zcl.DataType.uint16},
valveClosingLimitVoltage: {ID: 0x6006, type: Zcl.DataType.uint16},
valveMotorRunningVoltage: {ID: 0x6007, type: Zcl.DataType.uint16},
valveOpeningDegree: {ID: 0x600B, type: Zcl.DataType.uint8},
valveClosingDegree: {ID: 0x600C, type: Zcl.DataType.uint8},
},
commands: {},
commandsResponse: {},
});
}
},
},
{
zigbeeModel: ['S60ZBTPF'],
Expand Down
11 changes: 11 additions & 0 deletions src/lib/modernExtend.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Zcl} from 'zigbee-herdsman';
import {ClusterDefinition} from 'zigbee-herdsman/dist/zcl/definition/tstype';
import tz from '../converters/toZigbee';
import fz from '../converters/fromZigbee';
import * as globalLegacy from '../lib/legacy';
Expand Down Expand Up @@ -1669,6 +1670,16 @@ export function deviceEndpoints(args: {endpoints: {[n: string]: number}, multiEn
return result;
}

export function deviceAddCustomCluster(clusterName: string, clusterDefinition: ClusterDefinition): ModernExtend {
const onEvent: OnEvent = async (type, data, device, options, state: KeyValue) => {
if (!device.customClusters[clusterName]) {
device.addCustomCluster(clusterName, clusterDefinition);
}
};

return {onEvent, isModernExtend: true};
}

export function ignoreClusterReport(args: {cluster: string | number}): ModernExtend {
const fromZigbee: Fz.Converter[] = [{
cluster: args.cluster.toString(),
Expand Down

0 comments on commit 6d328d1

Please sign in to comment.