Skip to content

Standardize country codes iso 3166#159

Open
ram-from-tvl wants to merge 5 commits intoopenclimatefix:mainfrom
ram-from-tvl:standardize-country-codes-iso-3166
Open

Standardize country codes iso 3166#159
ram-from-tvl wants to merge 5 commits intoopenclimatefix:mainfrom
ram-from-tvl:standardize-country-codes-iso-3166

Conversation

@ram-from-tvl
Copy link
Contributor

Pull Request

Description

This PR standardizes all country codes in the solar-consumer project to follow the ISO 3166-1 alpha-3 standard, as requested in issue #157.

Changes made:

Old Code New Code Country
gb gbr_gb Great Britain (excluding Northern Ireland)
nl nld Netherlands
de deu Germany
be bel Belgium
ind_rajasthan ind_rj India – Rajasthan

Files updated:

  • fetch_data.py — Updated country code dict keys, default parameter, docstring, and error message
  • app.py — Updated all country conditionals, default parameters, docstring, and os.getenv default
  • save_data_platform.py — Updated default parameter, docstring, and all country comparisons/comments
  • save_site_database.py — Updated all country comparisons, default parameters, docstrings, and error messages
  • test_fetch_data.py — Updated country= argument in GB historic tests
  • test_save_forecast.py — Updated country= argument for NL and India tests
  • test_save_nl_to_data_platform.py — Updated country= argument
  • README.md — Updated COUNTRY environment variable documentation
  • .example.env — Updated default COUNTRY value and available options comment

Only country code parameter strings were changed. No data-level identifiers (e.g. "nl_national" site names, "Belgium" region names from the Elia API) were modified — these are data values, not country code parameters.

Fixes #157

Checklist:

  • My code follows OCF's coding style guidelines
  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works (updated existing tests with new country codes)
  • I have checked my code and corrected any misspellings

Copilot AI review requested due to automatic review settings February 9, 2026 05:19
@ram-from-tvl
Copy link
Contributor Author

Hi @peterdudfield
I have made changes for country codes standardization.
Please review it and let me know if we are good to go.
Thank you!

@ram-from-tvl
Copy link
Contributor Author

All tests have passed.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to standardize country code parameters across the solar-consumer project to ISO 3166-1 alpha-3-style codes (with special handling like gbr_gb), updating application defaults, dispatch logic, and tests/docs accordingly.

Changes:

  • Updated country-code parameters/defaults across fetch, save, and app orchestration paths (e.g. gb→gbr_gb, nl→nld, de→deu, be→bel, ind_rajasthan→ind_rj).
  • Updated unit/integration tests to use the new country code strings.
  • Updated user-facing documentation and example environment configuration to reflect the new codes.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
solar_consumer/fetch_data.py Updates default country and dispatch table keys to new codes; updates docstrings/messages.
solar_consumer/app.py Updates default country and country→model_tag mapping to new codes.
solar_consumer/save/save_data_platform.py Updates default country and NL/GB branching comparisons to new codes.
solar_consumer/save/save_site_database.py Updates defaults and country comparisons/docstrings for site-db saving logic.
solar_consumer/data/fetch_gb_data.py Adds fallback logic for missing GSPs (DB-backed) and adjusts handling of empty GSP frames.
tests/unit/test_fetch_data.py Updates GB historic tests to call fetch_data(..., country="gbr_gb").
tests/unit/test_save_forecast.py Updates NL and India country args used in save tests.
tests/integration/test_save_nl_to_data_platform.py Updates NL integration test to use country="nld".
README.md Updates COUNTRY env var docs to new codes.
.example.env Updates default COUNTRY value and comment options list.
Comments suppressed due to low confidence (1)

solar_consumer/save/save_data_platform.py:56

  • save_generation_to_data_platform treats any country other than "nld" as the GB branch. Now that the application supports other country codes (e.g. "deu", "bel", "ind_rj"), calling this with those values (e.g. via app.py when SAVE_METHOD=data-platform) will incorrectly assume GB columns like gsp_id/regime exist and can fail or silently write bad data. Add explicit validation (raise for unsupported countries) or implement dedicated branches per supported country.
    # 0. Create the observers required if they don't exist already
    if country == "nld":
        required_observers = {"nednl"}
        id_key = "region_id"
        capacity_col = "capacity_kw"
        capacity_multiplier = 1000
    else:  # gbr_gb
        required_observers = {"pvlive_in_day", "pvlive_day_after"}
        id_key = "gsp_id"
        capacity_col = "capacity_mwp"
        capacity_multiplier = 1e6


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

logger.info(f"Created backup data for {len(backup_rows)} entries")
except Exception as e:
logger.error(f"Error creating backup GSP data: {e}")

Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

fetch_gb_data_historic now only appends non-empty frames to all_gsps_yields, but still unconditionally returns pd.concat(all_gsps_yields, ...). If PVLive returns empty data for all queried GSPs (e.g., upstream outage), all_gsps_yields will be empty and pd.concat will raise ValueError: No objects to concatenate. Handle the empty-list case by returning an empty DataFrame with the expected columns (or by always appending an empty frame).

Suggested change
if not all_gsps_yields:
# Return an empty DataFrame with the expected columns if no data was fetched
return pd.DataFrame(
columns=[
"target_datetime_utc",
"solar_generation_kw",
"gsp_id",
"installedcapacity_mwp",
"capacity_mwp",
"regime",
"pvlive_updated_utc",
]
)

Copilot uses AI. Check for mistakes.
Comment on lines +179 to +188
if missing_gsps and national_df is not None:
logger.info(f"Creating backup data for {len(missing_gsps)} missing GSPs using national data")
db_url = os.getenv("DB_URL")
if not db_url:
logger.warning("DB_URL not set, cannot create backup GSP data")
else:
try:
connection = DatabaseConnection(url=db_url)
with connection.get_session() as session:
locations = session.query(LocationSQL).filter(LocationSQL.gsp_id.in_(missing_gsps)).all()
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

This adds new behavior beyond country-code standardization: when GSPs are missing it attempts to connect to the database (via DB_URL) and synthesize backup per-GSP data from national data and LocationSQL capacities. This contradicts the PR description claim that only country-code parameter strings changed, and it also introduces a runtime dependency on DB connectivity during data fetching. Either remove this change from the PR or update the PR description/scope and add tests/guardrails for this new backup path.

Copilot uses AI. Check for mistakes.
Comment on lines 69 to 76
If `capacity_override_kw` is provided, that value will be used when creating the site.
For Germany, the TSO’s known capacity is used if no override is given. For NL, default 20GW applied

Parameters:
session (Session): CurrentSQLAlchemy session
pvsite (PVSite): Pydantic model with site metadata
country (str): Country code ('nl' or 'de')
country (str): Country code ('nld' or 'deu')
capacity_override_kw (Optional[int]): Force a specific capacity on creation
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

The get_or_create_pvsite docstring says country is ('nld' or 'deu'), but the function is also used for India Rajasthan via save_generation_to_site_db(... country="ind_rj"). Update the docstring (and/or the capacity-selection comment) to include the supported ind_rj code so callers know it’s valid.

Copilot uses AI. Check for mistakes.

:param country: "gb", "nl", "de", "ind_rajasthan", or "be"
:param country: "gbr_gb", "nld", "deu", "ind_rj", or "bel"
:param historic_or_forecast: "generation" or "forecast"
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

fetch_data docstring says historic_or_forecast is "generation" or "forecast", but the codebase uses other values too (e.g. GB historic tests pass "historic"; India fetcher defaults to "historic" and ignores it). This makes the public API misleading. Document the actual accepted values (or normalize/validate them in fetch_data before dispatch).

Suggested change
:param historic_or_forecast: "generation" or "forecast"
:param historic_or_forecast: Indicator passed through to the country-specific fetcher, e.g. "forecast",
"generation", or "historic". The exact accepted values are backend-specific; see the corresponding
fetch_<country>_data function for details.

Copilot uses AI. Check for mistakes.

- `DB_URL=postgresql://postgres:postgres@localhost:5432/neso_solar` : Database Configuration
- `COUNTRY="gb"` : Country code for fetching data. Currently, other options are ["be", "ind_rajasthan", "nl"]
- `COUNTRY="gbr_gb"` : Country code for fetching data. Currently, other options are ["bel", "ind_rj", "nld"]
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

README COUNTRY documentation lists other options as ["bel", "ind_rj", "nld"], but the application also supports Germany ("deu") (see app.py country→model_tag mapping and fetch_data dispatch table). Update the README options list to include "deu" (and any other supported codes) to avoid misconfiguration.

Suggested change
- `COUNTRY="gbr_gb"` : Country code for fetching data. Currently, other options are ["bel", "ind_rj", "nld"]
- `COUNTRY="gbr_gb"` : Country code for fetching data. Currently, other options are ["bel", "deu", "ind_rj", "nld"]

Copilot uses AI. Check for mistakes.
Comment on lines 61 to 62


Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

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

app() assigns model_tag only for a fixed set of countries and has no else/default. If an unsupported country value is provided (e.g. via COUNTRY env var), model_tag will be undefined and the function can crash later with UnboundLocalError. Add an explicit else that raises a clear exception listing supported country codes.

Suggested change
else:
supported_countries = ["gbr_gb", "nld", "deu", "bel"]
raise ValueError(
f"Unsupported country code: {country!r}. "
f"Supported country codes are: {', '.join(supported_countries)}."
)

Copilot uses AI. Check for mistakes.
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.

Standardise countries ISO_3166-1_alpha-3

1 participant