Skip to content

Add Kīlauea Activity app - #587

Merged
tavdog merged 6 commits into
tronbyt:mainfrom
daveshilobod:add-kilauea-activity
Jul 20, 2026
Merged

Add Kīlauea Activity app#587
tavdog merged 6 commits into
tronbyt:mainfrom
daveshilobod:add-kilauea-activity

Conversation

@daveshilobod

@daveshilobod daveshilobod commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Kīlauea Activity

Kīlauea Activity state cycle

Adds a new 64×32 app that turns Kīlauea's latest official USGS status into an original animated pixel-art caldera.

This intentionally complements the existing kilauea webcam app rather than replacing it. No existing app files are changed: users can choose between live webcam imagery and this data-driven visual interpretation.

What it shows

  • Distinct quiet, building, erupting, warning, and no-data scenes.
  • The literal bulletin phase separately from the visual mode, so a paused eruption with forecast precursor signals can read PAUSED while using the warmer building scene.
  • A consistent four-rung USGS aviation-color indicator on the scene and status cards.
  • Bright 5×8 supporting text that scrolls only when it exceeds the display width.
  • A 14.2-second live animation and deterministic 12-second all-state preview.

Data and reliability

  • Uses the structured USGS HANS endpoint for volcano 332010: https://volcanoes.usgs.gov/hans-public/api/volcano/newestForVolcano/332010.
  • Selects the matching noticeSections entry by volcano number rather than trusting notice-wide maximum fields.
  • Caches HTTP responses for five minutes and retains the last valid normalized notice as a fallback.
  • Marks notices stale after 48 hours and refuses to present notices older than seven days as current.
  • Requires no API key, secrets, user data, or configuration.
  • This is an informational display and is not intended as an emergency-alerting system.

Validation

  • pixlet format --dry-run and pixlet lint pass.
  • pixlet check apps/kilaueaactivity passes with the repository-pinned Tronbyt Pixlet v0.50.1 and current v0.53.1.
  • Profile: roughly 280–340 ms, below the one-second CI budget.
  • Live and deterministic preview renders complete below the 15-second animation limit.
  • The standalone implementation's deterministic parsing/classification tests pass on both Pixlet versions.

Development source and tests: https://github.com/daveshilobod/tidbyt-kilauea

Summary by CodeRabbit

  • New Features
    • Added the Kīlauea Activity app with a 64×32 animated pixel display showing activity phases, alert levels/aviation colors, freshness/stale status, and forecast details.
    • Implemented live USGS notice rendering with short caching and “last good” fallback, plus fixture/mock and preview modes (scene/info/detailed animation). Supports an optional minimum alert-level threshold.
  • Documentation
    • Added a complete README describing the display states, data mapping, caching behavior, and deterministic rendering for informational use.
  • Chores
    • Added the app manifest, an animated WebP asset, and a 5-minute update interval entry.

@daveshilobod
daveshilobod requested a review from tavdog as a code owner July 19, 2026 22:15
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 636e120d-286c-44e0-9872-6f353a6d23e5

📥 Commits

Reviewing files that changed from the base of the PR and between 2d23180 and b90ce88.

📒 Files selected for processing (2)
  • apps/kilaueaactivity/kilaueaactivity.star
  • apps/kilaueaactivity/manifest.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/kilaueaactivity/manifest.yaml
  • apps/kilaueaactivity/kilaueaactivity.star

📝 Walkthrough

Walkthrough

Adds a Kīlauea Activity app that normalizes USGS HANS notices, caches live results, renders animated pixel-art scenes and status cards, and integrates the app with repository metadata, documentation, an image asset, and five-minute scheduling.

Changes

Kīlauea Activity app

Layer / File(s) Summary
USGS status normalization
apps/kilaueaactivity/kilaueaactivity.star
Adds fixture and live payload handling, volcano-section selection, synopsis cleaning, activity classification, freshness tracking, and normalized status models.
Fetch and cached fallback
apps/kilaueaactivity/kilaueaactivity.star
Fetches USGS HANS JSON, caches successful normalized results, refreshes cached freshness, and returns an unavailable status when needed.
Pixel scene and information rendering
apps/kilaueaactivity/kilaueaactivity.star
Renders animated activity scenes, alert ladders, mode-specific layers, information cards, forecast text, and detail lines.
App entrypoint and repository integration
apps/kilaueaactivity/kilaueaactivity.star, apps/kilaueaactivity/README.md, apps/kilaueaactivity/manifest.yaml, apps/kilaueaactivity/kilaueaactivity.webp, update_intervals.txt
Connects live, mock, preview, and demo modes, and adds app documentation, manifest metadata, the animated asset, and a five-minute update interval.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Device
  participant fetch_status
  participant USGS_HANS
  participant normalize_notice
  participant Renderer
  Device->>fetch_status: Request app status
  fetch_status->>USGS_HANS: GET volcano 332010 data
  USGS_HANS-->>fetch_status: Notice JSON
  fetch_status->>normalize_notice: Normalize notice and freshness
  normalize_notice-->>fetch_status: Status model
  fetch_status->>Renderer: Provide status model
  Renderer-->>Device: Render scene and information animation
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding the new Kīlauea Activity app.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/kilaueaactivity/kilaueaactivity.star`:
- Around line 592-600: Update short_date to strip the time component from
sent_utc before splitting and parsing the date, ensuring the year-month-day
prefix is used so the day conversion remains numeric and invalid input still
returns an empty string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d7c678b0-f4e6-4e71-8ac9-c4f41e1b536a

📥 Commits

Reviewing files that changed from the base of the PR and between 75495a4 and 5b46dd0.

📒 Files selected for processing (5)
  • apps/kilaueaactivity/README.md
  • apps/kilaueaactivity/kilaueaactivity.star
  • apps/kilaueaactivity/kilaueaactivity.webp
  • apps/kilaueaactivity/manifest.yaml
  • update_intervals.txt

Comment on lines +592 to +600
def short_date(sent_utc):
parts = sent_utc.split("-")
if len(parts) != 3:
return ""

month_number = int(parts[1])
if month_number < 1 or month_number > 12:
return ""
return "%s %d" % (MONTHS[month_number - 1][1], int(parts[2]))

@coderabbitai coderabbitai Bot Jul 19, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

USGS HANS newestForVolcano API sentUtc field format

💡 Result:

In the USGS Hazard Notification System (HANS) API, the sentUtc field generally follows the format: "YYYY-MM-DD HH:MM:SS" [1][2][3]. This represents the date and time the notice was sent in Coordinated Universal Time (UTC) [1]. For example, API responses show values such as "2026-07-03 20:06:55" and "2026-06-09 18:15:37" [2][3]. This field provides a standardized timestamp independent of local time zones for the various observatories [1]. Users should note that while this format is consistent in many HANS API endpoints, API implementations can occasionally vary or be updated, so it is recommended to verify the specific output for the endpoint being used [4][1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant function with line numbers.
sed -n '560,630p' apps/kilaueaactivity/kilaueaactivity.star | cat -n

printf '\n--- sentUtc usages ---\n'
rg -n 'sentUtc|short_date\(' apps/kilaueaactivity/kilaueaactivity.star

Repository: tronbyt/apps

Length of output: 2867


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- payload -> sent_date path ---'
sed -n '840,890p' apps/kilaueaactivity/kilaueaactivity.star | cat -n

printf '\n%s\n' '--- all sentUtc examples across repo ---'
rg -n '"sentUtc"|sentUtc' .

printf '\n%s\n' '--- nearby tests/fixtures for short_date or sent_date ---'
rg -n 'short_date|sent_date|sentUtc' apps/kilaueaactivity -A3 -B3

Repository: tronbyt/apps

Length of output: 7063


Strip the time portion before parsing sentUtc. HANS sentUtc values include a time component (for example 2026-07-03 20:06:55), so split("-") makes parts[2] non-numeric and int(...) can raise. Parse only the YYYY-MM-DD prefix to keep the detail view from crashing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/kilaueaactivity/kilaueaactivity.star` around lines 592 - 600, Update
short_date to strip the time component from sent_utc before splitting and
parsing the date, ensuring the year-month-day prefix is used so the day
conversion remains numeric and invalid input still returns an empty string.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this make sense to do or is coderabbit a dummy ?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline apps/kilaueaactivity/kilaueaactivity.star \
  --items all \
  --type function \
  --match 'normalize_notice|short_date|detail_line'

printf '\n--- normalization and date-display path ---\n'
rg -n -A90 -B10 'def normalize_notice\(|def short_date\(|def detail_line\(' \
  apps/kilaueaactivity/kilaueaactivity.star

printf '\n--- date-related test coverage ---\n'
rg -n -A4 -B4 'short_date|sent_date|sentUtc' apps/kilaueaactivity

Length of output: 13176


@tavdog — the Comment image shows a small dark blue/purple starfield thumbnail with scattered pale stars and a faint central glow; no text or controls are visible.

This one makes sense. The live path copies payload["sentUtc"] directly into sent_date (Line 870), and short_date() later does int(parts[2]) (Line 600). For a normal timestamp like 2026-07-03 20:06:55, parts[2] becomes "03 20:06:55", causing a conversion error when the detail view renders.

The fixtures use date-only values, so they mask the problem.

A minimal safe fix is:

def short_date(sent_utc):
    date = sent_utc.split(" ")[0]
    parts = date.split("-")
    if len(parts) != 3:
        return ""

    month_number = int(parts[1])
    if month_number < 1 or month_number > 12:
        return ""
    return "%s %d" % (MONTHS[month_number - 1][1], int(parts[2]))

So: not a dummy finding—just a slightly overdramatic severity label for a small, valid defensive parsing fix.

@tavdog tavdog left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice complement to the cam app ! Does the coderabbit suggestion make sense at all ? If not then I approve.

tavdog and others added 4 commits July 20, 2026 11:35
@tavdog
tavdog merged commit 0654232 into tronbyt:main Jul 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants