Skip to content

Add Solar Buddy app - #171

Open
sujithq wants to merge 1 commit into
badger:mainfrom
sujithq:sujithq-solar-buddy
Open

sujithq wants to merge 1 commit into
badger:mainfrom
sujithq:sujithq-solar-buddy

Conversation

@sujithq

@sujithq sujithq commented Nov 3, 2026 •

Copy link
Copy Markdown

What does this PR do?

Adds Solar Buddy, an animated solar companion that reads Home Assistant power sensors (solar, grid import, grid export) and recommends appliances after a stable surplus. It runs in demo mode with simulated data and no network, or in live mode against a Home Assistant instance. Recommendations are read-only.

  • Physical badge: live mode uses the existing socket HTTP client.
  • Badge Simulator canvas: the WebAssembly runtime has no socket module, so ha_client.py selects a new asynchronous browser fetch client (browser_http.py) when sys.platform == "webassembly". It is read-only, has timeouts, rejects redirects, limits bodies to 16 KiB and is cancellable. When CORS hides the HTTP Date header it falls back to the browser's UTC clock for the freshness check and prints a one-time notice.
  • Credentials: live mode reads a private /state/solar_buddy_secrets.json. The app ships a credential-free solar_buddy_secrets.example.json and a .gitignore for the real solar_buddy_secrets.json and settings.json. The README documents how to provide the file locally, on the badge (mpremote fs cp ... :/state/...) and in the canvas, and warns not to deploy the private file into apps/.
  • Missing optional config files are handled on both the badge (errno 2) and the canvas (errno 44).

Type of change

  • New badge app
  • Improvement or bug fix to an existing app
  • Firmware, menu, or system change
  • Documentation
  • Infrastructure (workflows, scripts, tooling)
  • Universe 2025 (badge25/) maintenance

Badge app checklist

  • The app lives in badge/apps/<name>/ with __init__.py and a 24x24 icon.png
  • README.md starts with a one-sentence description, followed by usage and any hardware or network requirements
  • Uses the 2026 runtime globals (badge, screen, image, ...) and logical buttons such as BUTTON_SELECT
  • Movement and animation are frame-rate independent (badge.ticks_delta)
  • Tested on Universe 2026 badge hardware, including both orientations and the capacitive controls
  • Assets are in assets/, are PNG where possible, and are as small as practical (only icon.png)
  • No secrets, tokens, or personal data are committed (badge/secrets.py stays empty)

Verification so far

  • python .github/scripts/validate_app_readmes.py badge/apps: passed.
  • Badge Simulator canvas: ran against a real Home Assistant instance, status LIVE, readings refreshed across polls with no errors.
  • Not tested on a physical badge: I don't have a Universe 2026 badge yet, so that checklist item is left unchecked. Testing on hardware by a maintainer or another contributor would be appreciated; the badge path uses the existing socket HTTP client.

Screenshots

Live mode in the Badge Simulator (320x240): the Buddy screen showing LIVE with solar, home and grid-import readings.

Solar Buddy live in the Badge Simulator

How to use it

Left/right switch screens; up/down select a scenario (demo) or appliance; Select opens appliance details, or toggles demo/live in Settings (and retries in live mode); Back returns to Buddy; Menu opens Settings; Home returns to the launcher. Shake briefly wakes the face. Live setup is described in the app README under "Home Assistant credentials".

Licensing and intellectual property

  • I created all code and assets in this PR, or they are already available under an MIT-compatible license and I have credited them in the app README
  • This PR doesn't include third-party characters, logos, trademarks, or other IP, or the owner has agreed to its release under the MIT License
  • I agree that my contribution is licensed under this project's MIT License

Additional notes

  • Live mode on hardware needs Wi-Fi configured in the badge's existing settings and a private credentials file in /state. When deploying the whole app folder by USB mass storage, make sure solar_buddy_secrets.json is not copied into apps/solar_buddy/.
  • Canvas live mode needs the canvas origin (including port) allowed in Home Assistant's http.cors_allowed_origins.

Home Assistant solar companion with demo and live modes. Live mode works on the badge (socket client) and in the Badge Simulator canvas (browser fetch client with a browser-clock fallback when CORS hides the Date header). Credentials stay in a git-ignored private file copied to /state.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sujithq
sujithq force-pushed the sujithq-solar-buddy branch from 4a5f705 to 7b11b96 Compare November 3, 2026 15:45
@sujithq
sujithq marked this pull request as ready for review November 3, 2026 15:50
Copilot AI balanced review requested due to automatic review settings November 3, 2026 15:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Stale nonzero export readings can incorrectly make appliances READY, while Wi-Fi reported as connected without an IP address can prevent reconnect attempts.

2 open issues
What changed in this PR

Adds Solar Buddy, a Universe 2026 badge app that displays Home Assistant power readings and recommends appliances after sustained solar surplus.

Changes:

  • Adds animated screens, simulated scenarios, appliance advice, and saved preferences.
  • Implements read-only Home Assistant polling through socket and browser HTTP clients.
  • Documents live setup, private credentials, simulator requirements, and deployment.
File Description
badge/​apps/​solar_buddy/​ui.py Renders dashboard, energy, appliance, and settings screens.
badge/​apps/​solar_buddy/​solar_buddy_secrets.example.json Provides a credential-free connection template.
badge/​apps/​solar_buddy/​settings.example.json Provides configurable thresholds, timing, and appliance loads.
badge/​apps/​solar_buddy/​README.md Documents controls, setup, credentials, and deployment.
badge/​apps/​solar_buddy/​http_client.py Implements bounded, incremental socket HTTP requests.
badge/​apps/​solar_buddy/​hardware.py Adds optional shake detection and case-light feedback.
badge/​apps/​solar_buddy/​ha_client.py Coordinates sensor polling and Wi-Fi recovery.
badge/​apps/​solar_buddy/​energy.py Validates power readings, freshness, and mood transitions.
badge/​apps/​solar_buddy/​demo.py Supplies simulated power and failure scenarios.
badge/​apps/​solar_buddy/​controller.py Manages navigation, operating modes, and application state.
badge/​apps/​solar_buddy/​config.py Loads and validates settings and credentials.
badge/​apps/​solar_buddy/​clock.py Provides wrap-safe timing helpers.
badge/​apps/​solar_buddy/​character.py Draws and animates the solar character.
badge/​apps/​solar_buddy/​browser_http.py Provides asynchronous browser requests for the simulator.
badge/​apps/​solar_buddy/​advisor.py Tracks sustained surplus for appliance recommendations.
badge/​apps/​solar_buddy/​.gitignore Excludes private credentials and local settings from Git.
badge/​apps/​solar_buddy/​__init__.py Connects the app to the badge runtime and lifecycle.

Review effort: Balanced

Comment on lines +121 to +122
if len(ages) > 2 and min(ages[1], ages[2]) > max_age_s:
raise ValueError(entities[1] + " and " + entities[2] + ": stale sensor reports")
raise ValueError("Configure WIFI_SSID in the badge's existing secrets.py")

def tick(self, now):
if self.wlan.isconnected():

This branch has not been deployed

No deployments
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