Skip to content

Commit 99065fa

Browse files
Merge remote-tracking branch 'origin/main' into fix/smart-control-off-planned-slots-5339
Conflicts resolved by keeping both sides: - config.py: APPS_SCHEMA lists both octopus_intelligent_smart_control (this PR) and octopus_intelligent_planned_slot (#5443). - fetch.py: keeps octopus_smart_control_off() and main's car_planned_slot_entity(). - octopus.py: imports take OCTOPUS_MANUAL_DISPATCH_SOURCES as well as main's REPEAT_FULL_LOG_SECONDS/RepeatLogGate. automatic_config() wires the Smart Control switch alongside the dispatch sensor, which the Octopus component still owns, while main's other_owner check (#5443) guards only the ready time and charge limit. - docs/apps-yaml.md, docs/car-charging.md: both new items documented. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 parents ca34471 + 9247831 commit 99065fa

83 files changed

Lines changed: 9098 additions & 864 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.claude/skills/issue-pr/SKILL.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ This skill assumes the issue has already been triaged — the daemon only invoke
1414

1515
## 1. Read the ticket
1616

17-
Fetch it with `gh issue view <number> --json title,body,labels,comments`. The bot's own triage comment (opens with "automated first-pass triage") already has the classification, priority, and any root-cause pointer — start from there rather than re-investigating from scratch.
17+
Fetch it with `gh issue view <number> --json title,body,labels,comments`. The bot's own triage comment (opens with "automated first-pass triage") already has the classification, priority, and any root-cause pointer — start from there rather than re-investigating from scratch. If it's labelled `bug` and the triage reached a full investigation, the comment also has a one-line statement of the fault right after the classification — use that as the precise claim to fix, not the reporter's (often vaguer) symptom description. If the issue carries any follow-up bot comments (opening with "automated follow-up triage review"), check the most recent one too — it may have restated, sharpened, or only just written that statement, and its version of the claim supersedes the first-pass one. A statement that a later bot comment retracted no longer counts.
18+
19+
A `bug` label can arrive without that statement: the split and evidence gates (`/issue-triage` steps 1a and 1b) apply a type label and stop before any investigation. If no bot comment has a bug statement or a root-cause pointer, the fault hasn't been verified yet — don't fall back to the reporter's title or symptoms. Go to step 8 and say the issue needs a full triage (the follow-up review that the reporter's reply triggers) before a fix can be attempted.
1820

1921
## 2. Investigate
2022

‎.claude/skills/issue-triage-followup/SKILL.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,18 @@ Compare your updated understanding against the original triage comment's classif
5050
- If the classification, priority, or root-cause should change given the new information, update it. You may change or remove a label **you previously applied as the bot** (classification, priority, `waiting_for_user`) — never remove a label a human added.
5151
- Apply the same duplicate check as `/issue-triage` step 4 if the new information suggests one.
5252

53+
If the bot's most recent prior comment (the one you found in step 1) carries a one-line bug statement (`/issue-triage` step 3), that statement is a standing claim and this review must settle it rather than silently carry it forward or drop it — including when nothing material changed, one of:
54+
55+
- **Still a bug** — restate the one-line statement in this comment, unchanged if the new evidence doesn't bear on it, updated if it sharpens or changes what the fault actually is.
56+
- **Not a bug after all** — say so plainly, retract the statement, and give the corrected classification. This is the expected outcome when, as happened on #5390, a maintainer's own reply shows the reported behaviour is Predbat doing what the config says.
57+
58+
If this review concludes the issue is a bug and there is no live statement to restate — the bot's most recent prior comment has none, or retracted one — write the one-line statement now, to the same standard as `/issue-triage` step 3. That covers this review changing the classification **to** `bug` (for the first time, or back to `bug` after an earlier follow-up retracted the statement), and this review confirming a `bug` label that an early-exit gate (`/issue-triage` step 1a or 1b) applied without investigating — those gates stop before step 3, so the first full investigation after one is where the statement gets written, even though the label is already there. A statement in an older comment that a later one retracted is not live, so it never stands in for a new one.
59+
5360
## 5. Post one follow-up comment
5461

5562
Check the comment history first: if the most recent comment is already a bot comment with nothing from a human posted after it, stop — this review already happened and nothing new has arrived since.
5663

57-
Post exactly one comment via `gh issue comment <number> --body "..."`, opening with a line disclosing this is an automated follow-up triage review (a maintainer will review before any action is taken), followed by: what was new since the last review, whether the classification/priority/root-cause changed and why (or confirmation nothing changed), and any further information request.
64+
Post exactly one comment via `gh issue comment <number> --body "..."`, opening with a line disclosing this is an automated follow-up triage review (a maintainer will review before any action is taken), followed by: what was new since the last review, whether the classification/priority/root-cause changed and why (or confirmation nothing changed), the one-line bug statement from step 4 whenever one is restated, newly written, or retracted there — restated as-is if the new evidence didn't bear on it — and any further information request.
5865

5966
Do **not** touch the `BOT_TRIAGED` or `BOT_REVIEW` labels — the daemon manages both.
6067

‎.claude/skills/issue-triage/SKILL.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,13 @@ A `predbat_debug.yaml` can also be replayed against current main to reproduce th
7373

7474
Apply exactly one of: `bug`, `question`, `configuration` (user error/misconfiguration), `enhancement` (feature request). If genuinely ambiguous, apply `unclear` instead of guessing.
7575

76+
If you classify as `bug`, write a one-line statement of the bug in your own words — what Predbat actually does wrong, not the reporter's symptom description. State the faulty behaviour and, if you have one, the mechanism, e.g. "The dispatch-cancel check re-reads the car's live status instead of the status at cancel time, so a car that resumes charging a second later still loses its slot." A restatement of the title ("battery charging not working") is not acceptable. This line carries into step 9.
77+
7678
## 4. Check for duplicates
7779

7880
Search existing issues (`gh issue list --search ...`, both open and closed) for the same symptom.
7981

80-
- High confidence match: label `duplicate`, comment linking the original issue, and close this one.
82+
- High confidence match: label `duplicate`, comment linking the original issue (including the step 3 one-line bug statement, if you wrote one), and close this one.
8183
- Low confidence: mention "possibly related to #N" in your triage comment; don't close.
8284

8385
Then look for **similar** issues and PRs as well, whether or not they are duplicates: search both open and closed ones for the symptom, the integration and the component it touches (`gh issue list --state all --search ...` and `gh pr list --state all --search ...`). Read the findings in the best matches — what was diagnosed, what was fixed, and what was ruled out — before forming a hypothesis, and link the relevant ones in your triage comment as "related to #N". An issue that shares a symptom or a trigger is not necessarily the same problem: only call it a duplicate when the cause matches, not just the symptom, and treat a past finding as a lead to confirm against current main, not as a conclusion.
@@ -106,6 +108,7 @@ Then look for **similar** issues and PRs as well, whether or not they are duplic
106108

107109
- Form a root-cause hypothesis with a `file:line` pointer if the investigation supports one. It's fine to say the cause needs maintainer review if it doesn't.
108110
- You may edit files locally to test a hypothesis (e.g. a temporary debug print, a tweaked test fixture) — this clone is hard-reset and cleaned before the next run, so nothing here persists. Never `git commit` or `git push`.
111+
- If this investigation changes your mind about step 3's classification — e.g. you classified `bug` but the investigation shows Predbat is doing what the config says — go back and revise it, and drop or rewrite the one-line bug statement to match. Don't let step 9 post a statement step 3 wrote before you knew better.
109112

110113
## 6. Apply component labels
111114

@@ -131,6 +134,8 @@ Check existing comments first — if one from you is already there, stop; don't
131134

132135
Post exactly one comment via `gh issue comment <number> --body "..."`, opening with a line disclosing this is an automated first-pass triage (a maintainer will review before any action is taken), followed by: classification, priority (if set), what you investigated and found (including test result if you ran one), a root-cause pointer if you have one, and any information request.
133136

137+
If you reached step 3 and classified as `bug`, lead with the one-line bug statement immediately after the classification. Gates 1a/1b apply a type label without ever reaching step 3, so there's nothing to include if you took one of those paths.
138+
134139
After posting, apply the `BOT_TRIAGED` label via `gh issue edit <number> --add-label BOT_TRIAGED` — every triage run gets this label, including a duplicate-close, regardless of classification. It marks the issue as triaged for the separate PR-creation flow (see `.claude/skills/issue-pr/SKILL.md`).
135140

136141
## Guardrails

‎.cspell/custom-dictionary-workspace.txt‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ denorm
145145
derate
146146
derated
147147
derating
148+
dess
148149
desync
149150
desynced
150151
devcontainer
@@ -170,6 +171,7 @@ dtype
170171
dwindow
171172
eauth
172173
echargingpile
174+
ECONNRESET
173175
ecosmart
174176
Eddi
175177
eddis
@@ -195,6 +197,7 @@ energythroughput
195197
enho
196198
Enlighten
197199
enlm
200+
ENOTFOUND
198201
enph
199202
enphase
200203
enphaseenergy
@@ -204,6 +207,7 @@ epod
204207
epvtoday
205208
errno
206209
ESSAPI
210+
ETIMEDOUT
207211
etoday
208212
etok
209213
euids
@@ -253,6 +257,7 @@ getall
253257
getattr
254258
getrusage
255259
Ginlong
260+
githubusercontent
256261
gitnexus
257262
giv
258263
GivEnergy
@@ -347,6 +352,7 @@ labelcolor
347352
labelledby
348353
labelnames
349354
ladybugdb
355+
Lanmate
350356
larr
351357
libbi
352358
libc
@@ -471,6 +477,7 @@ overfitting
471477
oversizing
472478
overvoltage
473479
ownerapi
480+
pac
474481
parseable
475482
pbat
476483
pbgw
@@ -530,6 +537,7 @@ pyproject
530537
pytest
531538
pythonhashseed
532539
pytz
540+
Quattro
533541
Qwen
534542
randn
535543
rany2
@@ -626,6 +634,7 @@ startswith
626634
startt
627635
stdlib
628636
stepline
637+
stevekirtley
629638
Storion
630639
Stromligning
631640
strptime

‎apps/predbat/annual.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,12 @@ def reset_sample_state(predbat):
788788
predbat.rate_min = 0
789789
predbat.rate_max = 0
790790
predbat.rate_average = 0
791+
# set_rate_thresholds() reads these alongside the rates. _apply_rates() clears them too, since
792+
# _run_scenarios() installs a second tariff without coming back through here.
793+
predbat.rate_import_saving_minutes = set()
794+
predbat.rate_export_saving_minutes = set()
795+
predbat.rate_import_pre_saving = {}
796+
predbat.rate_export_pre_saving = {}
791797

792798
predbat.load_inday_adjustment = 1.0
793799
predbat.load_scaling_dynamic = None
@@ -1188,6 +1194,13 @@ def _apply_rates(predbat, rate_import, rate_export):
11881194
predbat.rate_export = rate_export
11891195
predbat.rate_low_threshold = 0
11901196
predbat.rate_high_threshold = 0
1197+
# A prior live cycle's saving-session minutes are absolute offsets into that cycle's own rate
1198+
# tables - stale and meaningless against this simulated tariff, and set_rate_thresholds() would
1199+
# otherwise exclude whatever unrelated minutes happen to sit at the same positions here.
1200+
predbat.rate_import_saving_minutes = set()
1201+
predbat.rate_export_saving_minutes = set()
1202+
predbat.rate_import_pre_saving = {}
1203+
predbat.rate_export_pre_saving = {}
11911204

11921205
if predbat.rate_import:
11931206
predbat.rate_scan(predbat.rate_import, print=False)

0 commit comments

Comments
 (0)