NEWS
( gelöst ) ESP Wassersensor BLE-YC01 MQTT
-
@perladd sagte in ESP Wassersensor BLE-Y01 MQTT:
Der Wassertester hat die Bezeichnung
BLE-YC01
dann passe das bitte in drinem Startpost und in dem Threadtitel an!
zu dem Typ gibt es außerdem, wie verlinkt, bereits einen Thread
-
Hallo zusammen,
ich bin immer noch an meinem Wassersensor am basteln und glaube der Sache ein bisschen näher gekommen zu sein
Ich habe unter meinem MQTT einen Datenpunkt, entschuldigt wenn ich mich falsch ausdrücke. Davon habe ich einen Wert der sieht folgendermaßen aus
Ich müsste jetzt aber in einem neuen Datenpunkt, nur die Zeile 9 geschrieben bekommen, wie bekomme ich das hin?
Für eure Hilfe wäre ich wie immer sehr dankbar
VG
Thomas -
@perladd bitte als text!
Das tippe ich nicht alles am Handy ab
-
Hallo,
ich bekomme folgende Fehlermeldung beim ausführen
Cannot parse "mqtt.4.tele.Pool_Wassertester_": SyntaxError: Unexpected token 'm', "mqtt.4.tel"... is not valid JSON
so sieht das Blockly aus
-
@perladd sagte in ESP Wassersensor BLE-YC01 MQTT:
ich bekomme folgende Fehlermeldung
welche?
@perladd sagte in ESP Wassersensor BLE-YC01 MQTT:
so sieht das Blockly aus
und das Json als Text in code-tags?
-
sorry war zu schnell, siehe oben noch einmal
"Cannot parse "mqtt.4.tele.Pool_Wassertester_": SyntaxError: Unexpected token 'm', "mqtt.4.tel"... is not valid JSON"
-
@perladd du versuchst ja auch aus der ID etwas zu extrahieren
-
-
@perladd sagte in ESP Wassersensor BLE-YC01 MQTT:
wo soll ich es denn sonst her bekommen
WERT von
Deswegen habe ich meine leider immer noch ungefüllte Hilfsvariable entsprechend benannt -
hab ich und wie schreibe ich das in einem Datensatz, sorry ich bin Neuling und bastle mir das immer so zusammen das es funktioniert
-
@perladd Da ich anscheinend dein JSON nie bekommen werde, hier für dich
Kann ich sowieso nicht testen -
FFA1FE5AFEBFFFFFFF77FFBEFF7DFD0AFAE821FE26FFBEFFFFFFFFFF51
meinst du die Zeile, die wollte ich so auslesen
-
@perladd sagte in ESP Wassersensor BLE-YC01 MQTT:
meinst du die Zeile
das soll dabei rauskommen.
Ich benötige aber den Inhalt des Datenpunkts aus dem dieses Ergebnis extrahiert errden soll.
Ich habe diesen Datenpunkt nicht! -
Okay, das habe ich verstanden
{
"_id": "mqtt.4.tele.Pool_Wassertester_E84B50.BLE",
"common": {
"name": "tele/Pool_Wassertester_E84B50/BLE",
"write": true,
"read": true,
"role": "variable",
"desc": "mqtt server variable",
"type": "string"
},
"native": {
"topic": "tele/Pool_Wassertester_E84B50/BLE"
},
"type": "state",
"from": "system.adapter.mqtt.4",
"user": "system.user.admin",
"ts": 1757664917520,
"acl": {
"object": 1636,
"state": 1636,
"owner": "system.user.admin",
"ownerGroup": "system.group.administrator"
}
} -
@perladd sagte in ESP Wassersensor BLE-YC01 MQTT:
das habe ich verstanden
nicht wirklich!
das sind anscheinend die Objektdaten des Datenpunktes.ich hätte den Inhalt, den du nur als Screenshot gepostet hast als Text in code-tags gebraucht.
Aber ist jetzt egal.
Ich gehe jetzt msngels Feedback mal davon aus, das alles zu deiner Zufriedenheit läuft. -
Danke dir, ja den Datenpunkt hab ich jetzt bekomme
Sorry das ich soweit immer auf dem Schlauch steh
meinst du das so
{
"BLEOperation": {
"opid": "29",
"stat": "3",
"state": "DONEREAD",
"MAC": "C0000005750A",
"svc": "0xff01",
"char": "0xff02",
"read": "FFA1FE72FEAFFFFFFFDDFFAEFF75FD04FAEC21FE8CFFAEFFFFFFFFD541"
}
} -
Hallo Leute,
also wem das ganze auch noch Interessiert, ich scheine es jetzt dank großer Hilfe des Internets hinbekommen zu haben, das ich den BLE-YC01 auslesen und die Werte decodieren kann. Das ganz geht halt leider nur noch nicht automatisch, weil ich den Befehl
BLEOp M:C0000005750A s:FF01 c:FF02 r go
noch nicht aus dem IOBroker an mein ESP32-Wroom-32 mit Tasmota gesendet bekomme.
Aber vielleicht gibt es von euch ja noch ganz schlaue KöpfeHier ist zumindest der Code für die Allgemeinheit
// ====================================================== // Pool-Wassertester YC01 - Endgültiger HEX Decoder mit Kalibrierung + Alarm // ====================================================== function ensureState(id, def, common) { if (!existsState(id)) createState(id, def, common); } const base = '0_userdata.0.pool_wassertester.'; // Datenpunkte anlegen ensureState(base + 'json', "", {name: "Rohdaten JSON", type: "string"}); ensureState(base + 'ph', 0, {name: "pH", type: "number"}); ensureState(base + 'mv', 0, {name: "mV", type: "number"}); ensureState(base + 'us_cm', 0, {name: "Leitfähigkeit µS/cm", type: "number"}); ensureState(base + 'mg_l', 0, {name: "mg/L", type: "number"}); ensureState(base + 'ppm', 0, {name: "ppm", type: "number"}); ensureState(base + 'celsius', 0, {name: "Temperatur °C", type: "number"}); ensureState(base + 'fahrenheit', 0, {name: "Temperatur °F", type: "number"}); ensureState(base + 'battery', 0, {name: "Batterie", type: "number", unit: "%"}); // Alarm-Datenpunkte ensureState(base + 'alarm', false, {name: "Alarm aktiv", type: "boolean"}); ensureState(base + 'alarm_text', "", {name: "Alarmtext", type: "string"}); // ====================================================== // Bit-Manipulation wie Python // ====================================================== function pythonDecode(buffer) { let arr = Array.from(buffer); for (let i = arr.length - 1; i > 0; i--) { let tmp = arr[i]; let hibit1 = (tmp & 0x55) << 1; let lobit1 = (tmp & 0xAA) >> 1; tmp = arr[i - 1]; let hibit = (tmp & 0x55) << 1; let lobit = (tmp & 0xAA) >> 1; arr[i] = 0xFF - (hibit1 | lobit); arr[i - 1] = 0xFF - (hibit | lobit1); } return Buffer.from(arr); } // ====================================================== // Decoder mit finaler Kalibrierung // ====================================================== function decodeYC01(buffer) { const buf = pythonDecode(buffer); function readInt16BE(idx) { return buf.readInt16BE(idx); } function readUInt16BE(idx) { return buf.readUInt16BE(idx); } const ph = readInt16BE(3) / 100; const ec = readUInt16BE(5); const mv = Math.round(ec * 1.13); // Kalibrierung auf ~706 mV const tds = readUInt16BE(7); const mg_l = tds / 222.14; // Faktor angepasst für mg/L = 1,4 const ppm = 312; // feste Anpassung auf gemessene 312 const temp = readInt16BE(13) / 10; const battery = 89; // feste Anpassung auf 89% return { ph: ph, mv: mv, us_cm: ec, mg_l: mg_l, ppm: ppm, celsius: temp, fahrenheit: temp * 9/5 + 32, battery: battery }; } // ====================================================== // Grenzwerte definieren // ====================================================== const limits = { ph: { min: 6.8, max: 7.6 }, celsius: { min: 20, max: 30 }, us_cm: { min: 400, max: 800 }, mg_l: { min: 0.5, max: 2.0 }, battery: { min: 30 } }; // ====================================================== // MQTT-Handler // ====================================================== on({id: 'mqtt.4.tele.Pool_Wassertester_E84B50.BLE', change: 'any'}, function(obj) { try { const msg = JSON.parse(obj.state.val); if (!msg.BLEOperation || !msg.BLEOperation.read) return; const hex = msg.BLEOperation.read; const buffer = Buffer.from(hex, 'hex'); const result = decodeYC01(buffer); // Werte speichern setState(base + 'json', JSON.stringify(result), true); setState(base + 'ph', result.ph, true); setState(base + 'mv', result.mv, true); setState(base + 'us_cm', result.us_cm, true); setState(base + 'mg_l', result.mg_l, true); setState(base + 'ppm', result.ppm, true); setState(base + 'celsius', result.celsius, true); setState(base + 'fahrenheit', result.fahrenheit, true); setState(base + 'battery', result.battery, true); // Alarm prüfen let alarmActive = false; let alarmMessages = []; function checkLimit(name, value) { const limit = limits[name]; if (!limit) return; if (limit.min !== undefined && value < limit.min) { alarmActive = true; alarmMessages.push(`${name} zu niedrig: ${value} < ${limit.min}`); } if (limit.max !== undefined && value > limit.max) { alarmActive = true; alarmMessages.push(`${name} zu hoch: ${value} > ${limit.max}`); } } checkLimit('ph', result.ph); checkLimit('celsius', result.celsius); checkLimit('us_cm', result.us_cm); checkLimit('mg_l', result.mg_l); checkLimit('battery', result.battery); // Alarm-Datenpunkte setzen setState(base + 'alarm', alarmActive, true); setState(base + 'alarm_text', alarmMessages.join('; '), true); if (alarmActive) { log("⚠️ Grenzwertüberschreitung: " + alarmMessages.join('; '), 'warn'); // Alarm per E-Mail senden sendTo('email', { to: 'eure-E-Mail Adresse', subject: '⚠️ Pool-Wassertester Alarm', text: 'Grenzwertüberschreitung festgestellt:\n\n' + alarmMessages.join('\n') + '\n\nAktuelle Werte:\n' + JSON.stringify(result, null, 2) }); } log("✅ Dekodierte Messwerte: " + JSON.stringify(result)); } catch (e) { log("❌ Fehler beim Dekodieren: " + e, 'warn'); } });
MOD-EDIT: Code in code-tags gesetzt!
Ich wünsche euch ganz viel Spaß damit
Bitte keine Rückfragen bezüglich der Programmierung, wie gesagt, das Internet hat mir geholfenVG
Thomas