Migrate vehicle driver to Polestar C3 gRPC backend (v3.0.0)#8
Open
kaohlive wants to merge 69 commits intoCoderaxx:masterfrom
Open
Migrate vehicle driver to Polestar C3 gRPC backend (v3.0.0)#8kaohlive wants to merge 69 commits intoCoderaxx:masterfrom
kaohlive wants to merge 69 commits intoCoderaxx:masterfrom
Conversation
Changelog: Added support for charge speed details
Changelog: Changed polestar vehicle to new device class car
Changelog: Fix for trigger events
Changelog: hotfix on the csv driver
Changelog: Improved insights on power measurements
Changelog: update to fix api changes
Changelog: Update npm modules
Changelog: Widget, service warning and login bug fix
Changelog: preview images
Changelog: fix widget update on device state change
Changelog: stability improvement
Changelog: service warning improvement
Changelog: Another login fix
Changelog: Fine tune the login error message
Changelog: Added support for new ev charging states
Changelog: Fixed CSV receiver driver
Changelog: Added upgrade path for existing cars for homey energy
Changelog: More rebost energy upgrade detection
Changelog: Changed api, no linger supports images
Changelog: Changed api, no linger supports images
Changelog: Added support to switch to miles
Changelog: Rounding and stability improvements
Replace the legacy @andysmithfal/polestar.js GraphQL path with a purpose-built C3 client (clone_modules/polestar-c3/) that talks raw HTTP/2 gRPC against the same backend the Polestar mobile app uses. This unlocks fields the public GraphQL stopped returning (power, current, voltage, charge type) and brings new telemetry (tyre pressures, lifetime driving consumption, per-session charge kWh). Restored capabilities: measure_current, measure_power, meter_power (the last one now accumulates cleanly during CHARGING instead of being overwritten by unrelated driving-consumption values). New capabilities: measure_voltage, measure_polestarChargingType, measure_polestarDrivingKwh, measure_polestarSessionKwh, alarm_polestarTyrePressure, measure_polestarTyrePressureFL/FR/RL/RR. The new client is zero-native-deps (Node's built-in http2 + a minimal protobuf varint codec) so it drops straight onto Homey Pro. A c3_backend_disabled setting falls back to the legacy client as a rollback lever for any account where C3 misbehaves. Bumps to 2.8.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wire the C3 chronos services (ChargeNow, TargetSoc, AmpLimit) through the
JS client so users can actually control their car from Homey, not just
read status. Adds flow action + condition cards and in-tile sliders for
charge limit and amp limit plus momentary Start/Stop charging buttons.
Device setting "Allow remote commands" is a master-switch kill-flag —
writes fail instantly when turned off. Replaces an earlier PIN prototype
that produced ugly titleFormatted strings.
Device setting "Charge limit slot" (Daily/LongTrip/Custom/Unspecified)
is exposed because Polestar 4 silently rejects writes to the Daily slot
but commits to Custom — and we don't yet know which slot other models
prefer. Default stays on Daily to match the Python reference; Polestar 4
users switch once. Writes that don't land surface a log warning pointing
at this setting.
gRPC reliability: HTTP/2 keep-alive ping every 30 s, goaway-event handler
that nulls the session eagerly, and one automatic retry on transient
errors (INTERNAL/UNAVAILABLE/GOAWAY/ECONNRESET/ETIMEDOUT) with a fresh
session. Resolves the cold-session GOAWAY hit we saw on the first write
after idle.
UNIMPLEMENTED responses are now captured in a persistent device-store
flag so unsupported features (e.g. Polestar 4 returns "Functionality not
supported: AMP_LIMIT") hide the slider tile and skip further calls on
subsequent runs instead of spamming the log forever.
Charge limit polling moved to the fast 60 s cycle (down from 15 min) so
changes made in the Polestar app or in-car menu show up within a minute.
Amp limit stays on the slow 15 min cycle — it rarely changes and is
skipped entirely on vehicles that don't support it.
Set-response parsing no longer trusts the echoed level: the P4 chronos
envelope returns a stale value, so we rely on a delayed Get 3 s after
the write to reflect the committed state. The slider stays on the
user-chosen value until that re-read either confirms or corrects it,
avoiding the disorienting snap-back-then-forward UX.
The custom measure_polestarTyrePressure{FL,FR,RL,RR} capabilities are
also migrated to measure_pressure.{front_left,front_right,rear_left,
rear_right} with a kPa unit override — the standard capability gets
better UI + Insights integration. Legacy JSON files remain with a
_deprecated marker so existing devices can migrate via removeCapability;
they will be deleted in a future release.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wire two more C3 services so the car's external closures and parking
climatization show up as Homey tiles:
ExteriorService/GetLatestExterior — locks, per-door/window open state,
hood, tailgate, sunroof, charging-port cover
ParkingClimatizationService/GetLatestParkingClimatization — running
state, target temperature, interior temperature, minutes remaining
Both are unary calls on the 60 s fast cycle so a user walking up to the
car sees door-opened alarms within the minute.
Homey capabilities chosen so they can be switched to setable later
without a rename, once lock/unlock + climate start/stop writes land:
locked — central lock state (setable:false for now)
onoff.climate — climatization running/not (setable:false)
target_temperature — last requested temp (setable:false)
measure_temperature — interior temperature (inherently read-only)
measure_polestarClimateRemaining — minutes left on the 30-min parking
climatization session; blank when idle
alarm_contact.door_{fl,fr,rl,rr} — per-door open alarms
alarm_contact.window_any — aggregate window-open alarm
alarm_contact.{tailgate,hood,sunroof,tank_lid} — body + charge port
open alarms
The capabilitiesOptions setable:false overrides keep the tiles visible
as read-only indicators. When writes arrive they just drop the override
and register listeners.
DigitalTwin flat-field format was reverse-engineered against a live
Polestar 4 session: exterior fields 2-16 hold ints (LockStatus enum on
2/16, OpenStatus 1/2/3 on all others), climate fields 2,3,7,8 are the
ones we trust (running_status, time_remaining in minutes, current and
requested temperature as float32). ventilation_only and request_type
are still speculative per-model so they stay in debug logs only.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Complete the invocation surface so every write Polestar's mobile app
offers is available from Homey flows and device tiles, plus a couple
of reads that round out the picture.
Writes (via /invocation.InvocationService):
lock / unlock — wired to the setable `locked` tile
unlock_trunk — tile button + flow action
honk_flash — tile button (flash-only default) +
flow action with HONK/FLASH/BOTH
climate_start / climate_stop — onoff.climate toggle reads seat and
steering-wheel heating defaults from
new device settings; a separate flow
action exposes all 6 params per-call
for one-off custom sessions
windows_open / windows_close — flow actions (OPEN_ALL / CLOSE_ALL —
the API doesn't support per-window)
Reads:
Location (/dtlinternet.DtlInternetService/GetLastKnownLocation) —
parser handles three documented response layouts, populates a
measure_polestarLocation string tile on the 15-min slow cycle.
A get_location flow action refreshes on-demand and exposes
latitude, longitude, and a formatted "lat, lng" string as tokens
for downstream cards (push notifications with a map link).
OTA (/ota_mobcache.OtaDiscoveryService/GetSoftwareInfo) —
alarm_polestarOtaAvailable fires on DOWNLOAD_READY /
DOWNLOAD_COMPLETED / INSTALLATION_DEFERRED / INSTALLATION_SCHEDULED.
State text falls back to a friendly "No pending update" when the
car returns an empty CarSoftwareInfo (no update queued).
Write side (schedule/install/cancel) deliberately omitted — the
risk of a misconfigured flow triggering an install mid-drive
outweighs the convenience over the Polestar app.
Flow cards:
11 action cards (charge ±, limits, lock ±, trunk, honk, climate ±,
windows ±, get_location)
3 conditions (is_locked, target_soc_is, amp_limit_is)
1 condition trigger (is_locked) + standard triggers from button.*,
locked, onoff.climate capabilities.
Housekeeping:
The four legacy measure_polestarTyrePressure{FL,FR,RL,RR} JSONs are
removed — they never shipped in a release and the migration loop
that would auto-remove them from existing devices is gone too, since
no one has those capabilities in their device state. All current and
future users take the standard measure_pressure.* sub-IDs directly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps to 3.0.0 and wraps up the C3-migration work.
- Mark the legacy polestar-2-csv driver as deprecated via Homey's
official driver flag so new pairings are rejected but existing
devices keep working. The Car Stats Viewer webhook still supplies
live telemetry the C3 backend doesn't expose (speed, gear,
ignition, battery temperature, trip summaries) so it stays around
for P2 owners who rely on it.
- Rewrite README.md with real feature list and deprecation note,
rewrite README.txt (app-store listing) with concrete read/write
capabilities and a privacy section, and refresh the
.homeycompose/app.json description + tags to reflect what the
app actually does now instead of generic marketing copy.
- Drop the `measure_power: { approximated: true }` override. The
new C3 client returns real power_watts from the car, not a
calculated estimate, so Homey Energy can treat it as a real
sensor reading.
- Add a `windows_supported` device setting and wire it into the
same OPTIONAL_FEATURES machinery that already auto-hides
amp_limit on Polestar 4. Unchecking hides the two window
buttons; the backend auto-disables the feature when it returns
UNIMPLEMENTED.
- Make `target_temperature` fall back to the configured climate
default when the C3 climatization response has no
requested_temp (happens whenever climate isn't running). Tile
no longer stays empty on a fresh device.
- After every state-changing write (lock, climate, windows,
charging, trunk) schedule two follow-up reads at +3 s and +10 s
so the UI reflects the actual state faster than the 60 s regular
poll cycle. Window opens/closes use a wider +15 s second refresh
because physical movement takes longer to complete.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Point every custom capability used by the active vehicle driver at an SVG in drivers/vehicle/assets/ so the driver stops depending on files that live in the deprecated polestar-2-csv driver's folder. Copies battery-75, battery-100, powerdc, hvbattery, location and update from the CSV driver into the vehicle driver's own asset folder. Add tire-pressure.svg and wire it to alarm_polestarTyrePressure — Homey threw a render error on the iconless alarm tile. Fill in the two remaining missing icons (alarm_polestarOtaAvailable, measure_polestarOtaVersion) with update.svg so all three OTA capabilities share the same glyph. CSV-only capabilities (speed, gear, ignition, temperature, etc.) keep pointing at their own driver's assets — they live together and will move as a set when that driver is eventually removed. Adds a 3.0.0 changelog entry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Changelog: Polish on icons etc
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Replaces the legacy @andysmithfal/polestar.js GraphQL client with a
purpose-built C3 gRPC client that talks the same backend the official
Polestar mobile app uses. Unlocks every read and write the app exposes,
and adds corresponding Homey device tiles and flow cards.
polestar-2-csvdriver marked deprecated via Homey's official flag; tyre pressure capabilities migrated to standardmeasure_pressure.*sub-ids;measure_powerno longer flagged asapproximatedsince C3 returns real power data.Zero native deps — pure Node
http2+ a minimal varint protobuf codec, so nothing extra to load on Homey Pro.Test plan
test-c3-poc.js) exercises all 12 gRPC calls against a live Polestar 4Breaking-change notes
3.0.0— the new driver auto-adds ~25 capabilities on first run, which migrates existing devices in place.client_id=lp8dyrd_10(mobile-app style). First launch triggers OIDC/PKCE login with stored credentials; tokens refresh transparently afterwards.c3_backend_disabledsetting remains as a rollback lever should any account run into C3 issues.