Skip to content

Commit

Permalink
Add schedule change function
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-r committed Jan 2, 2024
1 parent 7281650 commit 712b9d8
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 29 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ This integration exposes the following entities:
* Switches (Charge state) - **These are only functional when a car is connected**
* Max Charge - Forces the connected car to charge regardless of set schedule
* Pause Charge - Pauses an ongoing charge
* Inputs - **Only available during a charge session**
* Number: Target Percentage - Change the target percentage of the ongoing charge
* Time: Target Time - Change the time target for the current charge
* Inputs - **If in a charge session, this will change the active charge. If disconnected, this will change your first schedule.**
* Number: Target Percentage - Change the target battery percentage
* Time: Target Time - Change the target time
* Buttons
* Approve Charge - Approves a charge when 'Pending Approval' is on

Expand Down
36 changes: 20 additions & 16 deletions custom_components/ohme/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from homeassistant.components.number import NumberEntity, NumberDeviceClass
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_ACCOUNTINFO
from .const import DOMAIN, DATA_CLIENT, DATA_COORDINATORS, COORDINATOR_CHARGESESSIONS, COORDINATOR_SCHEDULES


async def async_setup_entry(
Expand All @@ -14,10 +14,10 @@ async def async_setup_entry(
"""Setup switches and configure coordinator."""
coordinators = hass.data[DOMAIN][DATA_COORDINATORS]

coordinator = coordinators[COORDINATOR_CHARGESESSIONS]
client = hass.data[DOMAIN][DATA_CLIENT]

numbers = [TargetPercentNumber(coordinator, hass, client)]
numbers = [TargetPercentNumber(
coordinators[COORDINATOR_CHARGESESSIONS], coordinators[COORDINATOR_SCHEDULES], hass, client)]

async_add_entities(numbers, update_before_add=True)

Expand All @@ -28,12 +28,13 @@ class TargetPercentNumber(NumberEntity):
_attr_device_class = NumberDeviceClass.BATTERY
_attr_suggested_display_precision = 0

def __init__(self, coordinator, hass: HomeAssistant, client):
def __init__(self, coordinator, coordinator_schedules, hass: HomeAssistant, client):
self.coordinator = coordinator
self.coordinator_schedules = coordinator_schedules

self._client = client

self._state = 0
self._state = None
self._last_updated = None
self._attributes = {}

Expand All @@ -49,10 +50,15 @@ def unique_id(self):

async def async_set_native_value(self, value: float) -> None:
"""Update the current value."""
await self._client.async_apply_charge_rule(target_percent=int(value))

await asyncio.sleep(1)
await self.coordinator.async_refresh()
# 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))
await asyncio.sleep(1)
await self.coordinator_schedules.async_refresh()
else:
await self._client.async_apply_charge_rule(target_percent=int(value))
await asyncio.sleep(1)
await self.coordinator.async_refresh()

@property
def icon(self):
Expand All @@ -62,13 +68,11 @@ def icon(self):
@property
def native_value(self):
"""Get value from data returned from API by coordinator"""
if self.coordinator.data and self.coordinator.data['appliedRule']:
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'])
elif self.coordinator_schedules.data:
target = round(self.coordinator_schedules.data['targetPercent'])

if target == 0:
return self._state

self._state = target
return self._state
return None
self._state = target if target > 0 else None
return self._state
33 changes: 23 additions & 10 deletions custom_components/ohme/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from homeassistant.components.time import TimeEntity
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_ACCOUNTINFO
from .const import DOMAIN, DATA_CLIENT, DATA_COORDINATORS, COORDINATOR_CHARGESESSIONS, COORDINATOR_SCHEDULES
from datetime import time as dt_time

_LOGGER = logging.getLogger(__name__)
Expand All @@ -18,10 +18,10 @@ async def async_setup_entry(
"""Setup switches and configure coordinator."""
coordinators = hass.data[DOMAIN][DATA_COORDINATORS]

coordinator = coordinators[COORDINATOR_CHARGESESSIONS]
client = hass.data[DOMAIN][DATA_CLIENT]

numbers = [TargetTime(coordinator, hass, client)]
numbers = [TargetTime(coordinators[COORDINATOR_CHARGESESSIONS],
coordinators[COORDINATOR_SCHEDULES], hass, client)]

async_add_entities(numbers, update_before_add=True)

Expand All @@ -30,8 +30,9 @@ class TargetTime(TimeEntity):
"""Target time sensor."""
_attr_name = "Target Time"

def __init__(self, coordinator, hass: HomeAssistant, client):
def __init__(self, coordinator, coordinator_schedules, hass: HomeAssistant, client):
self.coordinator = coordinator
self.coordinator_schedules = coordinator_schedules

self._client = client

Expand All @@ -51,10 +52,17 @@ def unique_id(self):

async def async_set_value(self, value: dt_time) -> None:
"""Update the current value."""
await self._client.async_apply_charge_rule(target_time=(int(value.hour), int(value.minute)))

await asyncio.sleep(1)
await self.coordinator.async_refresh()
# 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)))
await asyncio.sleep(1)
await self.coordinator_schedules.async_refresh()
else:
await self._client.async_apply_charge_rule(target_time=(int(value.hour), int(value.minute)))
await asyncio.sleep(1)
await self.coordinator.async_refresh()



@property
def icon(self):
Expand All @@ -64,9 +72,14 @@ def icon(self):
@property
def native_value(self):
"""Get value from data returned from API by coordinator"""
# Make sure we're not pending approval, as this sets the target time to now
if self.coordinator.data and self.coordinator.data['appliedRule'] and self.coordinator.data['mode'] != "PENDING_APPROVAL":
# If we are not pending approval or disconnected, return in progress charge rule
target = None
if self.coordinator.data and self.coordinator.data['appliedRule'] and self.coordinator.data['mode'] != "PENDING_APPROVAL" and self.coordinator.data['mode'] != "DISCONNECTED":
target = self.coordinator.data['appliedRule']['targetTime']
elif self.coordinator_schedules.data:
target = self.coordinator_schedules.data['targetTime']

if target:
self._state = dt_time(
hour=target // 3600,
minute=(target % 3600) // 60,
Expand Down

0 comments on commit 712b9d8

Please sign in to comment.