Open maltejahn opened 3 years ago
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
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
).
Hallo,
so nach langer Zeit... bemerkt das es ein Dockerfile gibt. Sehr nett!
Mein Workaround passt dann nicht mehr:
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
}
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.
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.
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"
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?
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%%?}}"
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!
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.${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.
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
` 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