NEWS
CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor
-
Fertig
Es fehlt nur noch die TPU-Dichtung unter dem Deckel. -
Jetzt brauche ich erstmal eine neue Idee!
-
Ich hatte noch einen CC2531 und ein paar DHT22 übrig.
Natürlich wieder mit Icon und eigenem Konverter
Ein Sensor mit 2m Kabel für die neue Werkstatt und einmal 5m Kabel, durch die Wand für den Außenbereich.
-
Hallo zusammen.
Ich habe mittlerweile ein paar eigene Zigbee Geräte in meinem Netzwerk. Klappt soweit sehr stabil.
Ich stehe nur vor einem 'Problem' bei einem externen Konverter. Kennst sich da jemand aus? Ich würde gern einen Wert direkt im Konverter umrechnen.Alles unter 300mm soll als 'true' und alles darüber als 'false' angezeigt werden. Mit einem Alias ist das kein Problem! Ich hätte es aber gern direkt in der Zigbee-Kachel anders stehen.
Ich messe hier in der Mähroboter-Garage, ob Roberta drin steht oder unterwegs ist.
So mache ich es zur Zeit (via Alias)
Ausschnitt vom Konverter. Könnte man es nicht schon direkt hier umrechnen?
Das wäre meine Wunschvorstellung (Photoshop)
-
@skvarel sagte in CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor:
Hallo zusammen.
[…]
Ausschnitt vom Konverter. Könnte man es nicht schon direkt hier umrechnen?
Kann man.
Dazu musst du 2 Dinge tun
- eine Funktion schreiben die die zigbee Nachricht abfängt um setzt
- das korrekte ‘expose’ dafür finden / definieren
Das hört sich jetzt sehr komplex an, ist es aber nicht.
- Du schaust dir die Funktion fz.ptvo_switch_analog_Input an. Wichtig sind die Parameter beim Aufruf sowie der rückgabewert
- du schreibst eine Funktion die mit den gleichen Parametern aufgerufen wird und rufst darin als erstes besagte fz… Funktion auf. Dann nimmst du den rückgabewert und baust den so um das deine Wunsch Bedingung erfüllt ist.
- Unter fromZigbee trägst du dann diese Funktion an Stelle der ptvo_switch_analog_Input ein.
- als letztes musst du schauen welcher Expose am besten dazu passt. Ich bin gerade unterwegs, kann da aber heute Nachmittag mal einen Vorschlag machen.
A.
-
@asgothian .. puhh, das klingt doch schon kompliziert.
-
Hier nochmal der aktuelle Konverter:
https://github.com/inventwo/custom-zigbee/blob/main/Converter/CC2531.US100.js
-
@skvarel sagte in CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor:
@asgothian .. puhh, das klingt doch schon kompliziert.
Es ist einfacher als du denkst. Ich hatte bei der Beschreibung aber auch einen Denkfehler. Versuch mal so:
const fzlocal = { ptvo_switch_analog_to_boolean: { cluster: 'genAnalogInput', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const value =( msg.data['presentValue'] > 300 ); const action = (value ? 'occupied':'free'); return {action: postfixWithEndpointName(action, msg, model, meta)}; }, }; const device = { zigbeeModel: ['CC2531.US100'], model: 'CC2531.US100', vendor: 'inventwo', description: '[CC2531 w. US-100 Sensor](https://github.com/inventwo/custom-zigbee)', fromZigbee: [fz.ignore_basic_report, fz.ptvo_switch_uart, fz.ptvo_switch_analog_input,fzlocal.ptvo_switch_analog_to_boolean], toZigbee: [tz.ptvo_switch_trigger, tz.ptvo_switch_uart,], exposes: [ exposes.numeric('l1', ea.STATE).withDescription('Innenraummessung').withUnit('mm'), exposes.action(['occupied'].withDescription('Innenraum belegt'), exposes.action(['free'].withDescription('Innenraum frei'), ], meta: { multiEndpoint: true, }, endpoint: (device) => { return { l1: 1, }; }, configure: async (device, coordinatorEndpoint, logger) => { const endpoint = device.getEndpoint(1); await endpoint.read('genBasic', ['modelId', 'swBuildId', 'powerSource']); }, };
A.
Nachtrag: ich hab das icon aus dem code genommen, und den Kopf nicht mit angegeben - das sollte aber kein problem für Dich sein
Nachtrag2: ich hatte noch einen Denkfehler - ist jetzt korrigiert.
-
@asgothian .. teste ich!
-
@asgothian .. das funktioniert leider überhaupt nicht
Sobald ich deine Teile einsetze, kommt gar nichts mehr an. Bei dir waren noch ein paar Klammern offen. Die habe ich geschlossen.
So hatte ich den Code verwendet:
const fzlocal = { ptvo_switch_analog_to_boolean: { cluster: 'genAnalogInput', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const value =( msg.data['presentValue'] > 300 ); const action = (value ? 'occupied':'free'); return {action: postfixWithEndpointName(action, msg, model, meta)}; }, } }; const device = { zigbeeModel: ['CC2531.US100'], model: 'CC2531.US100', vendor: 'inventwo', description: '[CC2531 w. US-100 Sensor](https://github.com/inventwo/custom-zigbee)', fromZigbee: [fz.ignore_basic_report, fz.ptvo_switch_uart, fz.ptvo_switch_analog_input, fzlocal.ptvo_switch_analog_to_boolean], toZigbee: [tz.ptvo_switch_trigger, tz.ptvo_switch_uart,], exposes: [ exposes.numeric('l1', ea.STATE).withDescription('Innenraummessung').withUnit('mm'), exposes.action(['occupied']).withDescription('Innenraum belegt'), exposes.action(['free']).withDescription('Innenraum frei'), ], meta: { multiEndpoint: true, }, endpoint: (device) => { return { l1: 1, }; }, configure: async (device, coordinatorEndpoint, logger) => { const endpoint = device.getEndpoint(1); await endpoint.read('genBasic', ['modelId', 'swBuildId', 'powerSource']); }, };
-
@skvarel gibt es Meldungen im log ? Ich bin wieder unterwegs und schau mal wenn ich wieder zu Hause bin
-
@skvarel ich hab nochmal was angepasst. Versuch bitte mal so:
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters'); const zigbeeHerdsmanUtils = require('zigbee-herdsman-converters/lib/utils'); const exposes = zigbeeHerdsmanConverters['exposes'] || require("zigbee-herdsman-converters/lib/exposes"); const ea = exposes.access; const e = exposes.presets; const modernExposes = (e.hasOwnProperty('illuminance_lux'))? false: true; const fz = zigbeeHerdsmanConverters.fromZigbeeConverters || zigbeeHerdsmanConverters.fromZigbee; const tz = zigbeeHerdsmanConverters.toZigbeeConverters || zigbeeHerdsmanConverters.toZigbee; const ptvo_switch = (zigbeeHerdsmanConverters.findByModel)?zigbeeHerdsmanConverters.findByModel('ptvo.switch'):zigbeeHerdsmanConverters.findByDevice({modelID: 'ptvo.switch'}); fz.legacy = ptvo_switch.meta.tuyaThermostatPreset; fz.ptvo_on_off = { cluster: 'genOnOff', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { if (msg.data.hasOwnProperty('onOff')) { const channel = msg.endpoint.ID; const endpointName = `l${channel}`; const binaryEndpoint = model.meta && model.meta.binaryEndpoints && model.meta.binaryEndpoints[endpointName]; const prefix = (binaryEndpoint) ? model.meta.binaryEndpoints[endpointName] : 'state'; const property = `${prefix}_${endpointName}`; if (binaryEndpoint) { return {[property]: msg.data['onOff'] === 1}; } return {[property]: msg.data['onOff'] === 1 ? 'ON' : 'OFF'}; } }, }; const fzlocal = { local_analog_switch: { cluster: 'genAnalogInput', type: ['attributeReport', 'readResponse'], convert: (model, msg, publish, options, meta) => { const payload = {}; const channel = msg.endpoint.ID; const name = `l${channel}`; const endpoint = msg.endpoint; payload[name] = precisionRound(msg.data['presentValue'], 3); payload[`contact_${channel}`] = (msg.data['presentValue'] < 300) const cluster = 'genLevelCtrl'; if (endpoint && (endpoint.supportsInputCluster(cluster) || endpoint.supportsOutputCluster(cluster))) { payload['brightness_' + name] = msg.data['presentValue']; } else if (msg.data.description !== undefined) { const data1 = msg.data['description']; if (data1) { const data2 = data1.split(','); const devid = data2[1]; const unit = data2[0]; if (devid) { payload['device_' + name] = devid; } const valRaw = msg.data['presentValue']; if (unit) { let val = precisionRound(valRaw, 1); const nameLookup = { C: 'temperature', '%': 'humidity', m: 'altitude', Pa: 'pressure', ppm: 'quality', psize: 'particle_size', V: 'voltage', A: 'current', Wh: 'energy', W: 'power', Hz: 'frequency', pf: 'power_factor', lx: 'illuminance', }; let nameAlt = ''; if (unit === 'A' || unit === 'pf') { if (valRaw < 1) { val = precisionRound(valRaw, 3); } } if (unit.startsWith('mcpm') || unit.startsWith('ncpm')) { const num = unit.substr(4, 1); nameAlt = num === 'A' ? unit.substr(0, 4) + '10' : unit; val = precisionRound(valRaw, 2); } else { nameAlt = nameLookup[unit]; } if (nameAlt === undefined) { const valueIndex = parseInt(unit, 10); if (!isNaN(valueIndex)) { nameAlt = 'val' + unit; } } if (nameAlt !== undefined) { payload[nameAlt + '_' + name] = val; } } } } return payload; }, }, } const device = { zigbeeModel: ['CC2531.US100'], model: 'CC2531.US100', vendor: 'inventwo', description: '[CC2531 w. US-100 Sensor](https://github.com/inventwo/custom-zigbee)', fromZigbee: [fz.ignore_basic_report, fz.ptvo_switch_uart, fzlocal.local_analog_switch,], toZigbee: [tz.ptvo_switch_trigger, tz.ptvo_switch_uart,], exposes: [ exposes.numeric('l1', ea.STATE).withDescription('Innenraummessung').withUnit('mm'), e.contact().withEndpoint('l1'), ], meta: { multiEndpoint: true, }, endpoint: (device) => { return { l1: 1, }; }, configure: async (device, coordinatorEndpoint, logger) => { const endpoint = device.getEndpoint(1); await endpoint.read('genBasic', ['modelId', 'swBuildId', 'powerSource']); }, }; module.exports = device;
(wieder ohne icon)
-
@asgothian .. Meldungen im Log:
z2m: Exception while calling fromZigbee converter: precisionRound is not defined}
So sieht es beim neuen Code aus:
-
@skvarel das ist nachdem du die Fehlermeldung eliminiert hast oder vorher ? einfach den Aufruf zu precisionRound entfernen und den Wert direkt nutzen
aus
precisionRound(msg.data['presentValue'], 3);
wird
msg.data['presentValue'];
A.
-
@asgothian sagte in CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor:
msg.data['presentValue'];
Der Fehler ist jetzt weg! Die Änderung hat geholfen.
Es bleibt aber bei N/A
-
@skvarel Du bist doch auf dem ioBroker discord. Wollen wir uns da kurz zusammen hängen - geht einfacher als hier per posts.
Ich bin einfach mal im '2 user only' channel
A.
-
@asgothian .. heute schaffe ich es leider nicht mehr. Morgen hätte ich Zeit.
-
@skvarel morgen tuts. Wann ?
-
@asgothian .. ab späten Vormittag. Uhrzeit ist mir egal. Ich habe nichts weiter vor!
-
@skvarel sagte in CC2530/CC2531 als Custom-Zigbee-Aktor/Sensor:
@asgothian .. ab späten Vormittag. Uhrzeit ist mir egal. Ich habe nichts weiter vor!
sagen wir 11 ?