Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sensor for Battery SoC #36

Merged
merged 2 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions custom_components/checkwatt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class CheckwattResp(TypedDict):
price_zone: str
annual_revenue: float
annual_fees: float
battery_power: float
battery_soc: float


async def update_listener(hass: HomeAssistant, entry):
Expand Down Expand Up @@ -129,6 +131,8 @@ async def _async_update_data(self) -> CheckwattResp:
raise InvalidAuth
if not await cw_inst.get_customer_details():
raise UpdateFailed("Unknown error get_customer_details")
if not await cw_inst.get_energy_flow():
raise UpdateFailed("Unknown error get_energy_flow")

# Prevent slow funcion to be called at boot.
# The revenue sensors will be updated after ca 1 min
Expand Down Expand Up @@ -189,6 +193,9 @@ async def _async_update_data(self) -> CheckwattResp:
"battery_charge_peak": cw_inst.battery_charge_peak,
"battery_discharge_peak": cw_inst.battery_discharge_peak,
}
if cw_inst.energy_data is not None:
resp["battery_power"] = cw_inst.battery_power
resp["battery_soc"] = cw_inst.battery_soc

# Use self stored variant of revenue parameters as they are not always fetched
if self.today_revenue is not None:
Expand Down
9 changes: 5 additions & 4 deletions custom_components/checkwatt/const.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Constants for the Checkwatt integration."""
"""Constants for the CheckWatt integration."""
from typing import Final

DOMAIN = "checkwatt"
Expand All @@ -8,22 +8,23 @@
CONF_UPDATE_INTERVAL = 1
CONF_UPDATE_INTERVAL_FCRD = 15
ATTRIBUTION = "Data provided by CheckWatt EnergyInBalance"
MANUFACTURER = "Checkwatt"
CHECKWATT_MODEL = "Checkwatt"
MANUFACTURER = "CheckWatt"
CHECKWATT_MODEL = "CheckWatt"

CONF_DETAILED_SENSORS: Final = "show_details"
CONF_DETAILED_ATTRIBUTES: Final = "show_detailed_attributes"

# Misc
P_UNKNOWN = "Unknown"

# Checkwatt Sensor Attributes
# CheckWatt Sensor Attributes
# NOTE Keep these names aligned with strings.json
#
C_ADR = "street_address"
C_ANNUAL_FEES = "annual_fees"
C_ANNUAL_FEE_RATE = "annual_fee_rate"
C_ANNUAL_GROSS = "annual_gross_income"
C_BATTERY_POWER = "battery_power"
C_CHARGE_PEAK = "charge_peak"
C_CITY = "city"
C_DISCHARGE_PEAK = "discharge_peak"
Expand Down
4 changes: 2 additions & 2 deletions custom_components/checkwatt/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"homekit": {},
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/faanskit/ha-checkwatt/issues",
"requirements": ["pycheckwatt>=0.1.4"],
"requirements": ["pycheckwatt>=0.1.5"],
"ssdp": [],
"version": "0.1.0",
"version": "0.1.1",
"zeroconf": []
}
51 changes: 50 additions & 1 deletion custom_components/checkwatt/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import UnitOfEnergy
from homeassistant.const import PERCENTAGE, UnitOfEnergy
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
Expand All @@ -24,6 +24,7 @@
C_ANNUAL_FEE_RATE,
C_ANNUAL_FEES,
C_ANNUAL_GROSS,
C_BATTERY_POWER,
C_CHARGE_PEAK,
C_CITY,
C_DISCHARGE_PEAK,
Expand Down Expand Up @@ -72,6 +73,15 @@
state_class=SensorStateClass.TOTAL,
translation_key="annual_yield_sensor",
),
"battery": SensorEntityDescription(
key="battery_soc",
name="CheckWatt Battery SoC",
icon="mdi:battery-medium",
device_class=SensorDeviceClass.BATTERY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.TOTAL,
translation_key="battery_soc_sensor",
),
}


Expand Down Expand Up @@ -166,6 +176,8 @@ async def async_setup_entry(
entities.append(
CheckwattAnnualSensor(coordinator, description, use_detailed_attributes)
)
elif key == "battery":
entities.append(CheckwattBatterySoCSensor(coordinator, description))

if use_detailed_sensors:
_LOGGER.debug(
Expand Down Expand Up @@ -601,3 +613,40 @@ def native_value(self) -> str | None:
if self.vat_key == "inc_vat":
return round(self._coordinator.data["spot_price"] * 1.25, 3)
return round(self._coordinator.data["spot_price"], 3)


class CheckwattBatterySoCSensor(AbstractCheckwattSensor):
"""Representation of a CheckWatt Battery SoC sensor."""

def __init__(
self,
coordinator: CheckwattCoordinator,
description: SensorEntityDescription,
) -> None:
"""Initialize the sensor."""
_LOGGER.debug("Creating %s sensor", description.name)
super().__init__(coordinator=coordinator, description=description)

async def async_update(self) -> None:
"""Get the latest data and updates the states."""
if "battery_power" in self._coordinator.data:
self._attr_extra_state_attributes.update(
{C_BATTERY_POWER: self._coordinator.data["battery_power"]}
)
self._attr_available = True

@callback
def _handle_coordinator_update(self) -> None:
"""Get the latest data and updates the states."""
if "battery_soc" in self._coordinator.data:
self._attr_native_value = self._coordinator.data["battery_soc"]
if "battery_power" in self._coordinator.data:
self._attr_extra_state_attributes.update(
{C_BATTERY_POWER: self._coordinator.data["battery_power"]}
)
super()._handle_coordinator_update()

@property
def native_value(self) -> str | None:
"""Get the latest state value."""
return self._coordinator.data["battery_soc"]
12 changes: 10 additions & 2 deletions custom_components/checkwatt/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"entity": {
"sensor": {
"daily_yield_sensor": {
"name": "CheckWatt Daily Yield",
"name": "CheckWatt Daily Net Income",
"state_attributes": {
"street_address": {
"name": "Street Address"
Expand Down Expand Up @@ -90,7 +90,7 @@
}
},
"annual_yield_sensor": {
"name": "CheckWatt Annual Yield",
"name": "CheckWatt Annual Net Income",
"state_attributes": {
"street_address": {
"name": "Street Address"
Expand Down Expand Up @@ -145,6 +145,14 @@
"name": "VAT"
}
}
},
"battery_soc_sensor": {
"name": "Battery SoC",
"state_attributes": {
"battery_power": {
"name": "Battery Power"
}
}
}
}
}
Expand Down
12 changes: 10 additions & 2 deletions custom_components/checkwatt/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"entity": {
"sensor": {
"daily_yield_sensor": {
"name": "CheckWatt Daily Yield",
"name": "CheckWatt Daily Net Income",
"state_attributes": {
"street_address": {
"name": "Street Address"
Expand Down Expand Up @@ -90,7 +90,7 @@
}
},
"annual_yield_sensor": {
"name": "CheckWatt Annual Yield",
"name": "CheckWatt Annual Net Income",
"state_attributes": {
"street_address": {
"name": "Street Address"
Expand Down Expand Up @@ -145,6 +145,14 @@
"name": "VAT"
}
}
},
"battery_soc_sensor": {
"name": "Battery SoC",
"state_attributes": {
"battery_power": {
"name": "Battery Power"
}
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions custom_components/checkwatt/translations/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@
"name": "Moms"
}
}
},
"battery_soc_sensor": {
"name": "Batteriladdning",
"state_attributes": {
"battery_power": {
"name": "Batterieffekt"
}
}
}
}
}
Expand Down
Loading