Skip to content

Commit

Permalink
Add backend logic for multi device support
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-r committed Jan 15, 2024
1 parent ce05a0a commit 0d56e93
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 14 deletions.
16 changes: 12 additions & 4 deletions custom_components/ohme/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ async def async_setup(hass: core.HomeAssistant, config: dict) -> bool:
return True


async def async_setup_dependencies(hass, config):
async def async_setup_dependencies(hass, entry):
"""Instantiate client and refresh session"""
client = OhmeApiClient(config['email'], config['password'])
client = OhmeApiClient(entry.data['email'], entry.data['password'], hass, entry)
hass.data[DOMAIN][DATA_CLIENT] = client

await client.async_create_session()
Expand All @@ -32,7 +32,7 @@ async def async_setup_entry(hass, entry):
if "email" not in config:
return False

await async_setup_dependencies(hass, config)
await async_setup_dependencies(hass, entry)

coordinators = [
OhmeChargeSessionsCoordinator(hass=hass), # COORDINATOR_CHARGESESSIONS
Expand Down Expand Up @@ -88,7 +88,15 @@ async def async_migrate_entry(hass: core.HomeAssistant, config_entry) -> bool:
# Version number has gone up
if config_entry.version < CONFIG_VERSION:
_LOGGER.debug("Migrating from version %s", config_entry.version)
new_data = config_entry.data
new_data = dict(config_entry.data)

# 1 -> 2: Add serial to config
if CONFIG_VERSION >= 2:
client = OhmeApiClient(new_data['email'], new_data['password'])
await client.async_create_session()

chargers = await client.async_get_chargers()
new_data['serial'] = chargers[0]

config_entry.version = CONFIG_VERSION
hass.config_entries.async_update_entry(config_entry, data=new_data)
Expand Down
30 changes: 22 additions & 8 deletions custom_components/ohme/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
class OhmeApiClient:
"""API client for Ohme EV chargers."""

def __init__(self, email, password):
def __init__(self, email, password, hass=None, config_entry=None):
if email is None or password is None:
raise Exception("Credentials not provided")

# Credentials from configuration
self._email = email
self._password = password
self._hass = hass
self._config_entry = config_entry

# Charger and its capabilities
self._device_info = None
Expand All @@ -35,7 +37,7 @@ def __init__(self, email, password):

# User info
self._user_id = ""
self._serial = ""
self._serial = config_entry.data['serial'] if config_entry else None

# Cache the last rule to use when we disable max charge or change schedule
self._last_rule = {}
Expand Down Expand Up @@ -226,7 +228,7 @@ async def async_apply_session_rule(self, max_price=None, target_time=None, targe

result = await self._put_request(f"/v1/chargeSessions/{self._serial}/rule?enableMaxPrice={max_price}&targetTs={target_ts}&enablePreconditioning={pre_condition}&toPercent={target_percent}&preconditionLengthMins={pre_condition_length}")
return bool(result)

async def async_get_schedule(self):
"""Get the first schedule."""
schedules = await self._get_request("/v1/chargeRules")
Expand Down Expand Up @@ -261,7 +263,7 @@ async def async_get_charge_sessions(self, is_retry=False):
"""Try to fetch charge sessions endpoint.
If we get a non 200 response, refresh auth token and try again"""
resp = await self._get_request('/v1/chargeSessions')
resp = resp[0]
resp = next(filter(lambda x: x['chargeDevice']['id'] == self._serial, resp), None)

# Cache the current rule if we are given it
if resp["mode"] == "SMART_CHARGE" and 'appliedRule' in resp:
Expand All @@ -276,15 +278,14 @@ async def async_get_account_info(self):

async def async_get_charge_device(self):
resp = await self.async_get_account_info()
device = resp[0]
device = next(filter(lambda x: x['id'] == self._serial, resp['chargeDevices']), None)

return device

async def async_update_device_info(self, is_retry=False):
"""Update _device_info with our charger model."""
resp = await self.async_get_account_info()

device = resp['chargeDevices'][0]
device = next(filter(lambda x: x['id'] == self._serial, resp['chargeDevices']), None)

info = DeviceInfo(
identifiers={(DOMAIN, "ohme_charger")},
Expand All @@ -297,10 +298,23 @@ async def async_update_device_info(self, is_retry=False):

self._capabilities = device['modelCapabilities']
self._user_id = resp['user']['id']
self._serial = device['id']
self._device_info = info

self._hass.config_entries.async_update_entry(
self._config_entry, title=f"{device['modelTypeDisplayName']} ({device['id']})"
)

return True

async def async_get_chargers(self):
"""Get a list of chargers on an account."""
resp = await self.async_get_account_info()
chargers = []

for device in resp['chargeDevices']:
chargers.append(device['id'])

return chargers

async def async_get_charge_statistics(self):
"""Get charge statistics. Currently this is just for all time (well, Jan 2019)."""
Expand Down
4 changes: 2 additions & 2 deletions custom_components/ohme/const.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Component constants"""
DOMAIN = "ohme"
USER_AGENT = "dan-r-homeassistant-ohme"
INTEGRATION_VERSION = "0.3.2"
CONFIG_VERSION = 1
INTEGRATION_VERSION = "0.3.3"
CONFIG_VERSION = 2
ENTITY_TYPES = ["sensor", "binary_sensor", "switch", "button", "number", "time"]

DATA_CLIENT = "client"
Expand Down

0 comments on commit 0d56e93

Please sign in to comment.