# ChirpStack Decoder für Füllstandsmessung ## Payload-Format (8 Bytes) Das Gerät sendet 8 Bytes via LoRaWAN: | Bytes | Beschreibung | Einheit | Berechnung | |-------|--------------|---------|------------| | 0-1 | Distanz | mm | Big Endian uint16 | | 2-3 | Füllhöhe | mm | Big Endian uint16 | | 4-5 | Füllstand | % × 10 | Big Endian uint16 (855 = 85.5%) | | 6-7 | Batterie | mV | Big Endian uint16 (3700 = 3.7V) | ## Decoder-Code für ChirpStack v4 ```javascript function decodeUplink(input) { var bytes = input.bytes; var fPort = input.fPort; // Validierung if (bytes.length !== 8) { return { errors: ["Invalid payload length - expected 8 bytes, got " + bytes.length] }; } if (fPort !== 1) { return { errors: ["Invalid fPort - expected 1, got " + fPort] }; } // Distanz (Byte 0-1, Big Endian) var distanceMm = (bytes[0] << 8) | bytes[1]; var distanceCm = distanceMm / 10.0; var distanceM = distanceMm / 1000.0; // Füllhöhe (Byte 2-3, Big Endian) var fillHeightMm = (bytes[2] << 8) | bytes[3]; var fillHeightCm = fillHeightMm / 10.0; var fillHeightM = fillHeightMm / 1000.0; // Füllstand in % (Byte 4-5, Big Endian, × 10) var fillPercentRaw = (bytes[4] << 8) | bytes[5]; var fillPercent = fillPercentRaw / 10.0; // Batteriespannung (Byte 6-7, Big Endian, in mV) var batteryMv = (bytes[6] << 8) | bytes[7]; var batteryV = batteryMv / 1000.0; // Batterie-Prozent berechnen (LiPo: 3.0V = 0%, 4.2V = 100%) var batteryPercent = ((batteryV - 3.0) / (4.2 - 3.0)) * 100.0; if (batteryPercent < 0) batteryPercent = 0; if (batteryPercent > 100) batteryPercent = 100; return { data: { // Distanz (Sensor bis Flüssigkeit) distance_mm: distanceMm, distance_cm: distanceCm, distance_m: distanceM, // Füllhöhe (Flüssigkeitshöhe im Tank) fill_height_mm: fillHeightMm, fill_height_cm: fillHeightCm, fill_height_m: fillHeightM, // Füllstand in Prozent fill_percent: fillPercent, // Batterie battery_mv: batteryMv, battery_v: batteryV, battery_percent: Math.round(batteryPercent) } }; } ``` ## Beispiel-Payloads Angenommen: Tank-Höhe = 180 cm | Payload (Hex) | Distanz | Füllhöhe | Füllstand | |---------------|---------|----------|-----------| | `0348 0AA0 0226` | 84.0 cm | 170.0 cm | 94.4% | | `05DC 0708 0197` | 150.0 cm | 180.0 cm | 40.9% | | `0708 0000 0000` | 180.0 cm | 0.0 cm | 0% | | `0014 06F8 03E8` | 2.0 cm | 178.0 cm | 100.0% | ### Berechnung Beispiel 1: `0348 0AA0 0226` - **Distanz**: `0x0348` = 840 mm = 84.0 cm - **Füllhöhe**: `0x0AA0` = 2720 mm = 272.0 cm (Fehler! sollte max 180cm sein) - **Füllstand**: `0x0226` = 550 = 55.0% ## Installation 1. Öffne ChirpStack → **Device Profile** → **Codec** 2. Wähle **JavaScript** als Codec 3. Kopiere den Decoder-Code ins **Uplink decoder** Feld 4. Klicke **Submit** ## Anzeige in ChirpStack Nach erfolgreicher Dekodierung siehst du in ChirpStack: ```json { "distance_mm": 840, "distance_cm": 84.0, "distance_m": 0.084, "fill_height_mm": 960, "fill_height_cm": 96.0, "fill_height_m": 0.096, "fill_percent": 53.3, "battery_mv": 3850, "battery_v": 3.85, "battery_percent": 71 } ``` ## Grafana Dashboard Empfohlene Visualisierungen: 1. **Gauge**: `fill_percent` (0-100%) 2. **Graph**: `fill_height_cm` über Zeit 3. **Gauge**: `battery_percent` (0-100%) 4. **Graph**: `battery_v` über Zeit (Batterie-Entladung) 5. **Graph**: `distance_cm` über Zeit (Fehlerdiagnose) ## Troubleshooting ### Negative Füllhöhe **Problem**: Füllhöhe zeigt negative Werte **Lösung**: Tank-Höhe (`TANK_HEIGHT`) im Code anpassen ### Füllstand über 100% **Problem**: Füllstand zeigt über 100% **Lösung**: Sensor ist zu nah am Boden installiert oder Tank-Höhe falsch konfiguriert