Skip to content

Commit

Permalink
Feature/battery state (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
acesyde authored May 14, 2023
1 parent 0ad46ab commit c599ebb
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 5 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ _Integration to integrate with [MyLight Systems][mylight_systems]._
| `sensor.total_self_conso` | Self consumption. | % | :white_check_mark: |
| `sensor.total_msb_charge` | My Smart Battery Charge. | W/h | :white_check_mark: |
| `sensor.total_msb_discharge` | My Smart Battery Discharge. | W/h | :white_check_mark: |
| `sensor.battery_state` | Current battery state. | kW | :white_check_mark: |
| `sensor.total_green_energy` | Total power consumned (from the production) by you home. | W/h | :white_check_mark: |

## Installation

Expand Down
29 changes: 29 additions & 0 deletions custom_components/mylight_systems/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
DEVICES_URL,
MEASURES_TOTAL_URL,
PROFILE_URL,
STATES_URL,
)
from .exceptions import (
CommunicationException,
Expand Down Expand Up @@ -133,6 +134,7 @@ async def async_get_devices(self, auth_token: str) -> InstallationDevices:
model.virtual_device_id = device["id"]
if device["type"] == "bat":
model.virtual_battery_id = device["id"]
model.virtual_battery_capacity = device["batteryCapacity"]
if device["type"] == "mst":
model.master_id = device["id"]
model.master_report_period = device["reportPeriod"]
Expand Down Expand Up @@ -165,3 +167,30 @@ async def async_get_measures_total(
)

return measures

async def async_get_battery_state(
self, auth_token: str, battery_id: str
) -> Measure | None:
"""Get battery state."""
response = await self._execute_request(
"get", STATES_URL, params={"authToken": auth_token}
)

if response["status"] == "error":
if response["error"] == "not.authorized":
raise UnauthorizedException()

measure: Measure = None

for device in response["deviceStates"]:
if device["deviceId"] == battery_id:
for state in device["sensorStates"]:
if state["sensorId"] == battery_id + "-soc":
measure = Measure(
state["measure"]["type"],
state["measure"]["value"],
state["measure"]["unit"],
)
return measure

return measure
1 change: 1 addition & 0 deletions custom_components/mylight_systems/api/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
PROFILE_URL: str = "/api/profile"
DEVICES_URL: str = "/api/devices"
MEASURES_TOTAL_URL: str = "/api/measures/total"
STATES_URL: str = "/api/states"
2 changes: 1 addition & 1 deletion custom_components/mylight_systems/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
NAME = "MyLight Systems"
DOMAIN = "mylight_systems"
PLATFORMS = [Platform.SENSOR]
VERSION = "0.0.2"
VERSION = "0.0.5"
COORDINATOR = "coordinator"
ATTRIBUTION = "Data provided by https://www.mylight-systems.com/"
SCAN_INTERVAL_IN_MINUTES = 15
Expand Down
14 changes: 11 additions & 3 deletions custom_components/mylight_systems/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
)
from .const import (
CONF_GRID_TYPE,
CONF_VIRTUAL_BATTERY_ID,
CONF_VIRTUAL_DEVICE_ID,
DOMAIN,
LOGGER,
Expand All @@ -41,6 +42,7 @@ class MyLightSystemsCoordinatorData(NamedTuple):
msb_charge: Measure
msb_discharge: Measure
green_energy: Measure
battery_state: Measure


# https://developers.home-assistant.io/docs/integration_fetching_data#coordinated-single-api-poll-for-data-for-all-entities
Expand Down Expand Up @@ -72,13 +74,20 @@ async def _async_update_data(self) -> MyLightSystemsCoordinatorData:
password = self.config_entry.data[CONF_PASSWORD]
grid_type = self.config_entry.data[CONF_GRID_TYPE]
device_id = self.config_entry.data[CONF_VIRTUAL_DEVICE_ID]
virtual_battery_id = self.config_entry.data[
CONF_VIRTUAL_BATTERY_ID
]

await self.authenticate_user(email, password)

result = await self.client.async_get_measures_total(
self.__auth_token, grid_type, device_id
)

battery_state = await self.client.async_get_battery_state(
self.__auth_token, virtual_battery_id
)

return MyLightSystemsCoordinatorData(
produced_energy=self.find_measure_by_type(
result, "produced_energy"
Expand All @@ -95,9 +104,8 @@ async def _async_update_data(self) -> MyLightSystemsCoordinatorData:
msb_discharge=self.find_measure_by_type(
result, "msb_discharge"
),
green_energy=self.find_measure_by_type(
result, "green_energy"
),
green_energy=self.find_measure_by_type(result, "green_energy"),
battery_state=battery_state,
)
except (
UnauthorizedException,
Expand Down
12 changes: 11 additions & 1 deletion custom_components/mylight_systems/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import PERCENTAGE, UnitOfEnergy
from homeassistant.const import PERCENTAGE, POWER_KILO_WATT, UnitOfEnergy

from .const import DOMAIN
from .coordinator import (
Expand Down Expand Up @@ -126,6 +126,16 @@ class MyLightSensorEntityDescription(
if data.green_energy is not None
else 0,
),
MyLightSensorEntityDescription(
key="battery_state",
name="Battery state",
icon="mdi:battery",
native_unit_of_measurement=POWER_KILO_WATT,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda data: round(data.battery_state.value / 36e2 / 1e3, 2)
if data.battery_state is not None
else 0,
),
)


Expand Down

0 comments on commit c599ebb

Please sign in to comment.