Releases: zany92/tesla-loadpilot
Release list
v1.4.0 - Law ceiling capped on the measured TWC3 reaction curve
What changed
law_emax_default moves from 1.0 A to 0.9 A, and law_gain_default from 0.75 back to 0.5.
Why the ceiling moved
PVi1 published a measured reaction curve of the TWC3 to fixed, stepped reported values on firmware 26.26.1:
| Excess above L | Measured wallbox reaction |
|---|---|
| +0.9 A | gentle reduction over tens of seconds |
| +1.0 A | reduction after ~20 s, inconsistent under dynamic load |
| +1.1 A | rapid reduction, full stop in about 3 s |
That curve independently corroborates the dead-band hysteresis measured on my own pilot, where the wallbox only engages at about L+0.85 from rest. Two separate instrumentations, the same threshold.
The published value carries a permanent +/-0.05 A dither, so a ceiling of 1.0 let the law peak at L+1.05: inside the inconsistent band, and 0.05 A away from the band that stops the charge outright. At 0.9 the peak is L+0.95, which still breaks the dead band while keeping 0.15 A of margin below the stop threshold.
The ceiling now deliberately equals escalation_kick_a, so the continuous law and the stage-2 anti-hysteresis kick target the same measured point. Stage 2 still bypasses the clamp by design, so its authority is unchanged.
Why the gain moved back
Both 0.5 and 0.75 are field validated, but 0.75 was measured pumping the regulation, 6 to 13 A swings, on a pilot whose house load was near constant: the loop was chasing its own echo. 0.5 holds the same equilibrium without pumping, and still sits on the measured distrust floor, which must never be crossed downward.
Upgrading
Both values are runtime knobs (Law Max Excursion, Law Echo Gain), so an existing install can adopt the change immediately without reflashing. Note that both carry restore_value: false by design: the law always boots on its shipped default, so a reflash is what makes the new values survive a reboot.
The pure test mirror and the 80 golden cases are updated and pass. The goldens pin their parameters explicitly, so traces recorded on the earlier defaults remain valid.
Credit to PVi1 for the measurement that motivated this.
Tesla LoadPilot 1.3.1
Tooling and consistency release.
- CI now validates the ESPHome schema of all four reference configs and
really compiles three of them (three-phase charger, single-phase
charger, single-phase meter) with a warm platformio cache. The
packet_transport duplicated-sensor question of the single-phase
provider is settled: it compiles and links. - Golden law tests: a pure Python mirror of the publication law (both
variants, escalations, dither, glitch firewall, fail-safe) replayed
against seven segments of the real 17-18 Aug traces. 80 pytest cases
run on every push; mutating a measured constant breaks the locks. - The shipped default echo gain moves to 0.75 (PVi1's value, bench
vindicated in 1.2.0); golden replays explicitly pin the 0.5-era
constants of the recorded traces. - Docs: spike-damper and episode-grouped announcement patterns, RS485
field note, validated firmwares 26.18 + 26.26.1.
Tesla LoadPilot 1.3.0
Tesla LoadPilot 1.3.0
The integration learns the control patterns that were prototyped and
field-validated on the pilot site. Everything is strictly opt-in: an
existing entry keeps byte-identical behavior until you enable a feature.
Charge cap (number.loadpilot_charge_cap)
A user-set ceiling in amps (0 = automatic). The coordinator runs a 10 s
control tick that steers the node's bias channel: target = worst-phase
headroom + vehicle current - cap, raised immediately, released at most
0.5 A per tick (the asymmetry that killed the 11-16 A limit cycle), with
an anti-hysteresis kick when the vehicle idles above the cap while the
published value sits in the dead band. Field-validated on the pilot
(13 A target held at 13.2 A steady). Requires mapping a vehicle-current
entity (new field in advanced mapping); without it the number stays
unavailable and nothing runs.
Automatic budget trim (option, default off)
When the cap is 0, an IDLE / ARMED / KICKING / COOLDOWN state machine
detects the parked-above-budget condition (negative headroom held 3 min,
published in the dead band, bias at 0) and applies a transient 2 A kick,
releasing it only if the bias is still its own. Layered under the
firmware stage-2 escalation of core 1.2.0: the integration acts at
3 min, the firmware backstops at 4 min with no Home Assistant needed.
Law settings enforcement (options, default off)
Optional gain / max-excursion (and site-mapped drag) values that the
integration re-applies when the node reboots or comes back: this closes
the real gap where a reflash silently resets the law numbers to their
initial values (lived on the pilot: the tail fell back to 0 after a
flash). A Repair is raised if an enforced knob has no resolvable target
entity. Note: the generic core ships law variant A; the decaying-tail
knob is a site-specific override with no generic default.
Meter distrust detector (binary_sensor.loadpilot_meter_distrust)
A PROBLEM binary sensor plus a pedagogical Repair when the published
value stays in the pull zone for 120 s while the vehicle keeps drawing:
the signature of the charger silently distrusting the meter (BEHAVIOR
section 4). Thresholds derive from the new max-conductor option.
Disabled without a vehicle-current mapping (a published-only variant is
structurally false-positive prone; the 17 Aug false alert is now a
regression test).
Engineering
The decision logic lives in a pure module (control.py, injected clock,
no Home Assistant imports) covered by 36 pytest cases anchored on the
real traces of 17-18 Aug, and the CI now runs them on every push.
Tesla LoadPilot 1.2.0
Firmware core: stage-2 escalation (anti-hysteresis kick).
After four minutes of sustained constraint the charger-side node now
publishes at least L + 0.9 A (substitution escalation_kick_a), breaking
the dead-band hysteresis documented in BEHAVIOR section 12. The pilot
then follows the published value down to L, which is the exact budget
equilibrium, and the episode leaves the constraint (one kick per
episode). Budget convergence no longer depends on Home Assistant.
Also raised the recommended echo gain to 0.75 (PVi1's original value,
quantitatively vindicated on the pilot bench: the engagement gap
shrinks from about 1.7 A to 1.1 A; the measured distrust floor remains
around 0.5, never go below it).
Deployed and flashed on the pilot site on 18 Aug 2026. Integration code
unchanged.
Tesla LoadPilot 1.1.1
Tesla LoadPilot 1.1.1
Documentation and field-data release. No code change in the integration
or the firmware packages; the version bump ships the knowledge gained
on the pilot site on 18 Aug 2026.
Firmware 26.26.1 revalidated
Tesla started rolling out wall connector firmware 26.26.1 overnight.
The pilot site updated under supervision and revalidated the whole
behavior model in a real charge session: the commissioned emulated
meter survives the update, and every measured behavior (echo
correlation, dead band, pull, pause, autonomous resume) is identical
to 26.18, including a real 115 percent house-spike stress test with a
clean floor stop and resume. Details and raw traces: BEHAVIOR section
12 and data/traces/ (both languages).
Behavior model refined: the dead band is a hysteresis
From rest the pilot engages at about L + 0.85 published; once pulling
it follows down to published = L and holds there. Consequence for any
external bias controller: raise fast, release slowly, kick through the
threshold when the vehicle idles above target. Documented in BEHAVIOR
(EN and FR) and applied to the manual-limit pattern in the roadmap.
Manual cap pattern field-tuned
The 13 A manual cap was exercised on a live charge: a fast symmetric
loop produced an 11-16 A limit cycle; the shipped pattern (immediate
raise, 0.5 A per 10 s decay, anti-hysteresis kick, 5 s local vitals
source) held 13.2 A steady. TESTPLAN record A16.
New runbook signature
"charging failed" right after a pause with a calm house: a pause bias
posted while no charge is running can survive every release path and
silently block session starts. Signature, remedy and the permanent
"empty pause" exemption deployed on the pilot are documented in
RUNBOOK_INCIDENTS (EN and FR).
Tesla LoadPilot 1.1.0
Tesla LoadPilot 1.1.0
Changes since 1.0.1. One SemVer tag still covers the whole repository:
the HACS integration and the ESPHome firmware packages ship in lockstep.
Theme: single-phase support, end to end and clearly labelled
THEORETICAL (meter provider, examples, preset, services, dashboards,
documentation), plus fully bilingual documentation.
Nothing changes for existing three-phase installations. The charger-node
firmware is unchanged character for character: esphome/packages/twc-core.yaml,
esphome/packages/providers/teleinfo-fr.yaml, the board packs and the
three-phase examples have a null git diff against 1.0.1, so the pilot-site
binaries need no reflash. The UDP measurement contract (port 18511, the six
lky_* broadcast ids) is untouched. The only behaviour change in the whole
release is the loadpilot.pause ceiling described below, and it only
affects single-phase entries.
Single-phase support (THEORETICAL - never bench-validated)
Scope: European 230 V single-phase, one logical CT. US split-phase (240 V,
two CTs) is a third topology and remains out of scope.
The packages already sketched single-phase (phase_count: "1" substitution
in the core, phase choice in the config flow, L1-only mirror). What was
missing to make it usable ships in this release:
- Single-phase TIC provider
esphome/packages/providers/teleinfo-fr-mono.yaml(new file; the
three-phase provider is byte-identical). A single-phase Linky never emits
the indexed labels the three-phase provider reads (SINSTS1/2/3), so with
the old provider the UDP feed would never become fresh and the charger
node would sit in fail-safe forever. The single-phase provider reads
SINSTS(no index) plusURMS1and computes sub-amp current as
SINSTS/URMS1; phases B/C are published at 0, slaved to the TIC
watchdog (0 only while phase A is alive, NAN on all six quantities on
failure). Constant zeros independent of phase A's health would keep the
feed judged fresh forever with a dead TIC - the exact resurrection of QA
pitfall M3.CONTRACTS.mdsection 2 is clarified accordingly (a
clarification of the existing rule, not an ABI change). - Single-phase meter example
esphome/examples/meter-teleinfo-mono-olimex-poe.yaml(same Olimex
board as the three-phase reference), and a completed charger example
charger-mono-exemple.yaml:bias_max_a: "32", an electrically
coherent 45 A service breaker for the 9 kVA example, pointers to the
single-phase provider and to the commissioning ladder (shadow mode
first, RAW as short as possible). - 3 kVA preset (
mono_3, 15 A) in the config flow: the single-phase
series now covers the full Enedis catalogue, 3/6/9/12/15/18/24 kVA.
Three-phase presets are unchanged value by value. - Bias up to 32 A on single-phase entries: a single-phase TWC Gen 3
draws up to 32 A on its one phase, and a full pause requires a bias at
least equal to the vehicle current.loadpilot.set_biasnow accepts up
to 32 A on a single-phase entry and still refuses anything above 16 A on
a three-phase one (the value is validated against every targeted entry
before being written to any). At the fixed firmware ramp, a full 32 A
pause takes about 160 s; theCharge Stopswitch remains the immediate
lever. - Single-phase dashboards:
dashboards/loadpilot-overview-mono.yaml
anddashboards/loadpilot_card-mono.yaml(L2/L3 rows removed). - Documentation: single-phase annexes in
docs/en/BEHAVIOR.md
section 11 anddocs/fr/40_LOI_DE_COMMANDE.mdsection 11 (what is
structurally invariant versus which numbers are three-phase calibration
NOT transferred), single-phase commissioning inserts in both INSTALL
guides, a single-phase provider row in
docs/fr/15_FOURNISSEURS_MESURE.md, and "Single-phase or three-phase"
configuration paragraphs in both READMEs.
Why "theoretical": no single-phase bench was available at design time.
The control-law constants (dead band, ~20 A.s cut integral, latencies,
slopes, vehicle minimum) are three-phase measurements, and the set of CT
registers a wallbox commissioned single-phase actually reads is unknown.
The bench campaign is declared OPEN as TESTPLAN cases C14-C20
(CT registers read, ct_total acceptance, control-law constants, 32 A
plausibility scale, real single-phase TIC, 32 A bias pause, fail-safe and
Meter Absent). Single-phase support stays theoretical until that campaign
runs; do not trust it on a real installation before then.
Fixed: loadpilot.pause used a hard-coded 16 A ceiling
loadpilot.pause now writes the per-installation bias ceiling (16 A
three-phase, 32 A single-phase) instead of a hard-coded 16 A. On a 32 A
single-phase charge, a 16 A bias would only have slowed the vehicle down,
never paused it. This is the only behaviour change of the release and it
only affects single-phase entries: on a three-phase entry the service
writes 16 A exactly as before.
Documentation is now fully bilingual
INSTALLandTESTPLANtranslated into English (docs/en/).BEHAVIORandRUNBOOK_INCIDENTStranslated into French (docs/fr/).- Cross-links are wired language to language: English pages link
docs/en/,
French pages linkdocs/fr/.
Upgrade notes
- No config-flow migration: existing entries reload as they are. The only
visible difference on a three-phase entry is one more option (mono_3)
in the preset dropdown. - Charger-node firmware: byte-identical, no reflash needed, no new
required substitution (phase_countstill defaults to"3"). - The
set_biasservice selector now shows 0-32 A; three-phase entries
still reject anything above 16 A at call time.
This project is not affiliated with, endorsed by, or sponsored by
Tesla, Inc.
Tesla LoadPilot 1.0.1
Packaging release for the HACS default-store submission.
- Brand icons now shipped inside the integration (custom_components/loadpilot/brand/), per the Home Assistant 2026.3 mechanism.
- LICENSE is now the pure MIT text so GitHub and HACS detect the SPDX id; the PVi1/Klangen82 attribution moved to NOTICE.md.
- README (EN and FR): step-by-step Installation section, variant B closed-loop verdict, MIT lineage.
- CI: HACS validation and hassfest both green with no ignored checks.
Functional behavior is unchanged from 1.0.0.
Tesla LoadPilot 1.0.0
Tesla LoadPilot 1.0.0
First tagged release. One SemVer tag covers the whole repository: the HACS
integration and the ESPHome firmware packages ship in lockstep and both
report version 1.0.0.
Tesla LoadPilot is local, cloud-free charging power regulation for the
Tesla Wall Connector Gen 3: an ESP32 emulates the discontinued Neurio meter
on the wallbox's RS485 bus and feeds it real per-phase measurements taken at
the utility meter, so the wallbox's own load management modulates the
vehicle without ever tripping.
Status: first public release. Validated on a single pilot site (France,
three-phase 15 kVA, Linky meter, TWC firmware 26.18). The repository is
private; nothing is published to HACS or home-assistant/brands yet.
Firmware (ESPHome packages)
- Co-variant worst-phase law (v2): the published signal always echoes
real load variations, even in constraint, via bounded compression above
the Max Conductor Limit (knobsLaw Echo Gain0.5,Law Max Excursion
1.0 A). This removes the "frozen published value" failure mode that
latched the wallbox's distrust state. Validated in closed loop on the
pilot site on 17 Aug 2026 (load steps absorbed, autonomous session
recovery, zero contactor events). Design:docs/fr/DESIGN_LOI_COVARIANTE.md. - Variant B (release drag): the asymmetric-release design that removes
the exit yo-yo is fully specified with an inert-by-default kill switch
(drag depth 0 restores the exact v2 law). It is delivered as design only
in this release and is not part of the generic firmware packages. Design:
docs/fr/DESIGN_VARIANTE_B.md. - TIC watchdog (meter provider): without it, a dead TIC hat on a live
ESP32 rebroadcasts frozen values forever and no fallback engages (proven
by ESPHome source reading, QA finding M3). The watchdog (tic_timeout_ms,
default 15 s) invalidates the six broadcast quantities to NAN, which
cascades to fail-safe on the charger node. - Anti-glitch plausibility firewall: measurement input filter on the
charger node. R1: physical floor with the contactor closed (a service
meter can never read below the wallbox's own draw). R2: sudden drops
above 5 A must be confirmed by a second sample. Rises always pass
immediately (the transient error is on the safe side). Design:
docs/fr/DESIGN_ANTI_GLITCH.md. - Direct STOP: the
Charge Stopswitch immediately publishes the stop
order (limit plus nudge, dithered). Never restored at boot: a deliberate
stop cannot silently survive a reboot. - Meter-absent test switch:
Meter Absent (test)silences the Modbus
server at runtime (hot slave-address change) to exercise the wallbox's
documented "loss of meter" 6 A fallback. Shipped OFF, never restored at
boot. Design:docs/fr/DESIGN_METER_ABSENT.md. - Escalation stop (120 s at zero headroom publishes limit + 0.1 A,
dithered), bias target with firmware-side ramp, fail-safe publication of
the main breaker value with source priority UDP > HA mirror > fail-safe,
all carried over from the production-validated reference block.
Integration (custom_components/loadpilot)
- Config flow, 5 steps: meter profile, node names (existence checked),
electrical parameters (installation type, France kVA presets, contract
limit, buffer, withbudget_too_smallandtri_limit_suspicious
validations), HA mirror mapping, confirmation summary. Options flow for
later adjustments. - Entity mapping layer:
entity_overrides(opt-in "advanced mapping"
options step) remaps any tracked charger-node entity to an arbitrary
entity_id; fail-safe detection depends only on the six essential
measurements. - 5 derived sensors: regulation state (enum), per-phase headroom (3),
worst phase. Contractual entity ids pinned in English
(sensor.loadpilot_state,sensor.loadpilot_headroom_l1/l2/l3,
sensor.loadpilot_worst_phase). - 3 services:
loadpilot.set_bias,loadpilot.pause,
loadpilot.resume. - Repairs: firmware/integration version skew, fail-safe source active,
charger node missing from the entity registry. - Diagnostics export for support bundles.
- Full EN/FR translations (identical key trees).
Known limitations
- Entity ids on translated instances: recent Home Assistant releases
(observed on 2026.8) ignoresuggested_object_id, so the derived sensors
can be created with translated object ids on a non-English instance (for
examplesensor.loadpilot_etatinstead ofsensor.loadpilot_state).
Workaround: rename the five entities to the contractual ids listed above
(Settings > Devices and services > Entities). The dashboards and docs
assume the English ids. - Pilot node requires mapping: the pilot site's charger node predates
the generic package naming, so the advanced entity mapping step is
required there. Fresh installs that followtwc-core.yamlnaming do not
need it. - Variant B is not closed-loop tested: design only, see above. The exit
yo-yo of the v2 law is a known, bounded behaviour until then. - Distrust layer is partially inferred: the wallbox's latched distrust
state is characterised from field episodes and community corroboration,
with statements labelled MEASURED / INFERRED / REPORTED in
docs/en/BEHAVIOR.mdsection 4. Expect refinements at the next episode. - Physical fault-injection tests remain: the TIC watchdog was proven by
source reading; the physical unplug test (TESTPLAN case C6, QA finding
M3) and the meter-absent 6 A fallback test have not been run yet. - Calibration is tied to TWC firmware 26.18: a wallbox firmware update
requires re-calibration of the measured law.
Documentation
docs/en/BEHAVIOR.md: the measured behaviour model of the TWC Gen 3 load
management (English), including the distrust state (section 4).docs/en/RUNBOOK_INCIDENTS.md: operator runbook for incidents.docs/fr/TESTPLAN.md: acceptance and fault-injection test plan.docs/fr/INSTALL.md: step-by-step installation guide (French).
Credits and license
Founding prior art: PVi1/esphome-twc-control
(Neurio emulation concept, Modbus register structure, escalation stop
technique). Licensing conversation in progress; nothing derived is
published. Neurio identity block constants from LucaTNT's register-map
gist. No license is granted yet (see LICENSE.placeholder); all rights
reserved until the attribution agreement is settled.
This project is not affiliated with, endorsed by, or sponsored by
Tesla, Inc.