Wetterstation Bresser 5-in-1 mit RTL-SDR USB Dongle empfangen, mit MQTT+TLS

Begonnen von Torxgewinde, 24 Mai 2022, 21:06:01

Vorheriges Thema - Nächstes Thema

Torxgewinde

Hallo,
Die Funksignale zahlreicher Geräte können mit einem USB TV-Stick empfangen und die Signale dekodiert werden. Populär sind die USB-Dongles mit dem Chip RTL2832U, da dieser von wenigen kHz bis ca. 1,7 GHz arbeiten kann. In diesem Codeschnipsel wird das Signal einer Bresser Funkwetterstation empfangen und mit MQTT+TLS an den Broker weitergeleitet. In FHEM spiegelt ein MQTT-device die Wetterstation wieder. Die Software für den USB-Funkdongle kann auch auf einem Einplatinencomputer oder einem OpenWRT Router laufen. Die Rechenleistung einer Fritzbox 7360 v2 reicht hierbei bereits aus (~25% CPU Auslastung durch rtl_433).

Einrichten des Funkdongles auf OpenWRT (hier Fritzbox 7360 v2):

opkg update && opkg install rtl_433 screen mosquitto-client-ssl


Die Software "rtl_433" kann zwar auch direkt unverschlüsselte MQTT Nachrichten versenden. Will man allerdings TLS nutzen, kann man besser die "mosquitto_pub" nutzen um die JSON codierten Werte an den Broker zu senden:

#!/bin/sh

while true; do
rtl_433 -f 868.272M -R 172 -M level -s 225.001k -F json | mosquitto_pub -t "garden/weatherstation" -l -p 8883 --cafile /etc/config/meine_CA.crt -h mein_broker_server.lan -u "Nutzername" -P "Passwort123"
done


Das Script kann man ausführen mit screen -d -S RTL -m sh "/root/WeatherStation.sh" oder zum Testen einfach direkt mit sh /root/WeatherStation.sh

Nun sollten die Werte der Wetterstation bereits im Broker im Topic "garden/weatherstation" auftauchen.

In FHEM kann man das Device dazu anlegen mit:

defmod WetterStation MQTT2_DEVICE
attr WetterStation IODev Mosquitto
attr WetterStation devicetopic garden/weatherstation
attr WetterStation event-on-change-reading battery_ok,humidity,id,rain_mm,snr,temperature_C,wind_avg_m_s,wind_dir_deg,wind_max_m_s,time,offset,rain_today
attr WetterStation readingList $DEVICETOPIC:.* { json2nameValue($EVENT) }
attr WetterStation stateFormat {\
my $hum = round(ReadingsNum($name, "humidity", -1),0);;\
my $temp = round(ReadingsNum($name, "temperature_C", -1), 1);;\
my $rain = round(ReadingsNum($name, "rain_today", -1), 1);;\
\
"${temp}°C, ${hum}%, ${rain}mm"\
}
attr WetterStation userReadings offset {\
my $LastUpdateDay = strftime("%d", localtime(time_str2num(ReadingsTimestamp("$name", "offset", undef))));;\
my $NowDay = strftime("%d", localtime());;\
\
if ($LastUpdateDay ne $NowDay) {\
Log(0, "Update den Wert, denn ".$LastUpdateDay." ist ungleich ".$NowDay);;\
return ReadingsVal("$name", "rain_mm", 0);;\
}\
\
return ReadingsNum("$name", "offset", undef);;\
},\
rain_today {\
my $rainTotal = round(ReadingsNum("$name", "rain_mm", undef), 3);;\
my $offset = round(ReadingsNum("$name", "offset", undef), 3);;\
my $diff = (($rainTotal*100 - $offset*100)%10000)/100.0;;\
\
#Log(0, "Berechne RainToday aus ".$rainTotal.", ".$offset." = ".$diff);;\
\
return $diff;;\
},\
wind_smooth {\
my $value = round(ReadingsNum("$name", "wind_avg_m_s", undef), 3);;\
my $previous = round(ReadingsNum("$name", "wind_smooth", undef), 3);;\
my $factor = 100.0;;\
\
my $moving_average = $previous - $previous/$factor + $value/$factor;;\
\
return $moving_average;;\
},\
wind_max_smooth {\
my $value = round(ReadingsNum("$name", "wind_max_m_s", undef), 3);;\
my $previous = round(ReadingsNum("$name", "wind_max_smooth", undef), 3);;\
my $factor = 100.0;;\
\
my $moving_average = $previous - $previous/$factor + $value/$factor;;\
\
if ($previous <= $value) {\
$moving_average = $value;;\
}\
\
return $moving_average;;\
}


Das Reading "offset" ist der Wert des Regenmessers. Er wird mit dem ersten Event des Sensors an einem neuen Tag gesetzt. Der Wert "rain_today" ist der Niederschlag des Tages. Da der Wert bei 100 überläuft wird der Wert mit Modulo berechnet. Da Modulo auf Ganzzahlen rundet, werden die Werte vorab mal hundert gerechnet und nachher wird es wieder durch hundert dividiert.

Da der verwendete RTL-SDR v3 Dongle recht warm wird, habe ich einen Kühlkörper darauf montiert.

Edit #1: Das DOIF für Regen-Tagesmenge ist dank der UserReadings unnötig.
Edit #2: Werte für Wind-Spitzen-Geschwindigkeit und Mittlere-Windgeschwindigkeit in den UserReadings ergänzt. Die Werte sind zeitlich gemittelt und klingen langsam ab (=decay, ähnlich wie ein RC-Glied bei analogen Schaltungen).