Skip to content
Merged
Show file tree
Hide file tree
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
26 changes: 23 additions & 3 deletions src/devices/ikea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {Zcl} from "zigbee-herdsman";
import {repInterval} from "../lib/constants";
import {
addCustomClusterManuSpecificIkeaAirPurifier,
addCustomClusterManuSpecificIkeaSmartPlug,
addCustomClusterManuSpecificIkeaUnknown,
addCustomClusterManuSpecificIkeaVocIndexMeasurement,
ikeaAirPurifier,
Expand All @@ -14,6 +15,7 @@ import {
ikeaDotsClick,
ikeaLight,
ikeaMediaCommands,
ikeaModernExtend,
ikeaVoc,
styrbarCommandOn,
tradfriCommandsLevelCtrl,
Expand Down Expand Up @@ -633,16 +635,34 @@ export const definitions: DefinitionWithExtend[] = [
{model: "E2204", vendor: "IKEA", description: "E2204 (EU)"},
{model: "E2214", vendor: "IKEA", description: "E2214 (CH)"},
],
extend: [addCustomClusterManuSpecificIkeaUnknown(), m.onOff(), m.identify()],
extend: [
addCustomClusterManuSpecificIkeaSmartPlug(),
addCustomClusterManuSpecificIkeaUnknown(),
m.onOff(),
ikeaModernExtend.smartPlugChildLock(),
ikeaModernExtend.smartPlugLedEnable(),
m.identify(),
],
ota: true,
},
{
zigbeeModel: ["INSPELNING Smart plug"],
model: "E2206",
vendor: "IKEA",
description: "INSPELNING smart plug",
whiteLabel: [{model: "E2220", vendor: "IKEA", description: "INSPELNING smart plug (US)"}],
extend: [addCustomClusterManuSpecificIkeaUnknown(), m.onOff(), m.identify(), m.electricityMeter()],
whiteLabel: [
{model: "E2220", vendor: "IKEA", description: "INSPELNING smart plug (US)"},
{model: "E2224", vendor: "IKEA", description: "INSPELNING smart plug (CH)"},
],
extend: [
addCustomClusterManuSpecificIkeaSmartPlug(),
addCustomClusterManuSpecificIkeaUnknown(),
m.onOff(),
ikeaModernExtend.smartPlugChildLock(),
ikeaModernExtend.smartPlugLedEnable(),
m.identify(),
m.electricityMeter(),
],
ota: true,
configure: async (device) => {
const endpoint = device.getEndpoint(1);
Expand Down
85 changes: 84 additions & 1 deletion src/lib/ikea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {gt as semverGt, gte as semverGte, lt as semverLt, valid as semverValid}
import {Zcl} from "zigbee-herdsman";
import * as tz from "../converters/toZigbee";
import * as constants from "../lib/constants";
import {access, options, presets} from "../lib/exposes";
import {access, binary, options, presets} from "../lib/exposes";
import * as m from "../lib/modernExtend";
import * as reporting from "../lib/reporting";
import * as globalStore from "../lib/store";
Expand All @@ -15,6 +15,7 @@ import {
getFromLookup,
getTransition,
hasAlreadyProcessedMessage,
isDummyDevice,
isObject,
mapNumberRange,
postfixWithEndpointName,
Expand Down Expand Up @@ -895,6 +896,20 @@ export function addCustomClusterManuSpecificIkeaVocIndexMeasurement(): ModernExt
});
}

export function addCustomClusterManuSpecificIkeaSmartPlug(): ModernExtend {
return m.deviceAddCustomCluster("manuSpecificIkeaSmartPlug", {
ID: 0xfc85,
manufacturerCode: Zcl.ManufacturerCode.IKEA_OF_SWEDEN,
attributes: {
childLock: {ID: 0x0000, type: Zcl.DataType.BOOLEAN},
ledEnable: {ID: 0x0001, type: Zcl.DataType.BOOLEAN},
},

commands: {},
commandsResponse: {},
});
}

export interface IkeaUnknown {
attributes: never;
commands: never;
Expand Down Expand Up @@ -1007,3 +1022,71 @@ const trackFreezing = (next: Tz.Converter["convertSet"]) => {

return converter;
};

export const ikeaModernExtend = {
smartPlugChildLock: (args?: Partial<m.BinaryArgs<"manuSpecificIkeaSmartPlug">>) => {
const resultName = "child_lock";
const resultDescription = "Enables/disables physical input on the device.";

const result: ModernExtend = m.binary({
name: resultName,
cluster: "manuSpecificIkeaSmartPlug",
attribute: {ID: 0x0000, type: Zcl.DataType.BOOLEAN},
entityCategory: "config",
valueOff: ["UNLOCK", 0x00],
valueOn: ["LOCK", 0x01],
description: resultDescription,
zigbeeCommandOptions: {manufacturerCode: Zcl.ManufacturerCode.IKEA_OF_SWEDEN},
});

// NOTE: make exposes dynamic based on fw version
result.exposes = [
(device, options) => {
if (
!isDummyDevice(device) &&
device.softwareBuildID &&
semverValid(device.softwareBuildID) &&
semverGte(device.softwareBuildID, "2.4.25")
) {
return [binary(resultName, access.ALL, "LOCK", "UNLOCK").withDescription(resultDescription).withCategory("config")];
}
return [];
},
];

return result;
},

smartPlugLedEnable: (args?: Partial<m.BinaryArgs<"manuSpecificIkeaSmartPlug">>) => {
const resultName = "led_enable";
const resultDescription = "Enables/disables the led on the device.";

const result: ModernExtend = m.binary({
name: resultName,
cluster: "manuSpecificIkeaSmartPlug",
attribute: {ID: 0x0001, type: Zcl.DataType.BOOLEAN},
entityCategory: "config",
valueOff: ["FALSE", 0x00],
valueOn: ["TRUE", 0x01],
description: resultDescription,
zigbeeCommandOptions: {manufacturerCode: Zcl.ManufacturerCode.IKEA_OF_SWEDEN},
});

// NOTE: make exposes dynamic based on fw version
result.exposes = [
(device, options) => {
if (
!isDummyDevice(device) &&
device.softwareBuildID &&
semverValid(device.softwareBuildID) &&
semverGte(device.softwareBuildID, "2.4.25")
) {
return [binary(resultName, access.ALL, "TRUE", "FALSE").withDescription(resultDescription).withCategory("config")];
}
return [];
},
];

return result;
},
};