This afternoon PostNL delivered my very first weather station, a " Bresser Prol 5-in-1 Weatherstation incl. Wifi with Wind and Barometer". I chose this one because I really don’t need another dongle to read 868Mhz or whatever these things use.A nice post to some third party site I can scrape will do just fine.
I installed it, verified it was reporting sensible data and then tried to hook it up to the Weather Underground and right there is where things went to crap.
The API in homeassistant for WU doesn’t do anything and the other custom component I found didn’t work either. Right, … Damn it, maybe I should’ve gotten another crap dongle. My server looks like a porcupine already, what’s one more.
However, this thing is reporting to the WU site, so I just need to trap the data.I fired up wireshark and sniffed all the packets from the device ip to the internet. (Mikrotik/Tools/Packet Sniffer --> Stream to server and cap everything coming from the weather station)
Sure enough, it posted to a php file :
HTTP 450 GET 169.47.111.60/weatherstation/updateweatherstation.php?ID=BABABOEY&PASSWORD=FAFAFOHI&action=updateraww&realtime=1&rtfreq=5&dateutc=now&baromin=29.91&tempf=68.9&dewptf=55.0&humidity=61&windspeedmph=4.6&windgustmph=4.6&winddir=112&rainin=0.0&dailyrainin=0.36&indoortempf=72.6&indoorhumidity=54 HTTP/1.1
And it does that often too, like every 20 seconds, that near enough real time, exactly what I wanted in HA.
Let’s tell the router to route that sweet data somewhere else.
[drbytes@MikroTik] /ip firewall nat> add chain=dstnat action=dst-nat to-addresses=10.0.0.100 protocol=tcp src-address=10.0.0.34
This NAT rule will route all traffic from the weather station (with ip .34) to an internal webserver with ip .100 which is where my Nginx reverse proxy lives.
Next I replicated the directory and php script /weatherstation/updateweatherstation.php
.
In the php (I hate php, it sucks I can not get used to that style) I have this code :
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\Exceptions\ConnectingToBrokerFailedException;
use PhpMqtt\Client\Exceptions\DataTransferException;
use PhpMqtt\Client\Exceptions\UnexpectedAcknowledgementException;
use PhpMqtt\Client\MQTTClient;
$server = "10.0.0.100";
$port = 1883;
$client_id = "weather-data-publisher";
$mqttRoot = "pws/sensors/";
// OVERLY VERBOSE HELPER STUFF
function RoundIt($ee){
return round($ee, 2);
}
function toKM( $a) {
return RoundIt( floatval($a)*1.60934);
}
function toC( $a) {
return RoundIt( (floatval($a)-32) * (5/9) );
}
function toMM( $a) {
return RoundIt( floatval($a)*25.4);
}
function toHPA( $a) {
return RoundIt((floatval($a)*33.8639);
}
// FOUND THIS ON THE NET IN SOME PASTEBIN
function wind_cardinal( $degree ) {
switch( $degree ) {
case ( $degree >= 348.75 && $degree <= 360 ):
$cardinal = "N";
break;
case ( $degree >= 0 && $degree <= 11.249 ):
$cardinal = "N";
break;
case ( $degree >= 11.25 && $degree <= 33.749 ):
$cardinal = "N NO";
break;
case ( $degree >= 33.75 && $degree <= 56.249 ):
$cardinal = "NO";
break;
case ( $degree >= 56.25 && $degree <= 78.749 ):
$cardinal = "O NO";
break;
case ( $degree >= 78.75 && $degree <= 101.249 ):
$cardinal = "O";
break;
case ( $degree >= 101.25 && $degree <= 123.749 ):
$cardinal = "O ZO";
break;
case ( $degree >= 123.75 && $degree <= 146.249 ):
$cardinal = "ZO";
break;
case ( $degree >= 146.25 && $degree <= 168.749 ):
$cardinal = "N";
break;
case ( $degree >= 168.75 && $degree <= 191.249 ):
$cardinal = "Z";
break;
case ( $degree >= 191.25 && $degree <= 213.749 ):
$cardinal = "Z ZW";
break;
case ( $degree >= 213.75 && $degree <= 236.249 ):
$cardinal = "ZW";
break;
case ( $degree >= 236.25 && $degree <= 258.749 ):
$cardinal = "W ZW";
break;
case ( $degree >= 258.75 && $degree <= 281.249 ):
$cardinal = "W";
break;
case ( $degree >= 281.25 && $degree <= 303.749 ):
$cardinal = "W NW";
break;
case ( $degree >= 303.75 && $degree <= 326.249 ):
$cardinal = "NW";
break;
case ( $degree >= 326.25 && $degree <= 348.749 ):
$cardinal = "N NW";
break;
default:
$cardinal = null;
}
return $cardinal;
}
// SHUFF IT TO MQTT
$mqtt = new MQTTClient($server, $port, $client_id);
$mqtt->connect();
$mqtt->publish($mqttRoot .'baromin', toHPA($_GET["baromin"]), 0);
$mqtt->publish($mqttRoot .'temp', toC($_GET["tempf"]), 0);
$mqtt->publish($mqttRoot .'dewpt', toC($_GET["dewptf"]), 0);
$mqtt->publish($mqttRoot .'humidity', $_GET["humidity"], 0);
$mqtt->publish($mqttRoot .'windspeedkph', toKM($_GET["windspeedmph"]), 0);
$mqtt->publish($mqttRoot .'windgustkph', toKM($_GET["windgustmph"]), 0);
$mqtt->publish($mqttRoot .'winddir',wind_cardinal( $_GET["winddir"]), 0);
$mqtt->publish($mqttRoot .'rainmm', toMM($_GET["rainin"]), 0);
$mqtt->publish($mqttRoot .'dailyrainmm', toMM($_GET["dailyrainin"]), 0);
$mqtt->publish($mqttRoot .'indoortemp', toC($_GET["indoortempf"]), 0);
$mqtt->publish($mqttRoot .'indoorhumidity', $_GET["indoorhumidity"], 0);
$mqtt->close();
// POST TO WU .. OPTIONAL, I SHOULD JUST NOT BECAUSE THEY PULLED A FREE SERVICE AND STILL LEECH DATA OF OF MY INVESTMENT WITHOUT ANY REAL RETURN.
$xml = file_get_contents("http://169.47.111.60/weatherstation/updateweatherstation.php?".$_SERVER['QUERY_STRING']);
?>
success
You need the success
so the weather station knows it went trough OK.
It’s pretty self explanatory, I just parse the query string, perform some localization on it, translate the wind direction and convert to metric where appropriate and shoot it off to MQTT.
Lastly I update the WU, for shizz n giggles.
For the PHP to work you need to install php-mqtt with composer.
After that I deployed a mqtt docker, added it to the HA configuration and finally added the sensors :
- platform: mqtt
name: "PWS Barometer"
state_topic: "pws/sensors/baromin"
unit_of_measurement: 'HPa'
- platform: mqtt
name: "PWS Outside Temperature"
state_topic: "pws/sensors/temp"
unit_of_measurement: 'C'
- platform: mqtt
name: "PWS Dew Point"
state_topic: "pws/sensors/dewpt"
unit_of_measurement: 'C'
- platform: mqtt
name: "PWS Outside Humidity"
state_topic: "pws/sensors/humidity"
unit_of_measurement: '%'
- platform: mqtt
name: "PWS Wind speed"
state_topic: "pws/sensors/windspeedkph"
unit_of_measurement: 'KMh'
- platform: mqtt
name: "PWS Wind Gust speed"
state_topic: "pws/sensors/windgustkph"
unit_of_measurement: 'KMh'
- platform: mqtt
name: "PWS Wind direction"
state_topic: "pws/sensors/winddir"
unit_of_measurement: ''
- platform: mqtt
name: "PWS Rain"
state_topic: "pws/sensors/rainmm"
unit_of_measurement: 'MM'
- platform: mqtt
name: "PWS Daily Rain"
state_topic: "pws/sensors/dailyrainmm"
unit_of_measurement: 'MM'
- platform: mqtt
name: "PWS Indoor Temperature"
state_topic: "pws/sensors/indoortemp"
unit_of_measurement: 'C'
- platform: mqtt
name: "PWS Indoor Humidity"
state_topic: "pws/sensors/indoorhumidity"
unit_of_measurement: '%'
And we’re done.
Near real time updates in HA and no dependencies other than the ones I already had, locally processed by trapping the outbound sensor data and publishing them via mqtt for easy pickup by HA.
I thought I’d share it here although it’s a bit of a hack, it might help someone.
If it’s been done before I didn’t find it and it would’ve saved me a couple of hours.