Repository navigation
Feat/lfenergy demo example #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nicburgt
wants to merge
35
commits into
main
Choose a base branch
from
feat/lfenergy-demo-example
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
cec0a6c
Add initial version of openadr-plugin
f27d1bb
chore: upgrade minimum version to FM v0.33
Flix6x 399ba39
Use SHA hashes for github actions, use ingestion queue, add pytest sp…
a952a5f
Update openadr3-client to latest version
36b888e
rename function, move top level imports
5f8d3b1
Fix mypy, ruff errors
bdac3d2
Set credits to elaad and foss email
0ead655
Remove certs
2ff2a5d
Clean up str based time storage in favor of python native time type
4e393e0
Fix structure of tests. Ensure tests pass with FM 0.33.0
bd0635d
Fix type errors, formatting
ff9a614
Newline fix
e57f98a
newline fix gitignore
a0be498
Add cronscheduler to plugin
84416f4
Add threading for cronscheduler
71497d9
Add cron scheduler as a dedicated worker which allows flexmeasures to…
61d52ad
Make final improvements related to openadr plugin initial version
57a7cdb
Clean up modules
1162c11
Fix potential lock issue in fresh start scenario
c90bcb4
Process PR comments
86b094f
Resolve mypy and ruff errors
545bd4b
Final fixes for typing and formatting
0f78822
Update uv lock with correct CI version
536efee
Upgrade uv to latest version
f913f83
Update trigger for CI
8dd1826
Pin to darwin and linux platform due to testcontainer limitation
8cf5440
Remove extra whitespace from CI
a74936b
Update pre commit config yaml
c9465f1
Create initial WIP example which creates asset structure and configur…
c6239bb
Introduce semi-realistic forecasts for all assets in lf-energy-demo
02f62f7
Initial 'good enough' LF energy demo scenario
6654eab
merge main into branch
f956f15
Fix account_id bug in asset, clean up example
d03add6
Improve example
e8f45b3
Update live demo walkthrough script
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # `.github/instructions/` — Path-Specific Custom Instructions | ||
|
|
||
| This directory contains [path-specific custom instructions](https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/add-custom-instructions/add-repository-instructions#creating-path-specific-custom-instructions) for GitHub Copilot. | ||
|
|
||
| Each `<topic>.instructions.md` file covers a cross-cutting convention that applies to multiple areas of the codebase. Copilot automatically applies these instructions when working on files that match the `applyTo:` glob pattern in the file's frontmatter. | ||
|
|
||
| ## Files in this directory | ||
|
|
||
| | File | `applyTo` | Topic | | ||
| |------|-----------|-------| | ||
| | `atomic-commits.instructions.md` | `**` | Commit discipline — one logical change per commit | | ||
| | `changelog.instructions.md` | `**` | Changelog entry format and location | | ||
| | `docstrings.instructions.md` | `**/*.py` | RST docstring format, doctests | | ||
| | `error-handling.instructions.md` | `**/*.py` | Catching specific exceptions | | ||
| | `marshmallow-schemas.instructions.md` | `flexmeasures/data/schemas/**/*.py` | `data_key`, field naming, `load_default` | | ||
| | `pre-commit-hooks.instructions.md` | `**` | Running hooks before every commit | | ||
| | `testing.instructions.md` | `flexmeasures/**/tests/**/*.py` | Full suite, `db` vs `fresh_db`, `requesting_user` | | ||
| | `timezone-awareness.instructions.md` | `**/*.py` | Always timezone-aware datetimes | | ||
| | `ui-terminology.instructions.md` | `flexmeasures/ui/**` | "organisation" not "account" in user-facing text | | ||
|
|
||
| ## Adding new instruction files | ||
|
|
||
| When a convention appears in two or more agent files or is frequently missed, extract it here: | ||
|
|
||
| 1. Create `<topic>.instructions.md` in this directory. | ||
| 2. Add a YAML frontmatter block with `applyTo:` pointing to the relevant files. | ||
| 3. Write concise, actionable instructions in natural language Markdown. | ||
| 4. Update the table above. | ||
| 5. Reference the new file from the relevant agent files in `.github/agents/`. | ||
| 6. Go through the agent files to remove sections that have been made redundant by the new file. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| --- | ||
| applyTo: "**" | ||
| --- | ||
| # Atomic Commits | ||
|
|
||
| Each commit must represent exactly one logical change. Never mix different types of changes. | ||
|
|
||
| ## What belongs in separate commits | ||
|
|
||
| - Production code changes | ||
| - Test changes | ||
| - Documentation updates | ||
| - Agent instruction updates | ||
| - Changelog entries | ||
| - Configuration / CI changes | ||
|
|
||
| ## Forbidden in commits | ||
|
|
||
| Never commit temporary planning or analysis files: | ||
| - `ARCHITECTURE_ANALYSIS.md`, `TASK_SUMMARY.md`, `TEST_PLAN.md`, `DOCUMENTATION_CHANGES.md` | ||
| - Any `.md` file created for understanding or planning (use `/tmp/` if you need scratch space) | ||
|
|
||
| ## Commit message format | ||
|
|
||
| ``` | ||
| <area>: <concise description of what changed and why> | ||
|
|
||
| Context: | ||
| - What triggered this change | ||
|
|
||
| Change: | ||
| - What was adjusted and why | ||
| ``` | ||
|
|
||
| Examples: | ||
| ``` | ||
| utils/time: fix duration parsing to respect timezone | ||
|
|
||
| Context: | ||
| - Bug #1234: PT2H parsed incorrectly in CET timezone | ||
|
|
||
| Change: | ||
| - Pass timezone through to isodate.parse_duration | ||
| ``` | ||
|
|
||
| ``` | ||
| agents/test-specialist: add full-suite requirement after governance failure | ||
|
|
||
| Context: | ||
| - Session 2026-02-10 revealed partial test execution as root cause | ||
|
|
||
| Change: | ||
| - Added explicit requirement to run complete test suite | ||
| ``` | ||
|
|
||
| Use the file path or area as the prefix (e.g. `api/v3_0`, `data/models`, `cli`, `docs`, `agents/<name>`). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| --- | ||
| applyTo: "**" | ||
| --- | ||
| # Changelog Entries | ||
|
|
||
| Each PR generally requires a changelog entry. | ||
|
|
||
| ## Changelogs | ||
|
|
||
| | File | Audience | | ||
| |------|----------| | ||
| | `documentation/changelog.rst` | Main changelog — API/CLI/UI users and plugin developers | | ||
| | `documentation/api/changelog.rst` | API-specific changes | | ||
| | `documentation/cli/changelog.rst` | CLI-specific changes | | ||
|
|
||
| ## Entry format | ||
|
|
||
| Always follow the formatting convention already present in the target changelog file — the style may evolve over time. The canonical guide is the file itself. | ||
|
|
||
| Current conventions: | ||
| - **Main changelog**: one sentence, no period at the end, written for end users (abstract away technical details when possible) | ||
| - **API and CLI changelogs**: slightly more technical audience; use a period at the end | ||
|
|
||
| Example for the main changelog: | ||
|
|
||
| ```rst | ||
| * Add cross-cutting Copilot instruction files to `.github/instructions/` [see `PR #XXXX <https://www.github.com/FlexMeasures/flexmeasures/pull/XXXX>`_] | ||
| ``` | ||
|
|
||
| Replace `XXXX` with the actual PR number. If the PR number is not yet known, alert the maintainer. | ||
|
|
||
| ## Sections in `documentation/changelog.rst` | ||
|
|
||
| Always use this order: | ||
|
|
||
| - **New features** — new capabilities visible to API/CLI/UI users | ||
| - **Infrastructure / Support** — changes targeting plugin developers and hosts | ||
| - **Bugfixes** — corrections to incorrect behavior | ||
|
|
||
| ## PR description checkbox | ||
|
|
||
| The PR template includes a changelog checkbox: | ||
|
|
||
| ```markdown | ||
| - [ ] Added changelog item in `documentation/changelog.rst` | ||
| ``` | ||
|
|
||
| Tick it once the changelog entry is committed. | ||
|
|
||
| ## What requires a changelog entry | ||
|
|
||
| Each PR generally requires an entry. Examples of what warrants one: | ||
|
|
||
| - New API endpoints or parameters | ||
| - Changed or removed API behavior | ||
| - New CLI commands or options | ||
| - UI feature additions or changes | ||
| - Performance improvements that affect users | ||
| - Breaking changes (always require a changelog entry, plus migration notes) | ||
| - Changes to plugin interfaces | ||
| - Significant changes to the repo's AI infrastructure | ||
|
|
||
| ## What does not require a changelog entry | ||
|
|
||
| - Internal refactoring with no user-visible effect | ||
| - Test-only changes | ||
| - Small agent instruction updates (typo fixes, minor wording changes) | ||
| - Pure documentation typo fixes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| --- | ||
| applyTo: "**/*.py" | ||
| --- | ||
| # Python Docstrings | ||
|
|
||
| All public functions, methods, and classes must have docstrings. Use RST (reStructuredText) format for Sphinx compatibility. | ||
|
|
||
| ## Standard function docstring | ||
|
|
||
| ```python | ||
| def function_name(param1: str, param2: int) -> bool: | ||
| """One-line summary ending with a period. | ||
|
|
||
| Longer description explaining purpose and usage when needed. | ||
| Parameter descriptions are aligned and separated from the colon | ||
| with at least one space. | ||
|
|
||
| :param param1: Description of param1. | ||
| :param param2: Description of param2. | ||
| :returns: Description of return value. | ||
| :raises ValueError: When param1 is empty. | ||
|
|
||
| Example:: | ||
|
|
||
| >>> function_name("test", 42) | ||
| True | ||
| """ | ||
| ``` | ||
|
|
||
| ## Key conventions | ||
|
|
||
| - One-line summary ends with a period and fits on one line. | ||
| - Leave one blank line between the summary and the extended description. | ||
| - Align `:param name:` descriptions using spaces (not tabs) for readability. | ||
| - Use `Example::` (double colon) to introduce a doctest block. | ||
| - Complement type hints — don't duplicate them in the docstring text. | ||
| - Use exactly one space after punctuation (no double spaces after periods). | ||
| - Use line breaks only after punctuation (this facilitates review commenting and text searching). This applies to in-line comments as well, not only docstrings; keep in-line comments short. So never wrap a docstring or comment in the middle of a phrase; each physical line must end at a comma, semicolon, colon, or period. (E501 is ignored and `max-line-length` is 160, so a long clause on one line is preferred over a mid-phrase break.) | ||
|
|
||
| ## For code review (incl. automated reviewers) | ||
|
|
||
| The line-break-after-punctuation rule above is a deliberate, load-bearing convention (stable review comments and text search), not a stylistic nicety. When reviewing a change, always report a docstring or comment that wraps mid-phrase as a review comment; do not treat such a finding as low-confidence, and do not omit or suppress it. | ||
|
|
||
| ## Click CLI commands | ||
|
|
||
| ```python | ||
| @click.command() | ||
| def my_command(): | ||
| """One-line summary of what the command does. | ||
|
|
||
| Longer description with usage context and examples if helpful. | ||
| """ | ||
| ``` | ||
|
|
||
| ## Doctests | ||
|
|
||
| Include doctests in docstrings for pure utility functions. Run them with: | ||
|
|
||
| ```bash | ||
| pytest --doctest-modules | ||
| ``` | ||
|
|
||
| Doctests in `documentation/` are also executed. Keep examples accurate and test them before committing. | ||
|
|
||
| ## Comments | ||
|
|
||
| Comments explain *why*, not *what*. Avoid redundant comments that just restate the code. Include issue numbers or external links in TODO comments when relevant. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| --- | ||
| applyTo: "**/*.py" | ||
| --- | ||
| # Error Handling | ||
|
|
||
| Catch specific exceptions, not bare `Exception`. Broad catches hide bugs and make debugging difficult. | ||
|
|
||
| ## What to catch and when | ||
|
|
||
| ```python | ||
| from sqlalchemy.exc import SQLAlchemyError | ||
|
|
||
| # ✅ Catch specific, expected failures | ||
| try: | ||
| obj = create_or_fetch(...) | ||
| except SQLAlchemyError as e: | ||
| db.session.rollback() | ||
| return error_response("Database error", 500) | ||
| except ValueError as e: | ||
| return error_response(str(e), 400) | ||
| # Let unexpected exceptions (AttributeError, TypeError, etc.) propagate | ||
| # — they indicate bugs that should fail loudly | ||
| ``` | ||
|
|
||
| ## Never do this | ||
|
|
||
| ```python | ||
| # ❌ Too broad: catches programming errors | ||
| try: | ||
| result = some_operation() | ||
| except Exception as e: | ||
| return error_response("Something went wrong") | ||
| ``` | ||
|
|
||
| ## Exception categories | ||
|
|
||
| | Exception type | When to catch | | ||
| |----------------|---------------| | ||
| | `SQLAlchemyError` | Database connection, integrity, or query errors | | ||
| | `ValueError` | Invalid input that was expected and validated | | ||
| | `KeyError` | Missing required data in a known structure | | ||
| | `AttributeError` | **Never** — indicates a bug in your code | | ||
| | `TypeError` | **Never** — indicates a bug in your code | | ||
| | `NameError` | **Never** — indicates a bug in your code | | ||
|
|
||
| ## Error messages | ||
|
|
||
| Good error messages state what went wrong, explain why, and suggest a fix: | ||
|
|
||
| ```python | ||
| raise ValueError( | ||
| f"Invalid sensor ID {sensor_id}. " | ||
| f"Sensor must belong to account {account.name}. " | ||
| f"See https://flexmeasures.readthedocs.io/..." | ||
| ) | ||
| ``` | ||
|
|
||
| ## HTTP status codes in API endpoints | ||
|
|
||
| - `400 Bad Request` — invalid client input (validation failure) | ||
| - `401 Unauthorized` — authentication required | ||
| - `403 Forbidden` — authenticated but not permitted | ||
| - `404 Not Found` — resource does not exist | ||
| - `500 Internal Server Error` — unexpected server-side failure | ||
|
|
||
| ## get-or-create idempotency | ||
|
|
||
| Never rely on `obj.id is None` to detect if an object is newly created (SQLAlchemy may not assign IDs until commit). Return an explicit boolean instead: | ||
|
|
||
| ```python | ||
| def get_or_create_thing(...): | ||
| existing = db.session.query(Thing).filter_by(...).first() | ||
| if existing: | ||
| return existing, False # (object, was_created) | ||
| new_obj = Thing(...) | ||
| db.session.add(new_obj) | ||
| return new_obj, True | ||
|
|
||
| thing, was_created = get_or_create_thing(...) | ||
| status_code = 201 if was_created else 200 | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| --- | ||
| applyTo: "**" | ||
| --- | ||
| # Feature Branch Synchronization | ||
|
|
||
| Feature branches must be kept synchronized with `origin/main` before implementing code changes. | ||
|
|
||
| ## Check branch status | ||
|
|
||
| Before starting implementation work, verify the branch is up to date: | ||
|
|
||
| ```bash | ||
| git log --oneline origin/main...HEAD --left-right | ||
| ``` | ||
|
|
||
| If you see < markers, origin/main has commits the branch lacks — a fresh merge is needed. | ||
|
|
||
| ```bash | ||
| # ❌ Don't just check git status (it only tells you about uncommitted changes) | ||
| git status # shows "nothing to commit" even if behind main | ||
|
|
||
| # ✅ Do check the commit graph | ||
| git log --left-right origin/main...HEAD | ||
| ``` | ||
|
|
||
| ## Merge before implementation | ||
|
|
||
| ```bash | ||
| git fetch origin | ||
| git merge origin/main | ||
| # Resolve any conflicts | ||
| git add . | ||
| git commit -m "Merge origin/main into feature branch" | ||
| ``` | ||
|
|
||
| This ensures your implementation starts from the latest state of the repository. | ||
|
|
||
| ## Why this matters | ||
|
|
||
| - Merging later causes merge conflicts to compound | ||
| - Large late merges are harder to review | ||
| - Feature work should build on current main, not diverge |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like these
.githubinstructions are copied from theflexmeasuresrepo. I think it would make sense to view these as being applicable to the FM server and all FM plugins (basically FlexMeasures organization-wide). I see 3 ways forward:flexmeasuresonly, and have plugins (including theflexmeasures-plugin-templaterepo) point to them in theirAGENTS.md. Not sure if agents will respect that.tsc(or a new dedicated) repo under the FlexMeasures organization. Same uncertainty as 1.flexmeasuresrepo).Do you want to try 1, which would be my preference? I'm afraid you happen to be the first plugin author to face this issue.