Skip to content

Commit bc8d009

Browse files
committed
feat: add EV SoC sensor, remove SoC change/limit, and refresh docs
add per-vehicle SoC sensor using live status (stateOfCharge.value) with session fallback keep per-vehicle battery size sensor remove SoC Change and SoC Limit sensors completely fix GraphQL SmartFlex status query (inline fragments + DecimalReading subfields) harden session handling for null/empty charging data update README files and release notes bump integration version to 0.0.90
1 parent c17021b commit bc8d009

8 files changed

Lines changed: 63506 additions & 12837 deletions

File tree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,21 @@ The integration is configured via the Home Assistant UI:
194194
- `account_number`: Your Octopus Energy account number
195195
- `last_updated`: Timestamp of the last update
196196

197+
#### Vehicle Sensors
198+
199+
- **Entity ID**: `sensor.octopus_<account_number>_<device_name>_soc`
200+
- **Description**: Latest vehicle state of charge (SoC) in percent
201+
- **State Source**:
202+
- Primary: live device status (`stateOfCharge.value`)
203+
- Fallback: latest charging session (`stateOfChargeFinal`)
204+
- **Unit**: `%`
205+
206+
- **Entity ID**: `sensor.octopus_<account_number>_<device_name>_battery_size`
207+
- **Description**: Vehicle battery size reported by the provider
208+
- **Unit**: `kWh`
209+
210+
**Note**: `SoC Change` and `SoC Limit` sensors were removed and are no longer created by the integration.
211+
197212
#### Smart Charging Sessions Sensor
198213

199214
- **Entity ID**: `sensor.octopus_<account_number>_<device_name>_smart_charging_sessions`

RELEASE_NOTES.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,44 @@
11
# Release Notes
22

3+
## Version 0.0.90 (2026-06-07)
4+
5+
### 🎉 New Features
6+
7+
#### Vehicle Data Sensors
8+
- **New Sensor**: `sensor.octopus_<account_number>_<device_name>_soc`
9+
- Per-vehicle state of charge (SoC) in `%`
10+
- Uses live status data (`stateOfCharge.value`) when available
11+
- Falls back to latest charging session (`stateOfChargeFinal`) if needed
12+
13+
- **New Sensor**: `sensor.octopus_<account_number>_<device_name>_battery_size`
14+
- Per-vehicle battery size in `kWh`
15+
16+
### 🔧 Improvements
17+
18+
#### GraphQL / API Compatibility
19+
- Fixed SmartFlex status query to use inline fragments for type-specific fields
20+
- `SmartFlexVehicleStatus`
21+
- `SmartFlexChargePointStatus`
22+
- Fixed `stateOfCharge` query shape to match API type `DecimalReading`
23+
- now queried as `stateOfCharge { value timestamp }`
24+
25+
#### Sensor Robustness
26+
- Prevented coordinator listener crashes when `charging_sessions` is `null`
27+
- Added defensive handling for missing/partial device and session payloads
28+
29+
### ❌ Removed
30+
31+
- Removed `SoC Change` sensor (`..._soc_change`)
32+
- Removed `SoC Limit` sensor (`..._soc_limit`)
33+
34+
Reason:
35+
- These values are not reliably provided by all providers/devices and caused confusion (`Nicht verfügbar`) in normal operation.
36+
37+
### 📝 Documentation Updates
38+
39+
- Updated both README files to document current vehicle sensors (`SoC`, `Battery Size`)
40+
- Removed documentation for `SoC Change` and `SoC Limit`
41+
342
## Version 0.0.66 (2025-11-22)
443

544
### 🎉 New Features

custom_components/octopus_germany/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,21 @@ The integration is configured via the Home Assistant UI:
211211
- `account_number`: Your Octopus Energy account number
212212
- `last_updated`: Timestamp of the last update
213213

214+
#### Vehicle Sensors
215+
216+
- **Entity ID**: `sensor.octopus_<account_number>_<device_name>_soc`
217+
- **Description**: Latest vehicle state of charge (SoC) in percent
218+
- **State Source**:
219+
- Primary: live device status (`stateOfCharge.value`)
220+
- Fallback: latest charging session (`stateOfChargeFinal`)
221+
- **Unit**: `%`
222+
223+
- **Entity ID**: `sensor.octopus_<account_number>_<device_name>_battery_size`
224+
- **Description**: Vehicle battery size reported by the provider
225+
- **Unit**: `kWh`
226+
227+
**Note**: `SoC Change` and `SoC Limit` sensors were removed and are no longer created by the integration.
228+
214229
### Switches
215230

216231
#### Smart Charging Control

custom_components/octopus_germany/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313
"requirements": [
1414
"python-graphql-client>=0.4.3"
1515
],
16-
"version": "0.0.89"
16+
"version": "0.0.90"
1717
}

custom_components/octopus_germany/octopus_germany.py

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,28 @@
180180
current
181181
currentState
182182
isSuspended
183+
... on SmartFlexVehicleStatus {
184+
stateOfCharge {
185+
value
186+
timestamp
187+
}
188+
stateOfChargeLimit {
189+
upperSocLimit
190+
timestamp
191+
isLimitViolated
192+
}
193+
}
194+
... on SmartFlexChargePointStatus {
195+
stateOfCharge {
196+
value
197+
timestamp
198+
}
199+
stateOfChargeLimit {
200+
upperSocLimit
201+
timestamp
202+
isLimitViolated
203+
}
204+
}
183205
}
184206
provider
185207
preferences {
@@ -224,6 +246,17 @@
224246
current
225247
currentState
226248
isSuspended
249+
... on SmartFlexVehicleStatus {
250+
stateOfCharge {
251+
value
252+
timestamp
253+
}
254+
stateOfChargeLimit {
255+
upperSocLimit
256+
timestamp
257+
isLimitViolated
258+
}
259+
}
227260
}
228261
vehicleVariant {
229262
model
@@ -234,6 +267,8 @@
234267
node {
235268
start
236269
end
270+
stateOfChargeChange
271+
stateOfChargeFinal
237272
energyAdded {
238273
value
239274
unit
@@ -259,6 +294,8 @@
259294
node {
260295
start
261296
end
297+
stateOfChargeChange
298+
stateOfChargeFinal
262299
energyAdded {
263300
value
264301
unit
@@ -629,6 +666,8 @@
629666
node {
630667
start
631668
end
669+
stateOfChargeChange
670+
stateOfChargeFinal
632671
energyAdded {
633672
value
634673
unit
@@ -654,6 +693,8 @@
654693
node {
655694
start
656695
end
696+
stateOfChargeChange
697+
stateOfChargeFinal
657698
energyAdded {
658699
value
659700
unit
@@ -1182,6 +1223,21 @@ async def fetch_all_data(self, account_number: str):
11821223
for edge in edges:
11831224
session = edge.get("node", {})
11841225
if session:
1226+
# Normalize SoC fields to snake_case for internal consumers.
1227+
if (
1228+
"soc_final" not in session
1229+
and "stateOfChargeFinal" in session
1230+
):
1231+
session["soc_final"] = session.get(
1232+
"stateOfChargeFinal"
1233+
)
1234+
if (
1235+
"soc_change" not in session
1236+
and "stateOfChargeChange" in session
1237+
):
1238+
session["soc_change"] = session.get(
1239+
"stateOfChargeChange"
1240+
)
11851241
# Add device context to session
11861242
session["device_id"] = device_id
11871243
session["device_name"] = device_name
@@ -1565,6 +1621,21 @@ async def fetch_charging_sessions(self, account_number: str):
15651621
for edge in edges:
15661622
session = edge.get("node", {})
15671623
if session:
1624+
# Normalize SoC fields to snake_case for internal consumers.
1625+
if (
1626+
"soc_final" not in session
1627+
and "stateOfChargeFinal" in session
1628+
):
1629+
session["soc_final"] = session.get(
1630+
"stateOfChargeFinal"
1631+
)
1632+
if (
1633+
"soc_change" not in session
1634+
and "stateOfChargeChange" in session
1635+
):
1636+
session["soc_change"] = session.get(
1637+
"stateOfChargeChange"
1638+
)
15681639
# Add device context to session
15691640
session["device_id"] = device_id
15701641
session["device_name"] = device_name
@@ -2323,7 +2394,9 @@ async def fetch_electricity_15min_readings(
23232394
return None
23242395

23252396
if "errors" in response:
2326-
_LOGGER.error("GraphQL errors in 15min readings: %s", response["errors"])
2397+
_LOGGER.error(
2398+
"GraphQL errors in 15min readings: %s", response["errors"]
2399+
)
23272400
return None
23282401

23292402
measurements = (
@@ -2348,7 +2421,9 @@ async def fetch_electricity_15min_readings(
23482421
)
23492422
_LOGGER.debug(
23502423
"Found %d 15-min readings for property %s on %s",
2351-
len(readings), property_id, date,
2424+
len(readings),
2425+
property_id,
2426+
date,
23522427
)
23532428
return readings
23542429
else:

0 commit comments

Comments
 (0)