Skip to content

Architecture

monikapurpl3 edited this page Aug 21, 2026 · 1 revision

Architecture

Breeze is an HTTP client and nothing more: it holds no state the server does not, and every capability it has is an endpoint on Breeze Core. That is why deleting the app leaves the server and the web panel working, and why the app can be pointed at a different server in a second.

lib/
├── main.dart                    Material You theming + stage router
└── src/
    ├── models.dart              wire models (units, control incl. beep, programs)
    ├── api_client.dart          HTTP layer: TLS enforcement, timeouts, typed errors, request signing
    ├── device_signer.dart       Ed25519 keypair + SHA3-512 request signing (auth v2)
    ├── secure_store.dart        encrypted credential storage (key, Ed25519 seed / bearer token)
    ├── app_controller.dart      app state + pairing + in-place v1 -> v2 upgrade
    ├── app_scope.dart           InheritedNotifier exposing the controller
    ├── home_widget_service.dart home-screen widget sync + headless control callback
    ├── theme.dart / util.dart   Material You accents, time helpers
    ├── screens/                 onboarding, pairing, home (swipe pager), unit_page,
    │                            diagnostics, programs, program_edit, settings
    └── widgets/                 temp_control, fan_control, flap_control, power_switch,
                                 big_toggle, mode_selector, curve_painter,
                                 climate_settings_editor

android/app/src/main/
├── kotlin/app/breeze/breeze/   BreezeUnitWidgetProvider + UnitConfigActivity (App Widget)
│   └── car/                    Android Auto: BreezeCarAppService, PowerScreen, CarUnitStore
└── res/                        layout/breeze_widget*, xml/{breeze_widget_info,automotive_app_desc},
                                widget + car drawables, colours

Three decisions worth knowing

The native surfaces share the phone's credentials rather than their own. The home-screen widgets and the Android Auto screen both read the same cached unit list and fire the same headless background callback, which goes through api_client and device_signer. Neither ships a second API client, and neither carries a copy of the crypto. The cost is that the app must be opened once after install so there is something cached; the benefit is one signing path to get right.

Credentials live in the Keystore, per server. secure_store keys everything by server profile, which is what lets Multiple servers work without re-pairing when you switch back.

Feature detection, not version checks. The app reads the server's advertised feature list and degrades: no SSE means polling, no scan means manual IP entry, no beep field means the toggle stays hidden. That is why it works against any server version rather than requiring a matched pair.

Clone this wiki locally