Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unterscheidung Sensor #2

Open
maltejahn opened this issue Jul 7, 2021 · 8 comments
Open

Unterscheidung Sensor #2

maltejahn opened this issue Jul 7, 2021 · 8 comments

Comments

@maltejahn
Copy link

Hallo,

wäre es möglich das zu erweitern? Es geht darum wie man verschiedene Sensoren an einem SDR "trennen" kann

Wenn man sich die ID ansieht, so erkennt man was der Inhalt sein wird:

`a000bccd

a = type 1 (17240baud types), 2 (9600 baud types), 3 (TX22)
b = static value (0 for TX22, usually 9 for others)
cc = random ID
d = subtype
    d = 0 (internal temperature sensor)
    d = 1 (external temperature sensor for 3143)
    d = 1 only humidity (TX22)
    d = 2 rain counter as temperature value (TX22)
    d = 3 speed as temperature in m/s, direction as humidity (TX22)
    d = 4 gust speed as temperature in m/s (TX22)

`
Konkret:
0865bcacdff1 2 : Regensensor
0865bcacdff1 0 : Temperatursensor der im Regensensor integiert ist

Ich stelle mir vor, das es eine Fallunterscheidung gibt:
0: message="{ \"sensor_id\":\"$sensor_id\", \"temperature\":$temperature, \"humidity\":$humidity, \"lowbat\":$lowbat, \"rssi\":$rssi }"
2: message="{ \"sensor_id\":\"$sensor_id\", \"raincount\":$raincount, \"timediff\":$timediff, \"lowbat\":$lowbat, \"rssi\":$rssi }"

Grüße
Malte

@maltejahn
Copy link
Author

maltejahn commented Jul 7, 2021

Hab da selbst was zusammenkopiert, scheint auf den ersten Blick zu funktionieren

# get last digit
read lastnibble <<< ${sensor_id:(-1)}

case $lastnibble in
0*) message="{ \"sensor_id\":\"$sensor_id\", \"temperature\":$temperature, \"humidity\":$humidity, \"lowbat\":$lowbat, \"rssi\":$rssi }";;
2*) message="{ \"sensor_id\":\"$sensor_id\", \"raincount\":$temperature, \"timediff\":$humidity, \"lowbat\":$lowbat, \"rssi\":$rssi }";;
esac

Abschließend
stateFormat Q: raincount t= timediff

@git-developer
Copy link
Owner

Hallo Malte,

ich vermute, dass die IDs Deiner Sensoren ein anderes Format haben als meine.

Meine Sensoren haben eine 4-stellige Hex-ID 15 Bit, bei denen keins der Zeichen eine spezielle Bedeutung hat, z. B. 5158.

Du scheinst Sensoren einzusetzen, die keine feste ID haben und ein strukturiertes Format versenden, siehe Non-WeatherHub (TFA_2, TFA_3, TX22).

Um je nach Sensor-Typ eine andere JSON-Nachricht zu erzeugen, sollte im Shell-Skript zunächst der Aufbau der ID untersucht (15-Bit / WeatherHub / Format a000bccd) und in Abhängigkeit davon eine passende Nachricht erzeugt werden. Wenn Du Dir eine entsprechende Erweiterung wünscht, kannst Du gern einen Pull Request im Git-Repository tfrec-mqtt aufmachen, wo der Code inzwischen gepflegt wird. Es wäre dabei sinnvoll, alle 3 bekannten Formate zu unterstützen.

Alternativ könnte man die Auswertung auch erst im Nachgang, also innerhalb von FHEM auf Basis des ID-Formates vornehmen. Die JSON-Nachricht wäre dann wie derzeit für alle Sensoren gleich (Properties temperature und humidity), und erst bei der Auswertung in FHEM würde ein passend benanntes Reading erzeugt (z.B. temperature / humidity oder rain_count / duration).

@maltejahn
Copy link
Author

maltejahn commented Oct 7, 2022

Hallo,

so nach langer Zeit... bemerkt das es ein Dockerfile gibt. Sehr nett!

Mein Workaround passt dann nicht mehr:

  • nicht "Updatesicher"
  • und ich es auf anhieb nicht geschafft habe meine Änderungen mqtt-publish unterzumogeln

So wie "ich" es verstehe werden verschiedene TFA Geräte unterschieden anhand des letzten 4 Bit. Konkret enthält mein Regensensor quasi zwei Sender:

0865bcacdff1 2 : Regensensor
0865bcacdff1 0 : Temperatursensor der im Regensensor integiert ist

Jeder Sensortyp liefert aber unterschiedliche Daten. Ich würde gerne schon beim "absenden" Richtung MQTT die Bezeichner richtig haben, das ein "Regeninkrement (0,25 l/Tick) auch als z.B. Regencount erscheint und ich mir nicht merken muss das, weil die Begriffe nicht angepasst werden, Temperature im Falle des Regensensors eingetlich "regencount" meint.

In meinem Fall Regensensor hat der xxxx2 Sensor als Temperaturwert den Regen - Tick, und als humidity die Zeit seit dem letzten Puls. Was auch erstmal "nur" für Weatherhub gilt.. :-(

In FHEM wird die Regenmenge dann so summiert:
rain_total monotonic { ReadingsVal ("mqtt_klima_regensensor_regen", "raincount", 0)*0.25 },

Nebenfrage: Woher kommt das "plötzlich" in rauen Mengen?
localhost run-tfrec.sh[10918]: Warning: Unable to locate configuration directory, default config not loaded.

Ich bin mir keiner Schuld bewusst.

Hier noch der verunglückte Versuch es selbst zu ändern

build_json_message() {                                                                       
  [ ! "${#}" -lt "8" ] || cancel "too few arguments: '${@}'"
  echo "${@}" | while read sensor_id temperature humidity seq lowbat rssi flags timestamp; do
    # remove the leading '+' to get a valid JSON number                                      
    temperature="${temperature#+}"                                         
                                                    
read lastnibble <<< ${sensor_id:(-1)}                     
                                                                                                                                    
    if [ "${FORMAT_JSON_LOWBAT_AS_BOOLEAN}" = 'true' ]; then                                                                        
      if [ "${lowbat}" -eq 1 ]; then lowbat='true'; else lowbat='false'; fi                                                         
    fi                                                                                                                              
                                                                                                                                    
case $lastnibble in                                                                                                            
0*) printf '{ "sensor_id":"%s", "temperature":%.9g, "humidity":%.9g, "seq":%i, "lowbat":%s, "rssi":%i, "flags":%i, "timestamp":%i }'
            "${sensor_id}"    "${temperature}"    "${humidity}"    "${seq}"  "${lowbat}"  "${rssi}"  "${flags}"  "${timestamp}"  ;;   
2*) printf '{ "sensor_id":"%s", "raincount":%.9g, "timediff":%.9g, "seq":%i, "lowbat":%s, "rssi":%i, "flags":%i, "timestamp":%i }' 
            "${sensor_id}"    "${temperature}"    "${humidity}"    "${seq}"  "${lowbat}"  "${rssi}"  "${flags}"  "${timestamp}"  ;;    
esac                                                                                                                         
                        
                                                                                                                                     
                                                                                                                                
#    printf '{ "sensor_id":"%s", "temperature":%.9g, "humidity":%.9g, "seq":%i, "lowbat":%s, "rssi":%i, "flags":%i, "timestamp":%i }'
#            "${sensor_id}"    "${temperature}"    "${humidity}"    "${seq}"  "${lowbat}"  "${rssi}"  "${flags}"  "${timestamp}"     
  done                                                                                                                          
} 

@git-developer
Copy link
Owner

Anpassungen an mqtt-publish

Mein Workaround passt dann nicht mehr:

  • und ich es auf anhieb nicht geschafft habe meine Änderungen mqtt-publish unterzumogeln

Du kannst das im Docker-Image integrierte Skript mqtt-publish mit einer von Dir modifizierten Variante überschreiben, indem Du Deine Variante in den Container mountest, Beispiel siehe unten.

Warnungen im Log

Woher kommt das "plötzlich" in rauen Mengen?
localhost run-tfrec.sh[10918]: Warning: Unable to locate configuration directory, default config not loaded.

Diese Meldung wird von mosquitto_pub ausgegeben, wenn die Umgebungsvariable HOME fehlt (Details). Setze HOME, um sie zu vermeiden.

Beispiel

Beide Punkte können durch Anpassungen an der docker-compose.yml behandelt werden. Falls die Variante von mqtt-publish den Namen custom-mqtt-publish hat und neben der docker-compose.yml liegt:

---
services:
  tfrec-mqtt:
  ...
    environment:
      HOME: "/home"
      ...
    volumes:
    - "./custom-mqtt-publish:/usr/local/bin/mqtt-publish:ro"

@git-developer
Copy link
Owner

git-developer commented Oct 8, 2022

Irgendwie ist hier Dein letzter Kommentar verloren gegangen...

Im
read lastnibble <<< ${sensor_id:(-1)}
das <<< wird nämlich nicht von /bin/sh unterstützt. Somit muss ich mal schauen wie ich hier den niedrigsten Nibble bekomme

Oben wird beschrieben, dass der subtype Werte von 0 bis 4 annehmen kann, dafür braucht man 3 Bit. Mit folgendem Code sollte es möglich sein, ohne Bash die letzten 3 Bit der Variable sensor_id auf eine neue Variable subtype zu schreiben:

subtype="$((${sensor_id##${sensor_id%%?}} % 8))"

Hilft Dir das weiter?

@git-developer
Copy link
Owner

Noch etwas kürzer wird es, wenn man das letzte Zeichen komplett auswertet, was laut der Doku oben auch zulässig sein dürfte:

subtype="${sensor_id##${sensor_id%%?}}"

@maltejahn
Copy link
Author

maltejahn commented Oct 9, 2022

Hallo,

ja, hatte den Beitrag zurückgezogen weil mir doch etwas eingefallen war bzw. ich zuerst was anderes probieren wollte. Deine Variante, auch wenn ich diese nicht genau verstehe, ist einfacher als das was ich tue. Ich habe zuerst ein "echte" Hexwert gebaut und dann maskiert

# add 0x to the sensor ID to get a real hexvalue
        var_hex=$(printf "%s%s" "0x" "$sensor_id")
# get the lowest byte value which indicates the sensor type
        nibble=$(((($var_hex)) & 0xF));

case $nibble in
0*) printf '{ "sensor_id":"%s", "temperature":%.9g, "humidity":%.9g, "seq":%i, "lowbat":%s, "rssi":%i, "flags":%i, "timestamp":%i }' \
            "${sensor_id}"    "${temperature}"    "${humidity}"    "${seq}"  "${lowbat}"  "${rssi}"  "${flags}"  "${timestamp}";;
2*) printf '{ "sensor_id":"%s", "raincount":%.9g, "timediff":%.9g, "seq":%i, "lowbat":%s, "rssi":%i, "flags":%i, "timestamp":%i }' \
            "${sensor_id}"    "${temperature}"    "${humidity}"    "${seq}"  "${lowbat}"  "${rssi}"  "${flags}"  "${timestamp}";;
*)  echo Oh, was unbekanntes;;
esac

Schein so erst einmal zu funktionieren. Also soweit, Danke!

@git-developer
Copy link
Owner

Deine Variante, auch wenn ich diese nicht genau verstehe, ist einfacher als das was ich tue.

Dann liefere ich gern eine kurze Erläuterung nach:

  • ${sensor_id%%?} schneidet das letzte Zeichen von sensor_id ab (genauer: den längsten Teilstring am Ende, der einem beliebigen Zeichen entspricht).
  • ${sensor_id##foo*} schneidet am Anfang von sensor_id den längsten Text ab, auf den foo* passt.
  • In Summe ergibt das: ${sensor_id##${sensor_id%%?}} schneidet den String "sensor_id ohne das letzte Zeichen" von der Variable sensor_id ab. Es bleibt also nur das letzte Zeichen übrig.

Die Shell-Syntax zur Parameter-Manipulation wird hier beschrieben.

Schön, dass es funktioniert.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants