CODE
exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const lumi = require('zigbee-herdsman-converters/lib/lumi');
const {manufacturerCode} = lumi;
const tzLocal = {
set_max_range: {
key: ['max_range'],
convertSet: async (entity, key, value, meta) => {
const intValue = Math.round(value * 100);
await entity.write('manuSpecificLumi', {0x015B: {value: intValue, type: 0x23}}, {manufacturerCode: manufacturerCode});
return {state: {max_range: value}};
},
},
};
const fzLocal = {
fp11_presence: {
cluster: 'manuSpecificLumi',
type: ['readResponse', 'attributeReport'],
convert: (model, msg, publish, options, meta) => {
console.info("msg.data=", msg.data);
let payload = {};
for (const key in msg.data) {
const value = msg.data[key];
// Logging voor specifieke keys
const hexKeysToLog = [0x0160, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E];
if (hexKeysToLog.includes(key)) {
console.log(`Hex key detected: 0x${key} with value: ${value}`);
}
if (key == 322) { //322 / 0x0142
payload["presence"] = value == 1;
}
if (key == 351) { //351 / 0x015F
// distance in cm, formatted to 2 decimal places
payload["target_distance"] = parseFloat((0.01 * value).toFixed(2));
}
if (key == 352) { //352 / 0x0160
// Map the value of 352 to the corresponding string
const bewegingValues = ['unknown 0', 'unknown 1', 'no presence', 'movement', 'no movement'];
payload["movement"] = bewegingValues[value] || `unknown ${value}`;
}
if (key === 232) { // 232 / 0x00E8
payload["restart_device"] = Boolean(value);
console.log(`Restart device detected: 0x00E8 with value: ${value}`);
}
}
return payload;
},
},
};
const definition = {
zigbeeModel: ['lumi.sensor_occupy.agl1'],
model: 'lumi.sensor_occupy.agl1',
vendor: 'Aqara',
description: 'Presence sensor FP1E',
extend: [lumi.modernExtend.lumiZigbeeOTA()],
fromZigbee: [
fzLocal.fp11_presence,
lumi.fromZigbee.lumi_specific,
lumi.fromZigbee.lumi_presence_region_events,
],
toZigbee: [
{
key: ['reset_presence'],
convertSet: async (entity, key, value, meta) => {
await entity.write('manuSpecificLumi', {0x0157: {value: 1, type: 0x20}});
return {state: {reset_presence: true}};
},
},
tzLocal.set_max_range,
lumi.toZigbee.lumi_presence,
lumi.toZigbee.lumi_monitoring_mode,
lumi.toZigbee.lumi_motion_sensitivity,
],
exposes: [
e.binary('reset_presence', ea.STATE_SET, 'PRESS', 'RELEASE').withDescription('Reset Presence (press to reset)'),
e.presence().withAccess(ea.STATE_GET),
e.device_temperature(),
e.power_outage_count(),
e.numeric('target_distance', ea.STATE_GET).withUnit('m').withDescription('Target distance'),
e.enum('movement', ea.STATE_GET, ['Unknown 0', 'Unknown 1', 'No presence', 'Movement', 'No movement'])
.withDescription('Is someone on the move'),
e.numeric('max_range', ea.STATE_SET)
.withValueMin(0)
.withValueMax(6.00)
.withValueStep(0.30)
.withUnit('m')
.withDescription('Adjust the slider between 0m and 6m with steps of 30cm'),
],
configure: async (device, coordinatorEndpoint) => {
device.softwareBuildID = `${device.applicationVersion}`;
device.save();
const endpoint = device.getEndpoint(1);
await endpoint.read('manuSpecificLumi', [0x0142], {manufacturerCode: manufacturerCode});
},
meta: {},
};
module.exports = definition;
After select press to start ai spatial it no longer detects false presence when the ceiling fan & ac turned on.
I still need to find the best angle/position for it, just place on bedside table but sometimes it doesn’t detect presence. Might need to place it higher or corner angle