da ich bei mir die einzelnen attribute und kein komplettes json ausgeben lasse, hat mir das hier nicht wirklich weitergeholfen, aber schon ein wenig inspiriert. hier mal mein erster schnellschuss - bisher funktioniert alles, kann aber sicher noch etwas verbessert werden (datentyp, min/max-werte):
const mqtt = "mqtt.0";
const topic = "zigbee2mqtt";
const zigbee2mqtt = mqtt +"."+ topic;
const doNotGenerateSetStates = ["update-state", "availability", "linkquality"]
const doNotOverwriteExistingObjects = false;
var devices = JSON.parse(getState(zigbee2mqtt +".bridge.devices").val);
devices.forEach(device => {
if (device.friendly_name.length > 0)
{
var device_name = device.friendly_name.replaceAll("/", ".")
console.log(device_name)
//console.log({device})
if (device.type.toLowerCase() === "router")
{
console.log("ist router")
var datapointBase = zigbee2mqtt + "." + device_name;
if (existsObject(datapointBase)) {
console.log(datapointBase + " existiert")
var getPoints = $('[state.id=' + datapointBase + '.*]')
//console.log({getPoints})
getPoints.each(function (id, i) {
if (existsObject(id)) {
var attribute = id.split('.').pop();
if (doNotGenerateSetStates.includes(attribute.toLocaleLowerCase())) {
console.log("--ABBRUCH: " + attribute)
return;
}
var setMqttPath = topic + "/" + device.friendly_name + "/set/" + attribute;
var setId = datapointBase + ".set." + attribute;
if (existsObject(setId) && doNotOverwriteExistingObjects) {
console.log("--ABBRUCH (existiert bereits): " + attribute)
return;
}
var attributeSpecs = device.definition.exposes.find(data => data.hasOwnProperty('features')).features.find(data => data.name === attribute);
if (attributeSpecs === undefined) {
attributeSpecs = device.definition.exposes.find(data => data.name === attribute);
}
//console.log(attributeSpecs)
var getObj = getObject(id);
getObj._id = setId;
getObj.common.name = setMqttPath;
getObj.native.topic = setMqttPath;
if (attributeSpecs?.value_min != undefined) {
getObj.common.min = attributeSpecs.value_min;
}
if (attributeSpecs?.value_max != undefined) {
getObj.common.max = attributeSpecs.value_max;
}
if (attributeSpecs?.unit != undefined) {
getObj.common.unit = attributeSpecs.unit;
}
setObject(setId, getObj, function (err) {
if (err) console.error('Cannot write object: ' + err);
});
console.log(setId)
}
});
}
}
}
})
und das ergebnis:
[image: 1663745698723-11798552-73cb-4280-a4da-507c4819625f-image.png]
edit: ich war etwas ungehalten und habe min, max und unit schon hinzugeügt. mehr werte kann man ja bei bedarf analog dazu auslesen.
als nächstes kommt dann noch ein alias datenpunkt, der entsprechend read und write datenpunkte vereint.