Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Off Topic
  4. Microcontroller
  5. ( gelöst ) ESP Wassersensor BLE-YC01 MQTT

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.8k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.4k

( gelöst ) ESP Wassersensor BLE-YC01 MQTT

Geplant Angeheftet Gesperrt Verschoben Microcontroller
22 Beiträge 3 Kommentatoren 1.1k Aufrufe 2 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • HomoranH Homoran

    @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.

    P Offline
    P Offline
    perladd
    schrieb am zuletzt editiert von perladd
    #21

    @homoran

    Danke dir, ja den Datenpunkt hab ich jetzt bekomme

    Sorry das ich soweit immer auf dem Schlauch steh :face_palm:

    meinst du das so

    {
    "BLEOperation": {
    "opid": "29",
    "stat": "3",
    "state": "DONEREAD",
    "MAC": "C0000005750A",
    "svc": "0xff01",
    "char": "0xff02",
    "read": "FFA1FE72FEAFFFFFFFDDFFAEFF75FD04FAEC21FE8CFFAEFFFFFFFFD541"
    }
    }

    P 1 Antwort Letzte Antwort
    0
    • P perladd

      @homoran

      Danke dir, ja den Datenpunkt hab ich jetzt bekomme

      Sorry das ich soweit immer auf dem Schlauch steh :face_palm:

      meinst du das so

      {
      "BLEOperation": {
      "opid": "29",
      "stat": "3",
      "state": "DONEREAD",
      "MAC": "C0000005750A",
      "svc": "0xff01",
      "char": "0xff02",
      "read": "FFA1FE72FEAFFFFFFFDDFFAEFF75FD04FAEC21FE8CFFAEFFFFFFFFD541"
      }
      }

      P Offline
      P Offline
      perladd
      schrieb am zuletzt editiert von Homoran
      #22

      @perladd

      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öpfe :)

      Hier 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 geholfen :)

      VG
      Thomas

      1 Antwort Letzte Antwort
      0
      Antworten
      • In einem neuen Thema antworten
      Anmelden zum Antworten
      • Älteste zuerst
      • Neuste zuerst
      • Meiste Stimmen


      Support us

      ioBroker
      Community Adapters
      Donate

      340

      Online

      32.4k

      Benutzer

      81.5k

      Themen

      1.3m

      Beiträge
      Community
      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
      ioBroker Community 2014-2025
      logo
      • Anmelden

      • Du hast noch kein Konto? Registrieren

      • Anmelden oder registrieren, um zu suchen
      • Erster Beitrag
        Letzter Beitrag
      0
      • Home
      • Aktuell
      • Tags
      • Ungelesen 0
      • Kategorien
      • Unreplied
      • Beliebt
      • GitHub
      • Docu
      • Hilfe