A helper for setting up weather stations
Find out what your weather station is actually sending.
The server prepares a temporary subdomain under test-station.schizza.cz which you set as the upload target in your weather station for the next 30 minutes. Every request the station sends is captured – you see method, path, port, SSL/non-SSL route, the detected protocol (PWS/WU vs. WSLink) and the full payload. Nothing is written to disk – the data disappears as soon as the session expires.
Detailed guide ↓In the station's custom upload settings (Custom Server / Customized Server) fill in these fields. Replace values in <> with what you get after clicking the button above. Server / Hostname: <code>.test-station.schizza.cz Port: 80 (HTTP) or 443 (HTTPS) Path: keep the station's default Station ID, Password: anything – the server does not check them Interval: the shortest available, so you see results quickly Tip: try HTTP (port 80) first. If your station only sends over HTTPS, the server will detect that and recommend the WSLink SSL proxy.
Three simple steps:
- Click the “Generate test address” button. The server will prepare a unique subdomain valid for 30 minutes – the actual address appears right after generation in the “Your new test address” box.
- In your weather station's settings (typically under “Custom Server”, “Weather Services” or “Customized”), enter that address as the upload target and save. A concrete field example is in the “What to enter into the weather station” card above.
- Open the “Results” link and wait for the first data (usually within one upload interval). The server will show what the station is really sending, which protocol it uses (PWS/WU vs. WSLink) and recommend the matching Home Assistant integration settings.
Show README
Test Station Server
A standalone lightweight web server for diagnosing requests from weather stations.
Rust-based, all-in-one web server.
Features
- estimates which protocol the station is using:
WSLinkvsPWS/WU - distinguishes
SSLandnon-SSLroutes based on proxy headers - temporarily stores
query string,form body,relevant headers, andraw payload - keeps each session for 5 minutes and then destroys it
- stores no cookies and writes no data to disk; all statistics are kept only in temporary memory and discarded after 5 minutes
Run
cd tools/test-station-server
cargo run
Docker Compose
cd tools/test-station-server
docker compose up --build -d
The service listens on port 8099 by default.
Optional environment variables:
TEST_STATION_BIND=0.0.0.0:8099
TEST_STATION_BASE_DOMAIN=test-station.schizza.cz
TEST_STATION_SESSION_TTL_SECS=300
TEST_STATION_MAX_BODY_BYTES=65536
Proxy Behind Traefik
The server does not handle TLS termination by itself. It assumes TLS is handled by Traefik or another reverse proxy, which forwards information about the original route in upstream headers.
The server reads these headers:
X-Forwarded-ProtoX-Forwarded-PortX-Forwarded-HostX-Forwarded-ForForwarded- optionally
X-Test-Station-Route-Security: ssl|non-ssl
X-Forwarded-Proto is usually enough. If you want to explicitly distinguish two Traefik routes, add a custom middleware that sets X-Test-Station-Route-Security.
An example dynamic configuration is available in examples/traefik-dynamic.yml.
Note for Traefik v3:
- use
HostRegexp(\[a-z0-9]+.test-station.your-domain.tld`)` for wildcard subdomains - the older syntax
HostRegexp(\{code:[a-z0-9]+}.test-station.your-domain.tld`)` is tied to v2 syntax and in v3 often results in the router not matching the request at all - if the base domain opens but the subdomain returns
404 page not found, the problem is usually theHostRegexpmatch or a missing wildcard DNS record
Routing Model
GET /on the base domain shows the session generatorPOST /api/sessionscreates a new session- results are available only on the base domain via
/results/<code> - session JSON is available only on the base domain via
/api/sessions/<code> - requests sent to the session subdomain are stored as captured events
Notes
- sessions are purely in-memory; they disappear after restart and expire after 5 minutes
- after TTL expires, the data is deleted and the subdomain stops being valid
- the
PWS/WUvsWSLinkheuristic is intentionally simple and mainly relies on known parameters such asID/PASSWORDorwsid/wspw