Edit: Lösung bei Post #3Nabend meine lieben - da bin ich mal wieder :))
Hab mir einen Ultraschallsensor für meine Zisterne gekauft - EPTTECH TLC2206.
Tja - wird zwar von Zigbee2MQTT erkannt und auch hinzugefügt - auch bei FHEM natürlich.
Das Teil wird nur leider in der Weboberfläche nicht unterstützt und es kommen keine Daten an.
Jetzt hab mich mich etwas belesen und sehe den Wald schon wieder vor lauter Bäume nicht.
Bin jetzt soweit gekommen, das dies eine externe Konfiguration braucht.
Kann mich hierbei jemand unterstützen ?
Hat evtl jemand auch so ein Teil?
TS0601.jpg
Edit: hier habe ich eine Anleitung über das selbe Gerät gefunden: Link (https://community.jeedom.com/t/tlc2206zb-niveau-deau-zigbee-zigbee2mqtt/134518)
Leider versteh ich trotz Übersetzer nicht ganz was ich machen soll.
- eine Datei namens
TZE200.js
anlegen im selben Verzeichnis wo die configuration.yml ist? - den code wie er schreibt in die Datei eintragen?
- TZE200.js im Reiter ,,Externe Konverter" zu den Z2M-Einstellungen hinzufügen???? - wie das??
Vlt kann jemand damit was anfangen - und mir das auf deutsch erklären :))
Durch das Update von z2m 1.4x auf 2.x hat sich sowohl der vorgesehen Speicherort für solche externen Erweiterungen (genau wie für externe Converter) als auch die Signatur solcher Erweiterungen geändert.
Nachzulesen in der Doku zu den "breaking changes" bei diesem Update beschrieben.
Das sollte man zumindest mal gelesen haben, anstatt einfach nur kopf- und planlos mit copy&paste zu experimentieren...
Zitat von: betateilchen am 09 April 2025, 15:53:07Durch das Update von z2m 1.4x auf 2.x hat sich sowohl der vorgesehen Speicherort für solche externen Erweiterungen (genau wie für externe Converter) als auch die Signatur solcher Erweiterungen geändert.
Nachzulesen in der Doku zu den "breaking changes" bei diesem Update beschrieben.
Das sollte man zumindest mal gelesen haben, anstatt einfach nur kopf- und planlos mit copy&paste zu experimentieren...
Erstmal vielen Dank für deine Antwort.
In der Tat habe ich das sogar gelesen - und genau wie du auch schreibst, möchte ich nicht einfach "nur kopf- und planlos mit copy&paste zu experimentieren" - daher schreib ich ja hier. Nur leider fehlt mir in solchen Dingen manchmal oder auch oft das Verständins.
Ich würde das jetzt so verstehen, dass ich in /data einen Ordner erstellen muss namens: external_extensions
... hier dann die TZE200.js speichern?
Das Frontend verwirrt mich auch, da ich unter dem Gerät z.B. generated_external_definition zwar einen code eingeben kann - aber nicht speichern kann, da finde ich keinen Button dafür.
Edit: Wenn ich z.B. die Datei direkt im Frontend unter Erweiterungen anlege - dann speichert er diese auch richtig im ordner /data/external_extensions
... nach einen Neustart bringt mir dies leider keine Änderung am Gerät .. bleibt auf Nicht unterstützt und bringt keine Daten
Edit die 2.
... OK, ich sehe es gibt anscheinend Fehler in der js. Datei. - sie lässt sich nicht speichern.
Wenn ich die Erweiterung erstelle, kommt bereits folgender Inhalt:
class MyExampleExtension1744209716212 {
constructor(
zigbee,
mqtt,
state,
publishEntityState,
eventBus,
enableDisableExtension,
restartCallback,
addExtension,
settings,
logger,
) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
this.eventBus = eventBus;
this.enableDisableExtension = enableDisableExtension;
this.restartCallback = restartCallback;
this.addExtension = addExtension;
this.settings = settings;
this.logger = logger;
this.logger.info('Loaded MyExampleExtension1744209716212');
this.mqttBaseTopic = this.settings.get().mqtt.base_topic;
}
/**
* Called when the extension starts (on Zigbee2MQTT startup, or when the extension is saved at runtime)
*/
start() {
this.mqtt.publish('example/extension', 'hello from MyExampleExtension1744209716212');
// all possible events can be seen here: https://github.com/Koenkk/zigbee2mqtt/blob/master/lib/eventBus.ts
this.eventBus.onStateChange(this, this.onStateChange.bind(this));
}
/**
* Called when the extension stops (on Zigbee2MQTT shutdown, or when the extension is saved/removed at runtime)
*/
stop() {
this.eventBus.removeListeners(this);
}
async onStateChange(data) {
// see typing (properties) here: https://github.com/Koenkk/zigbee2mqtt/blob/master/lib/types/types.d.ts => namespace eventdata
const { entity, update } = data;
// example how to toggle state
if (entity.ID === '0x00158d000224154d') {
this.logger.info(`State changed for 0x00158d000224154d: ${JSON.stringify(data)}`);
// state changed for some device (example: clicked a button)
if (update.action === 'single') {
const myLampIeeAddr = '0x00124b001e73227f'; // change this
this.mqtt.onMessage(`${this.mqttBaseTopic}/${myLampIeeAddr}/set`, JSON.stringify({ state: 'toggle' }));
}
}
}
}
module.exports = MyExampleExtension1744209716212;
in die müsste jetzt die folgenden parameter eingebaut werden (wenn ich richtig liege):
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 {} = require("zigbee-herdsman-converters/lib/modernExtend");
const e = exposes.presets;
const ea = exposes.access;
const tuya = require("zigbee-herdsman-converters/lib/tuya");
const utils = require("zigbee-herdsman-converters/lib/utils");
const dp = {
instalationHeight: 19,
liquidDepthMax: 21,
maxSet: 7,
miniSet: 8,
};
const tzdatapoints = {
key: [
"installation_height",
"liquid_depth_max",
"max_set",
"mini_set",
],
convertSet: async (entity, key, value, meta) => {
switch (key) {
case "installation_height": {
await tuya.sendDataPointValue(entity, dp.instalationHeight, value);
break;
}
case "liquid_depth_max": {
await tuya.sendDataPointValue(entity, dp.liquidDepthMax, value);
break;
}
case "max_set": {
await tuya.sendDataPointValue(entity, dp.maxSet, value);
break;
}
case "mini_set": {
await tuya.sendDataPointValue(entity, dp.miniSet, value);
break;
}
}
},
};
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: "TS0601",
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: "_TZE200_lvkk0hdg",
},
],
model: "TS0601_tlc2206zb",
vendor: "TuYa",
whiteLabel: [
{
vendor: "EPTTECH",
model: "TLC2206-ZB",
},
],
description: "EPTTECH Tank Level Monitor Zigbee",
fromZigbee: [tuya.fz.datapoints],
// toZigbee: [tuya.tz.datapoints],
toZigbee: [tzdatapoints],
onEvent: tuya.onEventSetTime, // Add this if you are getting no converter for 'commandMcuSyncTime'
configure: tuya.configureMagicPacket,
exposes: [
// Here you should put all functionality that your device exposes
e
.numeric("liquid_level_percent", ea.STATE)
.withUnit("%")
.withDescription("Liquid level percentage"),
e
.numeric("liquid_depth", ea.STATE)
.withUnit("m")
.withDescription("Liquid Depth"),
e
.enum("liquid_state", ea.STATE, ["low", "normal", "high"])
.withDescription("Liquid State"),
e
.numeric("installation_height", ea.STATE_SET)
.withUnit("mm")
.withDescription("Height from sensor to tank bottom")
.withValueMin(100)
.withValueMax(3000)
.withValueStep(1),
e
.numeric("mini_set", ea.STATE_SET)
.withUnit("%")
.withDescription("Liquid minimal percentage")
.withValueMin(0)
.withValueMax(100)
.withValueStep(1),
e
.numeric("max_set", ea.STATE_SET)
.withUnit("%")
.withDescription("Liquid max percentage")
.withValueMin(0)
.withValueMax(100)
.withValueStep(1),
e
.numeric("liquid_depth_max", ea.STATE_SET)
.withUnit("mm")
.withDescription("Height from sensor to liquid level")
.withValueMin(100)
.withValueMax(2000)
.withValueStep(1),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[22, "liquid_level_percent", tuya.valueConverter.raw],
[2, "liquid_depth", tuya.valueConverter.divideBy100],
[
1,
"liquid_state",
tuya.valueConverterBasic.lookup({ low: 1, normal: 0, high: 2 }),
],
[19, "installation_height", tuya.valueConverter.raw],
[7, "max_set", tuya.valueConverter.raw],
[8, "mini_set", tuya.valueConverter.raw],
[21, "liquid_depth_max", tuya.valueConverter.raw],
],
},
extend: [
// A preferred new way of extending functionality.
],
};
module.exports = definition;
Wenn ich nur dies eingebe kommt folgender Fehler: modul is not a constructor.
Könnte mir jemand die .js anpassen? hab jetzt schon einiges Probiert aber komm auf keine Lösung
Auf Github hat jemand da eine Lösung über die yaml Datei geschrieben - siehe Hier: LINK (https://github.com/Koenkk/zigbee2mqtt/issues/21015#issuecomment-2781439165)
1. Go to developer tools
2. Actions
3. Select 'mqtt.publish'
4. Click 'GO TO YAML MODE'
5. Paste
{
"name": "TLC2206ZB.js",
"code": "const exposes = require(\"zigbee-herdsman-converters/lib/exposes\");\nconst {} = require(\"zigbee-herdsman-converters/lib/modernExtend\");\nconst e = exposes.presets;\nconst ea = exposes.access;\nconst tuya = require(\"zigbee-herdsman-converters/lib/tuya\");\n\nconst definition = {\n fingerprint: tuya.fingerprint(\"TS0601\", [\"_TZE200_lvkk0hdg\"]),\n model: \"TS0601_tlc2206zb\",\n vendor: \"TuYa\",\n whiteLabel: [\n {\n vendor: \"EPTTECH\",\n model: \"TLC2206-ZB\",\n },\n ],\n description: \"EPTTECH Tank Level Monitor Zigbee\",\n fromZigbee: [tuya.fz.datapoints],\n toZigbee: [tuya.tz.datapoints],\n onEvent: tuya.onEventSetTime,\n configure: tuya.configureMagicPacket,\n exposes: [\n e\n .numeric(\"liquid_level_percent\", ea.STATE)\n .withUnit(\"%\")\n .withDescription(\"Liquid level percentage\"),\n e\n .numeric(\"liquid_depth\", ea.STATE)\n .withUnit(\"m\")\n .withDescription(\"Liquid Depth\"),\n e\n .enum(\"liquid_state\", ea.STATE, [\"low\", \"normal\", \"high\"])\n .withDescription(\"Liquid State\"),\n\n e\n .numeric(\"installation_height\", ea.STATE_SET)\n .withUnit(\"mm\")\n .withDescription(\"Height from sensor to tank bottom\")\n .withValueMin(100)\n .withValueMax(3000)\n .withValueStep(1),\n e\n .numeric(\"mini_set\", ea.STATE_SET)\n .withUnit(\"%\")\n .withDescription(\"Liquid minimal percentage\")\n .withValueMin(0)\n .withValueMax(100)\n .withValueStep(1),\n e\n .numeric(\"max_set\", ea.STATE_SET)\n .withUnit(\"%\")\n .withDescription(\"Liquid max percentage\")\n .withValueMin(0)\n .withValueMax(100)\n .withValueStep(1),\n e\n .numeric(\"liquid_depth_max\", ea.STATE_SET)\n .withUnit(\"mm\")\n .withDescription(\"Height from sensor to liquid level\")\n .withValueMin(100)\n .withValueMax(2000)\n .withValueStep(1),\n ],\n meta: {\n // All datapoints go in here\n tuyaDatapoints: [\n [22, \"liquid_level_percent\", tuya.valueConverter.raw],\n [2, \"liquid_depth\", tuya.valueConverter.divideBy100],\n [\n 1,\n \"liquid_state\",\n tuya.valueConverterBasic.lookup({ low: 1, normal: 0, high: 2 }),\n ],\n [19, \"installation_height\", tuya.valueConverter.raw],\n [7, \"max_set\", tuya.valueConverter.raw],\n [8, \"mini_set\", tuya.valueConverter.raw],\n [21, \"liquid_depth_max\", tuya.valueConverter.raw],\n ],\n },\n extend: [\n // A preferred new way of extending functionality.\n ],\n};\n\nmodule.exports = definition;"
}
Aber ich find nicht mal mehr die yaml über das Frontend, und hab auch schlechte Erfahrungen diese zu bearbeiten
LÖSUNG
Gerät aus Zigbee entfernen! ansonsten müsst ihr das eh nach den folgenden Schritten tun.
Ordner erstellen in /opt/zigbee2mqtt/data/external_converters
In dem Ordner die .js Datei anlegen.
mein code sieht so aus:
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 {} = require("zigbee-herdsman-converters/lib/modernExtend");
const e = exposes.presets;
const ea = exposes.access;
const tuya = require("zigbee-herdsman-converters/lib/tuya");
const utils = require("zigbee-herdsman-converters/lib/utils");
const dp = {
instalationHeight: 19,
liquidDepthMax: 21,
maxSet: 7,
miniSet: 8,
};
const tzdatapoints = {
key: [
"installation_height",
"liquid_depth_max",
"max_set",
"mini_set",
],
convertSet: async (entity, key, value, meta) => {
switch (key) {
case "installation_height": {
await tuya.sendDataPointValue(entity, dp.instalationHeight, value);
break;
}
case "liquid_depth_max": {
await tuya.sendDataPointValue(entity, dp.liquidDepthMax, value);
break;
}
case "max_set": {
await tuya.sendDataPointValue(entity, dp.maxSet, value);
break;
}
case "mini_set": {
await tuya.sendDataPointValue(entity, dp.miniSet, value);
break;
}
}
},
};
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: "TS0601",
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: "_TZE200_lvkk0hdg",
},
],
model: "TS0601_tlc2206zb",
vendor: "TuYa",
whiteLabel: [
{
vendor: "EPTTECH",
model: "TLC2206-ZB",
},
],
description: "EPTTECH Tank Level Monitor Zigbee",
fromZigbee: [tuya.fz.datapoints],
// toZigbee: [tuya.tz.datapoints],
toZigbee: [tzdatapoints],
onEvent: tuya.onEventSetTime, // Add this if you are getting no converter for 'commandMcuSyncTime'
configure: tuya.configureMagicPacket,
exposes: [
// Here you should put all functionality that your device exposes
e
.numeric("liquid_level_percent", ea.STATE)
.withUnit("%")
.withDescription("Liquid level percentage"),
e
.numeric("liquid_depth", ea.STATE)
.withUnit("m")
.withDescription("Liquid Depth"),
e
.enum("liquid_state", ea.STATE, ["low", "normal", "high"])
.withDescription("Liquid State"),
e
.numeric("installation_height", ea.STATE_SET)
.withUnit("mm")
.withDescription("Height from sensor to tank bottom")
.withValueMin(100)
.withValueMax(3000)
.withValueStep(1),
e
.numeric("mini_set", ea.STATE_SET)
.withUnit("%")
.withDescription("Liquid minimal percentage")
.withValueMin(0)
.withValueMax(100)
.withValueStep(1),
e
.numeric("max_set", ea.STATE_SET)
.withUnit("%")
.withDescription("Liquid max percentage")
.withValueMin(0)
.withValueMax(100)
.withValueStep(1),
e
.numeric("liquid_depth_max", ea.STATE_SET)
.withUnit("mm")
.withDescription("Height from sensor to liquid level")
.withValueMin(100)
.withValueMax(2000)
.withValueStep(1),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[22, "liquid_level_percent", tuya.valueConverter.raw],
[2, "liquid_depth", tuya.valueConverter.divideBy100],
[
1,
"liquid_state",
tuya.valueConverterBasic.lookup({ low: 1, normal: 0, high: 2 }),
],
[19, "installation_height", tuya.valueConverter.raw],
[7, "max_set", tuya.valueConverter.raw],
[8, "mini_set", tuya.valueConverter.raw],
[21, "liquid_depth_max", tuya.valueConverter.raw],
],
},
extend: [
// A preferred new way of extending functionality.
],
};
module.exports = definition;
- Zigbee2MQTT neu starten.
- Gerät neu anlernen.
Die Readings kommen dann nach einer Weile - und dann läuft es perfekt. Ansonsten nochmal Zigbee2MQTT neu starten (warum auch immer)
Jetzt zeigt Zigbee2MQTT den TS0601 ( _TZE200_lvkk0hdg ) als Unterstützt an, und unter Details können die spezifischen Einstellungen vorgenommen werden.
(siehe Bilder)
1.jpg
2.jpg
3.jpg