-
-
Save Koenkk/3d766bc346c74cb985b75cbb13eb7c6e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 fzLocal = { | |
battery: { | |
cluster: 'genPowerCfg', | |
type: ['attributeReport', 'readResponse'], | |
convert: (model, msg, publish, options, meta) => { | |
const payload = {}; | |
if (msg.data.hasOwnProperty('batteryPercentageRemaining') && (msg.data['batteryPercentageRemaining'] < 255)) { | |
// Some devices do not comply to the ZCL and report a | |
// batteryPercentageRemaining of 100 when the battery is full (should be 200). | |
// | |
// IKEA corrected this on newer remote fw version, but many people are still | |
// 2.2.010 which is the last version supporting group bindings. We try to be | |
// smart and pick the correct one for IKEA remotes. | |
let dontDividePercentage = false; | |
let percentage = msg.data['batteryPercentageRemaining']; | |
const fwVer = meta.device.softwareBuildID.split('.').map((e) => Number(e)); | |
if ((fwVer[0] < 2) || (fwVer[0] == 2 && fwVer[1] <= 3)) { | |
dontDividePercentage = true; | |
} | |
percentage = dontDividePercentage ? percentage : percentage / 2; | |
payload.battery = precisionRound(percentage, 2); | |
} | |
return payload; | |
}, | |
}, | |
styrbar_on: { | |
cluster: 'genOnOff', | |
type: 'commandOn', | |
convert: (model, msg, publish, options, meta) => { | |
if (utils.hasAlreadyProcessedMessage(msg, model)) return; | |
const arrowReleaseAgo = Date.now() - globalStore.getValue(msg.endpoint, 'arrow_release', 0); | |
if (arrowReleaseAgo > 700) { | |
return {action: 'on'}; | |
} | |
}, | |
}, | |
styrbar_arrow_release: { | |
cluster: 'genScenes', | |
type: 'commandTradfriArrowRelease', | |
options: [exposes.options.legacy()], | |
convert: (model, msg, publish, options, meta) => { | |
if (utils.hasAlreadyProcessedMessage(msg, model)) return; | |
globalStore.putValue(msg.endpoint, 'arrow_release', Date.now()); | |
const direction = globalStore.getValue(msg.endpoint, 'direction'); | |
if (direction) { | |
globalStore.clearValue(msg.endpoint, 'direction'); | |
const duration = msg.data.value / 1000; | |
const result = {action: `arrow_${direction}_release`, duration, action_duration: duration}; | |
if (!utils.isLegacyEnabled(options)) delete result.duration; | |
return result; | |
} | |
}, | |
}, | |
ikea_arrow_click: { | |
cluster: 'genScenes', | |
type: 'commandTradfriArrowSingle', | |
convert: (model, msg, publish, options, meta) => { | |
if (hasAlreadyProcessedMessage(msg, model)) return; | |
if (msg.data.value === 2) { | |
// This is send on toggle hold, ignore it as a toggle_hold is already handled above. | |
return; | |
} | |
const direction = msg.data.value === 257 ? 'left' : 'right'; | |
return {action: `arrow_${direction}_click`}; | |
}, | |
} | |
} | |
const definition = { | |
zigbeeModel: ['Remote Control N2'], | |
model: 'E2001/E2002', | |
vendor: 'IKEA', | |
description: 'STYRBAR remote control CUSTOM', | |
fromZigbee: [fzLocal.battery, fzLocal.styrbar_on, fz.command_off, fz.command_move, fz.command_stop, fzLocal.ikea_arrow_click, | |
fz.ikea_arrow_hold, fzLocal.styrbar_arrow_release], | |
exposes: [e.battery().withAccess(ea.STATE_GET), e.action(['on', 'off', 'brightness_move_up', 'brightness_move_down', | |
'brightness_stop', 'arrow_left_click', 'arrow_right_click', 'arrow_left_hold', | |
'arrow_right_hold', 'arrow_left_release', 'arrow_right_release'])], | |
toZigbee: [tz.battery_percentage_remaining], | |
// ota: ota.tradfri, | |
configure: async (device, coordinatorEndpoint, logger) => { | |
// Binding genOnOff is not required to make device send events. | |
const endpoint = device.getEndpoint(1); | |
const version = device.softwareBuildID.split('.').map((n) => Number(n)); | |
// https://github.com/Koenkk/zigbee2mqtt/issues/15725 | |
const v245OrLater = version[0] > 2 || (version[0] == 2 && version[1] >= 4); | |
const binds = v245OrLater ? ['genPowerCfg', 'genOnOff', 'genLevelCtrl', 'genScenes'] : ['genPowerCfg']; | |
await reporting.bind(endpoint, coordinatorEndpoint, binds); | |
await reporting.batteryPercentageRemaining(endpoint); | |
}, | |
}; | |
module.exports = definition; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment