Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Solar Mapper

A Django web application that displays US commercial sites on an interactive map and estimates their solar energy potential using NREL's PVWatts API. Sites are geocoded from street addresses, then analyzed for annual AC energy production and capacity factor using a standard 100 kW commercial system model.


Prerequisites


Setup Instructions

1. Clone and create a virtual environment

git clone <repo-url>
cd solar-mapper
python3 -m venv venv
source venv/bin/activate

2. Install dependencies

pip install -r requirements.txt

requirements.txt pins exact versions for all direct and transitive dependencies. Installing from it guarantees an identical environment to the one used during development.

3. Get an NREL API key

  1. Go to developer.nrel.gov/signup
  2. Fill out the short form — the key is issued instantly by email
  3. The key unlocks both the Solar Resource API and PVWatts v8

4. Configure the .env file

cp .env.example .env

Open .env and replace the placeholder:

NREL_API_KEY=your_actual_key_here

The .env file is listed in .gitignore and will never be committed.

5. Run migrations

python3 manage.py migrate

6. Create a superuser

python3 manage.py createsuperuser

Or use the pre-configured development credentials:

echo "from django.contrib.auth import get_user_model; U = get_user_model(); U.objects.create_superuser('admin', 'admin@example.com', 'admin123')" | python3 manage.py shell

7. Load the 5 test sites

This single command resets the database, loads the fixture, geocodes all addresses, and fetches solar data:

python3 manage.py load_sites

Expected output:

Loaded 5 site(s) from fixture.
--- Geocoding ---
  [101] Tesla Gigafactory Texas ... OK (30.22193, -97.61877)
  [102] Amazon Fulfillment Center ... FAILED — No results found
  [103] Google Data Center ... OK (41.25766, -95.89954)
  [104] Walmart Distribution Center ... OK (32.97827, -97.30684)
  [105] Invalid Address Test ... FAILED — No results found

--- Solar Data ---
  [101] Tesla Gigafactory Texas ... OK  147,130 kWh/yr
  ...

--- Summary ---
  [OK]     Tesla Gigafactory Texas → (30.2219, -97.6188)  147,130 kWh/yr
  [FAILED] Amazon Fulfillment Center → No results found for address: ...
  [OK]     Google Data Center → (41.2577, -95.8995)  140,930 kWh/yr
  [OK]     Walmart Distribution Center → (32.9783, -97.3068)  157,027 kWh/yr
  [FAILED] Invalid Address Test → No results found for address: ...

Running the Application

python3 manage.py runserver

Open http://127.0.0.1:8000/ in your browser.

You will see:

  • A full-screen interactive map centered on the continental US
  • Blue markers for successfully geocoded and analyzed sites
  • Red markers for sites where geocoding failed (positioned in the Gulf region for visibility)
  • Clicking any marker opens a popup with the site name and a link to its detail page
  • The detail page shows solar irradiance, annual energy production, and capacity factor for successful sites, or a clear error banner for failed ones

The Django admin is available at http://127.0.0.1:8000/admin/ (credentials: admin / admin123). The site list can be filtered by geocode status using the right-hand sidebar.


Architecture Notes

Why Django over Node/Express

Django was chosen because it offers a mature ORM, built-in admin interface, and management commands out of the box, all directly useful for this scope. The admin panel alone provides a free UI for verifying geocoding results without writing any additional code. Python is also the natural language for data-adjacent work like API integration and batch processing.

Why Nominatim for geocoding

Nominatim (OpenStreetMap's geocoding service) is free and requires no API key, making the project fully runnable without any account setup beyond NREL. It has strong coverage for US commercial addresses. A 1-second delay is enforced between requests per Nominatim's usage policy.

Why CARTO tiles

CARTO's basemap tiles (light_all) are more permissive than the OSM default tile server for development use. The OSM tile CDN enforces referrer restrictions that cause 403 errors in local Django development. CARTO tiles require no API key and provide a clean, low-contrast base layer that keeps site markers visually prominent.

Why management commands for API operations

Geocoding and solar data fetching are batch operations with rate limits and external costs. Running them as management commands (geocode_sites, fetch_solar_data) means they execute intentionally on demand rather than on every page load. Each command is independently re-runnable: geocode_sites only touches pending sites; fetch_solar_data only touches geocoded sites with no existing solar data.

How error handling works

Every external API call returns a normalized result dict (success, data fields, error). The geocode_status field on each Site tracks state (pending / success / failed), and geocode_error stores the human-readable reason. Failed sites are never silently dropped and they appear as red markers on the map with their error message in the popup, and their detail page shows a prominent warning banner explaining why solar analysis is unavailable.


Key Design Decisions

Decision Rationale
JSONField for solar data NREL responses vary by endpoint; a flexible field avoids premature schema design and makes it easy to store both Solar Resource and PVWatts outputs together
Separate geocoding and solar commands Decoupled retry logic — if NREL is down, geocoding results are preserved; if an address is wrong, only that step needs to be re-run
Red vs blue markers Immediate visual distinction between operational and failed sites; failed sites remain visible on the map rather than being silently hidden
1-second Nominatim delay Nominatim's usage policy requires a maximum of 1 request/second; the delay is enforced in services.py at the call site, not left to the caller
update_fields on save Management commands use update_fields to avoid race conditions and unintentionally overwriting unrelated fields during batch updates

Management Commands Reference

Command What it does
python3 manage.py load_sites Full reset: delete all sites, load fixture, geocode, fetch solar data
python3 manage.py geocode_sites Geocode all pending sites
python3 manage.py fetch_solar_data Fetch NREL data for all geocoded sites missing solar data

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages