Files

7.6 KiB

name, description
name description
weather Record a day's high temperature, low temperature, rainfall, growing degree days, solar energy, and freezing exposure in that day's daily note, read from the home weather station. Use whenever the user asks to log, add, backfill, or look up the weather for a date — including when they say only "yesterday's weather" or "add the weather to my daily note", when they ask about growing degree days, GDD, accumulated heat, solar energy, frost or freezing hours, and including the scheduled run that fills in the day that just ended.

weather — a day's weather in the daily note

Shell the weather-day CLI from in this skill's scripts directory with the bash tool, then write its values into the daily note's frontmatter. Nothing here needs a key or a login — the station is public.

Getting the numbers

weather-day [YYYY-MM-DD]      # no argument: yesterday

One JSON object on stdout:

{ "date": "2026-08-18", "station_id": 173994,
  "temp_high": 72.3, "temp_low": 54.1, "rainfall": 0.02,
  "gdd_base50": 11.4, "solar_energy_kwh_m2": 6.83,
  "observations": 287, "coverage_hours": 23.9 }

On a day that went below freezing, two more keys appear between solar_energy_kwh_m2 and observations:

  "hours_below_freezing": 7.2, "freezing_degree_hours": 31.8,
key units what it is
temp_high, temp_low °F the day's extremes
rainfall inches total for the day
gdd_base50 °F-days growing degree days, base 50°F
solar_energy_kwh_m2 kWh/m² total solar energy on a horizontal surface
hours_below_freezing hours time spent under 32°F
freezing_degree_hours °F-hours how far under 32°F, integrated over that time

Everything from date through freezing_degree_hours is a frontmatter key — copy the values across unchanged rather than reformatting or re-rounding them. observations and coverage_hours are diagnostics; they stay out of the note.

Three of them are written only when they have something to say. rainfall is omitted from the note when it is 0 — most days here are dry, and a rainfall: 0 on four notes in five is noise that makes the days it did rain harder to spot. hours_below_freezing and freezing_degree_hours are omitted by weather-day itself on a day that never went below 32°F, so they are simply not there to copy. Either way the key's absence is the record: a dry day, a day with no frost.

Note the difference in where the omission happens. weather-day always prints rainfall, 0 included — that is a measurement, and the CLI reports it. Dropping it is this skill's decision about the note, so do not expect the JSON to be missing it.

gdd_base50 is one day's accumulation, not a running total. It is the number you sum to answer a question — days from planting to harvest, from transplanting to first bloom, from fruit set to ripe. A single day's value on its own says very little. When the user asks "how many GDD since I planted the tomatoes", add up the gdd_base50 of each daily note from that date forward; say how many days you summed and flag any in the range that have no value rather than treating a missing day as zero.

Any failure exits non-zero with a message on stderr. Report it and stop; do not write a partial or guessed value into the note. That includes the station going quiet mid-day: the totals are integrals over the whole day, so rather than draw a straight line across an hour or more of missing readings, weather-day refuses the date outright. There is no partial answer to salvage and nothing to write — say which stretch is missing and leave the note alone.

Check the coverage before writing

coverage_hours is the span from the first observation to the last. A full day is ~24 (23 or 25 across a DST change).

observations is a count, not a duration, and a low-looking one is not by itself a problem: the API answers a day-long range on a 5-minute grid, so a complete day is around 288, not the ~1440 a per-minute feed would give. Judge the day by coverage_hours.

If coverage_hours is under 20, do not write to the note. Tell the user the day is only partly covered and give them the numbers to judge. A high or low computed from part of a day looks entirely normal in the frontmatter and stays wrong forever. It usually means the station was offline for a stretch, or the date asked for is today and the day hasn't finished.

A hole inside the day is a hard failure rather than a low coverage_hours, so a number that gets here has no outage longer than an hour in it. What coverage_hours still catches is a day the station started or stopped reporting partway through — and for the totals that is worse than for the extremes: gdd_base50 and solar_energy_kwh_m2 are missing the hours that never arrived, so they come out low, plausibly, and stay that way in every season sum afterwards.

Writing it into the note

The note is <vault>/daily/<date>.md — the date exactly as weather-day echoed it back, and the absolute path, always.

If the note exists: add or update only the keys you are writing. Every other key keeps its value and its position, and the body is untouched — the vault syncs live from other devices, so a rewritten note is a sync conflict waiting to happen. Add new keys at the end of the frontmatter block.

If the note does not exist: create it with just those keys and the date as an H1.

---
temp_high: 72.3
temp_low: 54.1
rainfall: 0.02
gdd_base50: 11.4
solar_energy_kwh_m2: 6.83
---
# 2026-08-18

A dry day with no frost is the common shape, and has neither rainfall nor the freezing pair:

---
temp_high: 78.1
temp_low: 55.6
gdd_base50: 14.4
solar_energy_kwh_m2: 7.02
---
# 2026-08-19

Any of those keys you are not writing, delete from the note if it is already thererainfall when the day was dry, hours_below_freezing and freezing_degree_hours when it never froze. Absence is the record, so a value left behind from an earlier run reports rain or a frost that did not happen, in exactly the format a real one would take. This is the one case where this skill removes rather than only adds, and it reaches only those three keys — never anything else in the frontmatter.

Re-running a date is otherwise safe: the same keys get the same values again.

Reading it back

To answer "what was the weather on X" for a day already recorded, read the note's frontmatter — that is faster than a station call and it is the recorded value. Call weather-day when the note has no weather keys yet, or when the user wants the station's answer rather than the note's.

A missing rainfall on a note that carries the other weather keys means zero, not unknown. The same goes for the freezing pair. So when totalling rain over a month or frost hours over a winter, a note with temp_high but no rainfall is a recorded dry day: count it as 0 and as a day you have data for. Reading it as a gap gets the total right by luck and everything around it wrong — it reports most of a dry July as unmeasured, and sends you re-running weather-day over days that were never missing. A note with none of the weather keys is the genuinely unrecorded case, and that one is worth saying out loud or filling in before answering.

gdd_base50 is different — it is written on every recorded day, including a 0. A daily note missing it has not been filled in, and should be reported as a hole rather than summed as zero.

A different station

STATION_ID is a constant at the top of the weather-day script, in this skill's directory. Changing it needs an image rebuild; say so rather than trying to override it at the command line.