F5 now builds, installs and attaches the debugger on the emulator, with the emulator booted automatically first, so there is no manual setup step between opening the project and stepping through code. tool/start_emulator.ps1 backs the preLaunchTask and is idempotent: it returns in about three seconds when a device is already attached, so re-launching the debugger cannot stack emulator instances. It fails with a useful message when the AVD is missing rather than hanging until a timeout. Five configurations rather than one, because they answer different questions. The profile-mode entry matters most for what comes next: debug builds run the Dart VM unoptimised, so the radar animation always looks worse than it is, and milestone 3's acceptance criterion is about whether it runs smoothly. The Windows entry trades the map away for a launch that takes seconds, which is worth it for pure UI work. Verified on this machine: the script cold-boots the AVD and waits for sys.boot_completed, and a second run exits immediately. Also removes the broken pixel_7_-_api_35 AVD, which could not boot because its system image was never installed. That returned 4.8 GB, taking free disk from 3.5 GB to 10.7 GB. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nuvolari
Precipitation radar for Piedmont, Italy. Android first, iOS later, one Flutter codebase.
Radar imagery comes from the public Radar-DPC platform, forecasts from MET Norway, weather alerts from the ARPA Piemonte XML-CAP bulletin. The app is free and ad-supported, with GDPR consent through Google's UMP.
Nuvolari is an independent app. It is not affiliated with, endorsed by, or operated by ARPA Piemonte or the Dipartimento della Protezione Civile. For civil-protection purposes the official channels always prevail.
Layout
app/ Flutter application (Dart package "nuvolari")
backend/ Python worker: fetches DPC rasters, crops, reprojects, renders PNG frames
docs/ architecture, data sources, licenses, stack decisions, roadmap, privacy
tool/ verification scripts
Start with docs/architecture.md, then docs/roadmap.md for what is built and what is next.
Toolchain
| Tool | Version |
|---|---|
| Flutter | 3.47.3 stable (Dart 3.13.3) |
| Android SDK | platform 36, build-tools 36.0.0, platform-tools |
| JDK | 21 |
| Python | 3.12+ (3.14 works; rasterio ships wheels for it) |
| Android NDK | 28.2.13676358 — pinned by maplibre_gl, not by this project |
A full toolchain plus a warm Gradle cache needs roughly 14 GB of disk: Flutter
3 GB, Android SDK 2.5 GB (2 GB of which is the NDK the map plugin pins), the Gradle
cache 5 GB, and build output around 2 GB. flutter clean reclaims the last of those.
Configuration
Secrets never enter the repository. Copy the template and fill it in:
cp env.example.json env.json # env.json is git-ignored
| Key | Purpose |
|---|---|
MAP_STYLE_URL |
MapLibre style URL. Empty falls back to a local offline style. |
RADAR_MANIFEST_URL |
Base URL of the published manifest.json. |
RADAR_SOURCE |
mock (offline demo), dpc (live), arpa (disabled stub). |
METNO_USER_AGENT_CONTACT |
Contact address for the MET Norway User-Agent — mandatory for forecasts. |
ADMOB_APP_ID, ADMOB_BANNER_UNIT_ID |
Empty means Google's test ad units are used. |
Running
cd app
flutter run --dart-define-from-file=../env.json
With no env.json the app starts in demo mode: mock radar frames from assets, offline
base map style, test ad units. No network and no credentials required.
Verifying
.\tool\verify.ps1 # format, analyze, test, build, lint, pytest
.\tool\verify.ps1 -SkipBuild # fast inner loop
Stages whose target does not exist yet are skipped, so this runs from day one.
Attribution
Radar-DPC (CC BY-SA) · MET Norway (CC BY 4.0) · Arpa Piemonte · © OpenStreetMap contributors (ODbL). See docs/licenses.md for the obligations these carry — in particular, the rendered radar frames are a derived product of CC BY-SA data and inherit share-alike.