Skip to content

Commit

Permalink
Merge pull request #100 from fsaris/home_battery_installation
Browse files Browse the repository at this point in the history
- Add home_battery_installation sensors #95
- Fix grouping for sensors for each PV system #99
- Link sensors to correct device and move redundant naming
- Add better entity naming, use device name
  • Loading branch information
fsaris authored Mar 17, 2024
2 parents a01b778 + 38fd507 commit 639fe53
Show file tree
Hide file tree
Showing 8 changed files with 436 additions and 183 deletions.
67 changes: 43 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,42 @@
Unofficial integration for Zonneplan | Energie

## Current features
- Zonneplan ONE (Solar inverter) sensors: (available when solar contract)
- Zonneplan:
- Solar panels: _(available when you have 1 or more Zonneplan solar inverters)_
- Yield today: `kWh` (combined yield of all Zonneplan solar inverters) _(can be used as entity on Energy Dashboard)_
- General energy values: _(available when there is a P1 reader from Zonneplan)_
- Electricity consumed today: `kWh` _(can be used as entity on Energy Dashboard)_
- Electricity returned today: `kWh` _(can be used as entity on Energy Dashboard)_
- Gas consumption today: ``
- Electricity today low tariff: `kWh` _(can be used as entity on Energy Dashboard, default disabled)_
- Electricity today normal tariff: `kWh` _(can be used as entity on Energy Dashboard, default disabled)_
- Electricity today high tariff: `kWh` _(can be used as entity on Energy Dashboard, default disabled)_
- Energy contract related sensors: _(available when you have a Zonneplan energy contract)_
- Current Zonneplan Electricity tariff: `€/kWh`
- The full Electricity forecast is available as a forecast attribute of this sensor
- Current Zonneplan Gas tariff: `€/m³`
- Next Zonneplan Gas tariff: `€/m³`
- 8 hours forecast of Zonneplan Electricity tariff: `€/kWh` _(default disabled, available when you have a energy contract)_
- Current electricity usage
- Sustainability score
- Electricity delivery costs today
- Electricity production costs today
- Gas delivery costs today
- Zonneplan ONE (Solar inverter) sensors: _(available when you have a Zonneplan solar inverter)_
- Yield total: `kWh`
- Yield today: `kWh` _(can be used as entity on Energy Dashboard)_
- First measured: `date` _(default disabled)_
- Last measured value: `W`
- Last measured: `date`
- Zonneplan Connect (P1 reader) sensors: (available when P1 available)
- Electricity consumed today: `kWh` _(can be used as entity on Energy Dashboard)_
- Electricity returned today: `kWh` _(can be used as entity on Energy Dashboard)_
- Electricity today low tariff: `kWh` _(can be used as entity on Energy Dashboard, default disabled)_
- Electricity today normal tariff: `kWh` _(can be used as entity on Energy Dashboard, default disabled)_
- Electricity today high tariff: `kWh` _(can be used as entity on Energy Dashboard, default disabled)_
- Zonneplan Connect (P1 reader) sensors: _(available when there is a P1 reader from Zonneplan)_
- Electricity consumption: `W`
- Electricity production: `W`
- Electricity average: `W` (average use over the last 5min)
- Electricity first measured: `date` _(default disabled)_
- Electricity last measured: `date`
- Electricity last measured production: `date`
- Gas consumption today: ``
- Gas first measured: `date` _(default disabled)_
- Gas last measured: `date`
- Charge point/Laadpaal: (available when charge point contract)
- Charge point/Laadpaal: _(available when charge point contract)_
- Charge point state
- Charge point power `W`
- Charge point energy delivered session `kWh`
Expand All @@ -42,17 +56,22 @@ Unofficial integration for Zonneplan | Energie
- Charge point plug and charge `on/off`
- Charge point overload protection active `on/off` _(default disabled)_
- Buttons to start/stop charge
- Additional sensors: _(available when you have a energy contract)_
- Current Zonneplan Electricity tariff: `€/kWh`
- The full Electricity forecast is available as a forecast attribute of this sensor
- Current Zonneplan Gas tariff: `€/m³`
- Next Zonneplan Gas tariff: `€/m³` #73
- 8 hours forecast of Zonneplan Electricity tariff: `€/kWh` _(default disabled)_
- Current electricity usage
- Sustainability score
- Electricity delivery costs today
- Electricity production costs today
- Gas delivery costs today
- Battery: _(available when there is a Zonneplan Thuisbatterij)_
- Battery state
- Percentage `%`
- Power `W` _(default disabled)_
- Delivery today `kWh`
- Production today `kWh`
- Today ``
- Total ``
- Dynamic charging enabled `on/off`
- Dynamic load balancing overload active `on/off`
- Dynamic load balancing overload enabled `on/off`
- Manual control enabled `on/off`
- Inverter state _(default disabled)_
- Manual control state _(default disabled)_
- First measured `datetime` _(default disabled)_
- Last measured `datetime`

## Installation

Expand Down Expand Up @@ -82,13 +101,13 @@ Do you have [HACS](https://hacs.xyz/) installed?
## Setup Energy Dashboard

#### Solar production
`Zonneplan yield total` is what your panels produced
`Zonneplan Yield total` is what your panels produced

#### Grid consumption
`Zonneplan P1 electricity consumption today` is what you used from the grid
`Zonneplan Electricity consumption today` is what you used from the grid

#### Return to grid
`Zonneplan P1 electricity returned today` is what you returned to the grid
`Zonneplan Electricity returned today` is what you returned to the grid

### Installing main/beta version using HACS
1. Go to `HACS` => `Integrations`
Expand Down
88 changes: 66 additions & 22 deletions custom_components/zonneplan_one/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
DOMAIN,
BINARY_SENSORS_TYPES,
CHARGE_POINT,
BATTERY,
ZonneplanBinarySensorEntityDescription,
)

Expand All @@ -33,6 +34,7 @@ async def async_setup_entry(hass: HomeAssistantType, config_entry, async_add_ent
entities = []
for uuid, connection in coordinator.connections.items():
charge_point = coordinator.getConnectionValue(uuid, CHARGE_POINT)
battery = coordinator.getConnectionValue(uuid, BATTERY)

_LOGGER.debug("Setup binary sensors for connnection %s", uuid)

Expand All @@ -49,6 +51,19 @@ async def async_setup_entry(hass: HomeAssistantType, config_entry, async_add_ent
)
)

if battery:
for install_index in range(len(battery)):
for sensor_key in BINARY_SENSORS_TYPES[BATTERY]:
entities.append(
ZonneplanBatteryBinarySensor(
uuid,
sensor_key,
coordinator,
install_index,
BINARY_SENSORS_TYPES[BATTERY][sensor_key],
)
)

async_add_entities(entities)


Expand Down Expand Up @@ -84,16 +99,6 @@ def unique_id(self) -> Optional[str]:
"""Return a unique ID."""
return self.install_uuid + "_" + self._sensor_key

@property
def name(self) -> str:
"""Return the name of the entity."""

name = self.entity_description.name
if self._install_index and self._install_index > 0:
name += " (" + str(self._install_index + 1) + ")"

return name

@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
Expand Down Expand Up @@ -145,28 +150,67 @@ def install_uuid(self) -> str:
@property
def device_info(self):
"""Return the device information."""
device_info = {
"identifiers": {(DOMAIN, self._connection_uuid, CHARGE_POINT)},
return {
"identifiers": {(DOMAIN, self.install_uuid)},
"via_device": (DOMAIN, self._connection_uuid),
"manufacturer": "Zonneplan",
"name": self.coordinator.getConnectionValue(
self._connection_uuid,
"charge_point_installation.0.label",
),
}

if self._install_index >= 0:
device_info["identifiers"].add((DOMAIN, self.install_uuid))
device_info["name"] = self.coordinator.getConnectionValue(
"charge_point_installation.{install_index}.label".format(
install_index=self._install_index
),
) + (f" ({self._install_index + 1})" if self._install_index and self._install_index > 0 else ""),
"model": self.coordinator.getConnectionValue(
self._connection_uuid,
"charge_point_installation.{install_index}.label".format(
install_index=self._install_index
),
)
device_info["model"] = self.coordinator.getConnectionValue(
),
"serial_number": self.coordinator.getConnectionValue(
self._connection_uuid,
"charge_point_installation.{install_index}.meta.serial_number".format(
install_index=self._install_index
),
)
}

class ZonneplanBatteryBinarySensor(ZonneplanBinarySensor):
@property
def install_uuid(self) -> str:
"""Return install ID."""
if self._install_index < 0:
return self._connection_uuid
else:
return self.coordinator.getConnectionValue(
self._connection_uuid,
"home_battery_installation.{install_index}.uuid".format(
install_index=self._install_index
),
)

return device_info
@property
def device_info(self):
"""Return the device information."""
return {
"identifiers": {(DOMAIN, self.install_uuid)},
"via_device": (DOMAIN, self._connection_uuid),
"manufacturer": "Zonneplan",
"name": self.coordinator.getConnectionValue(
self._connection_uuid,
"home_battery_installation.{install_index}.label".format(
install_index=self._install_index
),
) + (f" ({self._install_index + 1})" if self._install_index and self._install_index > 0 else ""),
"model": self.coordinator.getConnectionValue(
self._connection_uuid,
"home_battery_installation.{install_index}.label".format(
install_index=self._install_index
),
),
"serial_number": self.coordinator.getConnectionValue(
self._connection_uuid,
"home_battery_installation.{install_index}.meta.identifier".format(
install_index=self._install_index
),
),
}
43 changes: 18 additions & 25 deletions custom_components/zonneplan_one/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,18 @@ def __init__(
@property
def install_uuid(self) -> str:
"""Return install ID."""
return self._connection_uuid
return self.coordinator.getConnectionValue(
self._connection_uuid,
"charge_point_installation.{install_index}.uuid".format(
install_index=self._install_index
),
)

@property
def unique_id(self) -> Optional[str]:
"""Return a unique ID."""
return self.install_uuid + "_" + self._button_key

@property
def name(self) -> str:
"""Return the name of the entity."""

name = self.entity_description.name
if self._install_index and self._install_index > 0:
name += " (" + str(self._install_index + 1) + ")"

return name

@property
def available(self) -> bool:
"""Return if entity is available."""
Expand All @@ -113,31 +108,29 @@ def available(self) -> bool:
@property
def device_info(self):
"""Return the device information."""
device_info = {
"identifiers": {(DOMAIN, self._connection_uuid, CHARGE_POINT)},
return {
"identifiers": {(DOMAIN, self.install_uuid)},
"via_device": (DOMAIN, self._connection_uuid),
"manufacturer": "Zonneplan",
"name": self.coordinator.getConnectionValue(
self._connection_uuid,
"charge_point_installation.0.label",
),
}

if self._install_index >= 0:
device_info["identifiers"].add((DOMAIN, self.install_uuid))
device_info["name"] = self.coordinator.getConnectionValue(
"charge_point_installation.{install_index}.label".format(
install_index=self._install_index
),
) + (f" ({self._install_index + 1})" if self._install_index and self._install_index > 0 else ""),
"model": self.coordinator.getConnectionValue(
self._connection_uuid,
"charge_point_installation.{install_index}.label".format(
install_index=self._install_index
),
)
device_info["model"] = self.coordinator.getConnectionValue(
),
"serial_number": self.coordinator.getConnectionValue(
self._connection_uuid,
"charge_point_installation.{install_index}.meta.serial_number".format(
install_index=self._install_index
),
)

return device_info
),
}

async def async_press(self) -> None:
"""Handle the button press."""
Expand Down
Loading

0 comments on commit 639fe53

Please sign in to comment.