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

Changes to schedule and session updating #32

Merged
merged 2 commits into from
Jan 3, 2024
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
2 changes: 1 addition & 1 deletion custom_components/ohme/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ async def async_max_charge(self):
result = await self._put_request(f"/v1/chargeSessions/{self._serial}/rule?maxCharge=true")
return bool(result)

async def async_apply_charge_rule(self, max_price=None, target_time=None, target_percent=None, pre_condition=None, pre_condition_length=None):
async def async_apply_session_rule(self, max_price=None, target_time=None, target_percent=None, pre_condition=None, pre_condition_length=None):
"""Apply rule to ongoing charge/stop max charge."""
# Check every property. If we've provided it, use that. If not, use the existing.
if max_price is None:
Expand Down
2 changes: 1 addition & 1 deletion custom_components/ohme/const.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Component constants"""
DOMAIN = "ohme"
USER_AGENT = "dan-r-homeassistant-ohme"
INTEGRATION_VERSION = "0.3.0"
INTEGRATION_VERSION = "0.3.1"

DATA_CLIENT = "client"
DATA_COORDINATORS = "coordinators"
Expand Down
41 changes: 29 additions & 12 deletions custom_components/ohme/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from homeassistant.helpers.entity import generate_entity_id
from homeassistant.core import callback, HomeAssistant
from .const import DOMAIN, DATA_CLIENT, DATA_COORDINATORS, COORDINATOR_CHARGESESSIONS, COORDINATOR_SCHEDULES

from .utils import session_in_progress

async def async_setup_entry(
hass: HomeAssistant,
Expand Down Expand Up @@ -43,36 +43,53 @@ def __init__(self, coordinator, coordinator_schedules, hass: HomeAssistant, clie

self._attr_device_info = client.get_device_info()

async def async_added_to_hass(self) -> None:
"""When entity is added to hass."""
await super().async_added_to_hass()
self.async_on_remove(
self.coordinator.async_add_listener(
self._handle_coordinator_update, None
)
)
self.async_on_remove(
self.coordinator_schedules.async_add_listener(
self._handle_coordinator_update, None
)
)

@property
def unique_id(self):
"""The unique ID of the switch."""
return self._client.get_unique_id("target_percent")

async def async_set_native_value(self, value: float) -> None:
"""Update the current value."""
# If disconnected, update top rule. If not, apply rule to current session
if self.coordinator.data and self.coordinator.data['mode'] == "DISCONNECTED":
await self._client.async_update_schedule(target_percent=int(value))
# If session in progress, update this session, if not update the first schedule
if session_in_progress(self.coordinator.data):
await self._client.async_apply_session_rule(target_percent=int(value))
await asyncio.sleep(1)
await self.coordinator_schedules.async_refresh()
await self.coordinator.async_refresh()
else:
await self._client.async_apply_charge_rule(target_percent=int(value))
await self._client.async_update_schedule(target_percent=int(value))
await asyncio.sleep(1)
await self.coordinator.async_refresh()
await self.coordinator_schedules.async_refresh()

@property
def icon(self):
"""Icon of the sensor."""
return "mdi:battery-heart"

@property
def native_value(self):
@callback
def _handle_coordinator_update(self) -> None:
"""Get value from data returned from API by coordinator"""
if self.coordinator.data and self.coordinator.data['appliedRule'] and self.coordinator.data['mode'] != "PENDING_APPROVAL" and self.coordinator.data['mode'] != "DISCONNECTED":
target = round(
self.coordinator.data['appliedRule']['targetPercent'])
# Set with the same logic as reading
if session_in_progress(self.coordinator.data):
target = round(self.coordinator.data['appliedRule']['targetPercent'])
elif self.coordinator_schedules.data:
target = round(self.coordinator_schedules.data['targetPercent'])

self._state = target if target > 0 else None

@property
def native_value(self):
return self._state
2 changes: 1 addition & 1 deletion custom_components/ohme/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ async def async_turn_on(self):
async def async_turn_off(self):
"""Stop max charging.
We are not changing anything, just applying the last rule. No need to supply anything."""
await self._client.async_apply_charge_rule()
await self._client.async_apply_session_rule()

await asyncio.sleep(1)
await self.coordinator.async_refresh()
Expand Down
41 changes: 29 additions & 12 deletions custom_components/ohme/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from homeassistant.helpers.entity import generate_entity_id
from homeassistant.core import callback, HomeAssistant
from .const import DOMAIN, DATA_CLIENT, DATA_COORDINATORS, COORDINATOR_CHARGESESSIONS, COORDINATOR_SCHEDULES
from .utils import session_in_progress
from datetime import time as dt_time

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -44,6 +45,20 @@ def __init__(self, coordinator, coordinator_schedules, hass: HomeAssistant, clie
"number.{}", "ohme_target_time", hass=hass)

self._attr_device_info = client.get_device_info()

async def async_added_to_hass(self) -> None:
"""When entity is added to hass."""
await super().async_added_to_hass()
self.async_on_remove(
self.coordinator.async_add_listener(
self._handle_coordinator_update, None
)
)
self.async_on_remove(
self.coordinator_schedules.async_add_listener(
self._handle_coordinator_update, None
)
)

@property
def unique_id(self):
Expand All @@ -52,29 +67,27 @@ def unique_id(self):

async def async_set_value(self, value: dt_time) -> None:
"""Update the current value."""
# If disconnected, update top rule. If not, apply rule to current session
if self.coordinator.data and self.coordinator.data['mode'] == "DISCONNECTED":
await self._client.async_update_schedule(target_time=(int(value.hour), int(value.minute)))
# If session in progress, update this session, if not update the first schedule
if session_in_progress(self.coordinator.data):
await self._client.async_apply_session_rule(target_time=(int(value.hour), int(value.minute)))
await asyncio.sleep(1)
await self.coordinator_schedules.async_refresh()
await self.coordinator.async_refresh()
else:
await self._client.async_apply_charge_rule(target_time=(int(value.hour), int(value.minute)))
await self._client.async_update_schedule(target_time=(int(value.hour), int(value.minute)))
await asyncio.sleep(1)
await self.coordinator.async_refresh()


await self.coordinator_schedules.async_refresh()

@property
def icon(self):
"""Icon of the sensor."""
return "mdi:alarm-check"

@property
def native_value(self):
@callback
def _handle_coordinator_update(self) -> None:
"""Get value from data returned from API by coordinator"""
# If we are not pending approval or disconnected, return in progress charge rule
# Read with the same logic as setting
target = None
if self.coordinator.data and self.coordinator.data['appliedRule'] and self.coordinator.data['mode'] != "PENDING_APPROVAL" and self.coordinator.data['mode'] != "DISCONNECTED":
if session_in_progress(self.coordinator.data):
target = self.coordinator.data['appliedRule']['targetTime']
elif self.coordinator_schedules.data:
target = self.coordinator_schedules.data['targetTime']
Expand All @@ -85,4 +98,8 @@ def native_value(self):
minute=(target % 3600) // 60,
second=0
)
self.async_write_ha_state()

@property
def native_value(self):
return self._state
13 changes: 13 additions & 0 deletions custom_components/ohme/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,16 @@ def time_next_occurs(hour, minute):
target = target + timedelta(days=1)

return target

def session_in_progress(data):
"""Is there a session in progress?
Used to check if we should update the current session rather than the first schedule."""
# Default to False with no data
if not data:
return False

# Car disconnected or pending approval, we should update the schedule
if data['mode'] == "DISCONNECTED" or data['mode'] == "PENDING_APPROVAL":
return False

return True
Loading