Weather Station
POCS integrates with the AAG CloudWatcher weather station out of the box, but it can
work with any weather source — a different sensor, a scraper for a local weather API,
or a home-built station — as long as you write records in the expected JSON format to the
weather database collection.
How It Works
Weather source ──────────────────► DB "weather" collection
(AAG CloudWatcher, adapter script, │
or any custom integration) ▼
POCS.is_weather_safe() ──► allow / deny observations
The only thing POCS.is_weather_safe() cares about is the most recent document in
the weather collection. It reads two fields and makes a go/no-go decision:
| Field | Required | Description |
|---|---|---|
is_safe |
yes | true = conditions are safe to observe |
timestamp |
yes | ISO 8601 string; records older than 180 s are treated as unsafe |
Building a Custom Integration
If you are using a non-AAG sensor or want to pull data from an existing weather service,
the only thing you need to do is expose an HTTP endpoint that returns a JSON object
with the required fields. POCS already has the polling and database-writing machinery
built in via RemoteMonitor and pocs sensor monitor.
What your endpoint must return
The JSON object returned by your endpoint must include at minimum:
{
"is_safe": true,
"timestamp": "2024-01-15T10:30:00.123456"
}
| Field | Type | Description |
|---|---|---|
is_safe |
bool |
true = conditions are safe to observe |
timestamp |
str |
ISO 8601 datetime of the reading; records older than 180 s are treated as unsafe |
Your endpoint can return any additional fields — they will be stored alongside the
required ones. Including the full AAG schema fields makes your
readings visible in pocs weather status output.
Polling the endpoint
Once your endpoint is running, point pocs sensor monitor at it:
# One-liner: poll http://myweather.local/status every 90 seconds
pocs sensor monitor weather --endpoint http://myweather.local/status --read-frequency 90
Or configure the URL in your config file so no --endpoint flag is needed:
environment:
weather:
url: http://myweather.local/status
pocs sensor monitor weather --read-frequency 90
pocs sensor monitor fetches the endpoint on every interval, merges in a date
timestamp, and writes the result to the weather database collection — the same
collection that POCS.is_weather_safe() reads.
Running as a background service
The supervisord configuration already includes a ready-to-use entry for this pattern.
Enable the pocs-weather-reader-remote program in conf_files/pocs-supervisord.conf
(and disable pocs-weather-reader if the AAG is not physically connected):
; Use this when your weather station is NOT connected to the POCS computer.
[program:pocs-weather-reader-remote]
command=pocs sensor monitor weather --read-frequency 90
autostart=true ; change from false → true
If the monitor process stops for any reason, readings in the database will go stale and POCS will automatically suspend observations after 180 s.
Full JSON Schema
The built-in AAG CloudWatcher integration writes all of the following fields.
Custom integrations may include any subset (only is_safe and timestamp are required),
or additional fields of their own.
Measurement Fields
| Field | Type | Unit | Description |
|---|---|---|---|
timestamp |
str |
— | ISO 8601 datetime of the reading, e.g. "2024-01-15T10:30:00.123456" |
ambient_temp |
float |
°C | Ambient (air) temperature |
sky_temp |
float |
°C | Sky infrared temperature; the difference sky_temp − ambient_temp indicates cloud cover |
wind_speed |
float |
m/s | Wind speed |
rain_frequency |
float |
— | Raw rain-sensor frequency; higher values mean drier conditions |
pwm |
float |
% | Heater element duty cycle |
Condition Fields
Derived by comparing the measurements against configurable thresholds
(see environment.weather in conf_files/pocs.yaml).
| Field | Type | Possible Values |
|---|---|---|
cloud_condition |
str |
"clear", "cloudy", "very cloudy", "unknown" |
wind_condition |
str |
"calm", "windy", "very windy", "gusty", "very gusty", "unknown" |
rain_condition |
str |
"dry", "wet", "rainy", "unknown" |
Safety Fields
| Field | Type | Description |
|---|---|---|
cloud_safe |
bool |
True when cloud_condition == "clear" |
wind_safe |
bool |
True when wind_condition == "calm" |
rain_safe |
bool |
True when rain_condition == "dry" |
is_safe |
bool |
True only when all three of cloud_safe, wind_safe, and rain_safe are True |
Full Example Record
{
"timestamp": "2024-01-15T10:30:00.123456",
"ambient_temp": 15.5,
"sky_temp": -25.0,
"wind_speed": 2.3,
"rain_frequency": 2700.0,
"pwm": 75.0,
"cloud_condition": "clear",
"wind_condition": "calm",
"rain_condition": "dry",
"cloud_safe": true,
"wind_safe": true,
"rain_safe": true,
"is_safe": true
}
Safety Evaluation
POCS.is_weather_safe() reads the latest weather record from the database and
applies two checks:
- Safety flag — looks for
is_safe(then falls back tosafe) and casts it tobool. - Staleness — compares
timestampto the current time. If the record is older thanstaleseconds (default 180 s) the record is treated as unsafe regardless of the flag value.
This means any integration that stops writing records will automatically halt observations after the staleness window expires.
HTTP API
The weather FastAPI service (default port 6566) exposes two endpoints:
| Endpoint | Method | Description |
|---|---|---|
/status |
GET |
Returns the most recent reading as a JSON object (schema above) |
/config |
GET |
Returns the active weather station configuration |
Querying via the CLI
# Show a formatted status table
pocs weather status
# Show raw JSON
pocs weather status --show-raw-values
# Show configuration
pocs weather config
# Connect to a remote unit
pocs weather --host 192.168.1.100 --port 6566 status
AAG CloudWatcher Configuration
For the built-in AAG integration, settings live under environment.weather in your
config file:
environment:
weather:
serial_port: /dev/weather # or /dev/ttyUSB0
auto_detect: false # set true to probe all ttyUSB* ports
record_interval: 60 # seconds between DB writes
store_permanently: false # keep every reading, not just the latest
To set up the stable /dev/weather symlink automatically, run:
pocs weather setup
This scans USB serial ports, identifies the AAG CloudWatcher by its handshake response,
and writes a udev rule to /etc/udev/rules.d/92-panoptes-weather.rules.