-
Notifications
You must be signed in to change notification settings - Fork 316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add VOC/CO/NO cluster #1287
Add VOC/CO/NO cluster #1287
Conversation
Did you already see any Zigbee devices which use these? |
I'm actually making my own with https://sensirion.com/products/catalog/SEN66 + https://github.com/espressif/esp-idf |
Since it's not an official Zigbee cluster, I would then use the custom cluster API, example |
Alright, thanks for your answer ! PS: Found a sensor with VOC https://www.ikea.com/us/en/p/vindstyrka-air-quality-sensor-smart-30498239/ |
I think we did not support the custom clusters at that time. |
Alright, understood, thanks ! Will try to work on adding a new device/clusters and submit a new PR soon then ! |
Hey again Thank you very much ! const {
temperature,
humidity,
pm25,
co2,
numeric,
deviceAddCustomCluster
} = require('zigbee-herdsman-converters/lib/modernExtend');
const {Zcl} = require('zigbee-herdsman');
const addCustomClusters = () => [
deviceAddCustomCluster('vocMeasurement', {
ID: 0xFC01,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
}
}),
deviceAddCustomCluster('pm1Measurement', {
ID: 0xFC02,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
}
}),
deviceAddCustomCluster('pm4Measurement', {
ID: 0xFC03,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
}
}),
deviceAddCustomCluster('pm10Measurement', {
ID: 0xFC04,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
}
}),
deviceAddCustomCluster('noxMeasurement', {
ID: 0xFC05,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
}
})
];
const definition = {
zigbeeModel: ['SEN66'],
model: 'SEN66',
vendor: 'Sensirion',
description: 'Custom multi-sensor device with VOC, PM1, PM4, PM10, and NOx measurements',
extend: [
temperature(),
humidity(),
pm25(),
co2(),
...addCustomClusters(),
numeric({
name: 'voc',
cluster: 'vocMeasurement',
attribute: 'measuredValue',
unit: 'ppb',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured VOC value'
}),
numeric({
name: 'pm1',
cluster: 'pm1Measurement',
attribute: 'measuredValue',
unit: 'µg/m³',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured PM1 value'
}),
numeric({
name: 'pm4',
cluster: 'pm4Measurement',
attribute: 'measuredValue',
unit: 'µg/m³',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured PM4 value'
}),
numeric({
name: 'pm10',
cluster: 'pm10Measurement',
attribute: 'measuredValue',
unit: 'µg/m³',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured PM10 value'
}),
numeric({
name: 'nox',
cluster: 'noxMeasurement',
attribute: 'measuredValue',
unit: 'ppb',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured NOx value'
})
],
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
const clusters = [0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05];
for (const cluster of clusters) {
try {
await endpoint.bind(cluster, coordinatorEndpoint);
await endpoint.configureReporting(cluster, [{
attribute: 'measuredValue',
minimumReportInterval: 10,
maximumReportInterval: 3600,
reportableChange: 1
}]);
} catch (error) {
logger.warn(`Failed to configure cluster ${cluster}: ${error}`);
}
}
},
meta: {
configureKey: 1,
},
};
module.exports = definition; |
This looks correct, doesn't it work? |
Try using a different cluster name, names from
|
Wow, after a few changes, it finally works smoothly, thank you very much ! PS: I'm also waiting ESP-IDF to add support for official clusters, but I don't think it will happen anytime soon. espressif/esp-zigbee-sdk#531 const {
temperature,
humidity,
pm25,
co2,
numeric,
deviceAddCustomCluster
} = require('zigbee-herdsman-converters/lib/modernExtend');
const {Zcl} = require('zigbee-herdsman');
const {logger} = require('zigbee-herdsman-converters/lib/logger');
const NS = 'zhc:sensirion';
const addCustomClusters = () => [
deviceAddCustomCluster('sen66VocMeas', {
ID: 0xFC01,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
},
commands: {},
commandsResponse: {},
}),
deviceAddCustomCluster('sen66Pm1Meas', {
ID: 0xFC02,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
},
commands: {},
commandsResponse: {},
}),
deviceAddCustomCluster('sen66Pm4Meas', {
ID: 0xFC03,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
},
commands: {},
commandsResponse: {},
}),
deviceAddCustomCluster('sen66Pm10Meas', {
ID: 0xFC04,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
},
commands: {},
commandsResponse: {},
}),
deviceAddCustomCluster('sen66NoxMeas', {
ID: 0xFC05,
attributes: {
measuredValue: {ID: 0x0000, type: Zcl.DataType.SINGLE_PREC}
},
commands: {},
commandsResponse: {},
})
];
const definition = {
zigbeeModel: ['SEN66'],
model: 'SEN66',
vendor: 'Sensirion',
description: 'Custom multi-sensor device with VOC, PM1, PM4, PM10, and NOx measurements',
extend: [
temperature(),
humidity(),
pm25(),
co2(),
...addCustomClusters(),
numeric({
name: 'voc',
cluster: 'sen66VocMeas',
attribute: 'measuredValue',
unit: 'ppb',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured VOC value'
}),
numeric({
name: 'pm1',
cluster: 'sen66Pm1Meas',
attribute: 'measuredValue',
unit: 'µg/m³',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured PM1 value'
}),
numeric({
name: 'pm4',
cluster: 'sen66Pm4Meas',
attribute: 'measuredValue',
unit: 'µg/m³',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured PM4 value'
}),
numeric({
name: 'pm10',
cluster: 'sen66Pm10Meas',
attribute: 'measuredValue',
unit: 'µg/m³',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured PM10 value'
}),
numeric({
name: 'nox',
cluster: 'sen66NoxMeas',
attribute: 'measuredValue',
unit: 'ppb',
access: 'STATE_GET',
reporting: {
min: 10,
max: 3600,
change: 1
},
description: 'Measured NOx value'
})
],
configure: async (device, coordinatorEndpoint) => {
const endpoint = device.getEndpoint(1);
const clusters = [0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05];
for (const cluster of clusters) {
try {
await endpoint.bind(cluster, coordinatorEndpoint);
await endpoint.configureReporting(cluster, [{
attribute: 'measuredValue',
minimumReportInterval: 10,
maximumReportInterval: 3600,
reportableChange: 1
}]);
logger.info(`Configured cluster ${cluster} for device ${device.ieeeAddress}`, NS);
} catch (error) {
logger.warning(`Failed to configure cluster ${cluster}: ${error}`, NS);
}
}
},
meta: {
configureKey: 1,
},
};
module.exports = definition; |
If instructions how to make this device are available, it can be added to https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/devices/custom_devices_diy.ts |
Alright, so I just published the instructions for the device here: https://github.com/RobinFrcd/Senesp98 With Z2M custom device here: https://github.com/RobinFrcd/Senesp98/blob/master/zigbee2mqtt/sen66.js Would it make sense to you if I add it to |
Yes, feel free to make a PR to custom devices and a PR to z2m.io with the links to your GH repo. |
Hi,
So the VOC/NO/CO Clusters are not defined in Zigbee, but are in Matter.
As said in Koenkk/zigbee2mqtt#23339 I just added these new clusters, is that fine for you ? @Koenkk
Thanks !