Skip to content

Commit

Permalink
Added target time and percentage inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-r committed Jan 1, 2024
1 parent a87f53b commit f56f886
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 2 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ This integration exposes the following entities:
* Car Charging - On when a car is connected and drawing power
* Pending Approval - On when a car is connected and waiting for approval
* Charge Slot Active - On when a charge slot is in progress according to the Ohme-generated charge plan
* Sensors (Charge power) - **These are only available during a charge session**
* Sensors (Charge power) - **Only available during a charge session**
* Power Draw (Watts) - Power draw of connected car
* Current Draw (Amps) - Current draw of connected car
* Voltage (Volts) - Voltage reading
Expand All @@ -54,6 +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
* Buttons
* Approve Charge - Approves a charge when 'Pending Approval' is on

Expand All @@ -67,6 +70,7 @@ The coordinators are listed with their refresh intervals below. Relevant coordin
* Buttons: Approve Charge
* Sensors: Power, current, voltage and next slot (start & end)
* Switches: Max charge, pause charge
* Inputs: Target time and target percentage
* OhmeAccountInfoCoordinator (1m refresh)
* Switches: Lock buttons, require approval and sleep when inactive
* OhmeAdvancedSettingsCoordinator (1m refresh)
Expand Down
2 changes: 1 addition & 1 deletion custom_components/ohme/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async def async_setup_entry(hass, entry):
hass.data[DOMAIN][DATA_COORDINATORS] = coordinators

# Create tasks for each entity type
entity_types = ["sensor", "binary_sensor", "switch", "button", "number"]
entity_types = ["sensor", "binary_sensor", "switch", "button", "number", "time"]
for entity_type in entity_types:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, entity_type)
Expand Down
74 changes: 74 additions & 0 deletions custom_components/ohme/number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from __future__ import annotations
import asyncio
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


async def async_setup_entry(
hass: HomeAssistant,
config_entry: config_entries.ConfigEntry,
async_add_entities
):
"""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)]

async_add_entities(numbers, update_before_add=True)


class TargetPercentNumber(NumberEntity):
"""Target percentage sensor."""
_attr_name = "Target Percentage"
_attr_device_class = NumberDeviceClass.BATTERY
_attr_suggested_display_precision = 0

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

self._client = client

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

self.entity_id = generate_entity_id(
"number.{}", "ohme_target_percent", hass=hass)

self._attr_device_info = client.get_device_info()

@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."""
await self._client.async_apply_charge_rule(target_percent=int(value))

await asyncio.sleep(1)
await self.coordinator.async_refresh()

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

@property
def native_value(self):
"""Get value from data returned from API by coordinator"""
if self.coordinator.data and self.coordinator.data['appliedRule']:
target = round(
self.coordinator.data['appliedRule']['targetPercent'])

if target == 0:
return self._state

self._state = target
return self._state
return None
74 changes: 74 additions & 0 deletions custom_components/ohme/time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from __future__ import annotations
import asyncio
import logging
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 datetime import time as dt_time

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(
hass: HomeAssistant,
config_entry: config_entries.ConfigEntry,
async_add_entities
):
"""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)]

async_add_entities(numbers, update_before_add=True)


class TargetTime(TimeEntity):
"""Target time sensor."""
_attr_name = "Target Time"

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

self._client = client

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

self.entity_id = generate_entity_id(
"number.{}", "ohme_target_time", hass=hass)

self._attr_device_info = client.get_device_info()

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

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()

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

@property
def native_value(self):
"""Get value from data returned from API by coordinator"""
if self.coordinator.data and self.coordinator.data['appliedRule']:
target = self.coordinator.data['appliedRule']['targetTime']
return dt_time(
hour=target // 3600,
minute=(target % 3600) // 60,
second=0
)
return None

0 comments on commit f56f886

Please sign in to comment.