Skip to content

Commit

Permalink
#198 setup done. needs refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
magnuselden authored and magnuselden committed Feb 22, 2023
1 parent d8a7699 commit 2ebca37
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 76 deletions.
5 changes: 3 additions & 2 deletions custom_components/peaqev/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ async def async_setup_entry(hass: HomeAssistant, conf: ConfigEntry) -> bool:

options = HubOptions()
options.peaqev_lite = peaqev_lite
options.powersensor_includes_car = conf.data[
"powersensorincludescar"] if "powersensorincludescar" in conf.data.keys() else False
options.powersensor_includes_car = conf.data["powersensorincludescar"] if "powersensorincludescar" in conf.data.keys() else False
options.locale = conf.data["locale"]
options.charger.chargertype = conf.data["chargertype"]
if options.charger.chargertype == ChargerType.Outlet.value:
options.charger.powerswitch = conf.data["outletswitch"]
options.charger.powermeter = conf.data["outletpowermeter"]
else:
options.charger.chargerid = conf.data["chargerid"]
if options.charger.chargertype == ChargerType.NoCharger.value:
options.powersensor_includes_car = True
options.startpeaks = conf.options["startpeaks"] if "startpeaks" in conf.options.keys() else conf.data["startpeaks"]
options.cautionhours = await _get_existing_param(conf, "cautionhours", [])
options.nonhours = await _get_existing_param(conf, "nonhours", [])
Expand Down
31 changes: 3 additions & 28 deletions custom_components/peaqev/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,20 @@
import logging
from datetime import timedelta

from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.core import HomeAssistant
from peaqevcore.models.hub.const import CHARGERDONE

from .const import (
import custom_components.peaqev.sensors.create_sensor_helper as helper
from custom_components.peaqev.const import (
DOMAIN)

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities): # pylint:disable=unused-argument
hub = hass.data[DOMAIN]["hub"]

peaqsensors = []

peaqsensors.append(PeaqBinarySensorDone(hub))
peaqsensors = helper.gather_binary_sensors(hub)
async_add_entities(peaqsensors)

SCAN_INTERVAL = timedelta(seconds=4)


class PeaqBinarySensorDone(BinarySensorEntity):
def __init__(self, hub) -> None:
"""Initialize a Peaq Binary sensor."""
self._attr_name = f"{hub.hubname} {CHARGERDONE}"
self._hub = hub
self._attr_device_class = "none"

@property
def unique_id(self):
return f"{DOMAIN.lower()}_{self._attr_name}"

@property
def device_info(self):
return {"identifiers": {(DOMAIN, self._hub.hub_id)}}

@property
def is_on(self) -> bool:
try:
return self._hub.sensors.charger_done.value
except:
_LOGGER.debug("Binarysensor_charger_done could not get state from hub.")
return False
2 changes: 1 addition & 1 deletion custom_components/peaqev/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"documentation": "https://github.com/elden1337/hass-peaq",
"issue_tracker": "https://github.com/elden1337/hass-peaq/issues",
"requirements": [
"peaqevcore==12.1.4"
"peaqevcore==12.1.6"
],
"codeowners": [
"@elden1337"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import time
from abc import abstractmethod
from datetime import datetime, timedelta

from peaqevcore.models.chargecontroller_states import ChargeControllerStates

from custom_components.peaqev.peaqservice.chargertypes.models.chargertypes_enum import ChargerType
from custom_components.peaqev.peaqservice.util.constants import CHARGERCONTROLLER

Expand Down Expand Up @@ -51,7 +53,7 @@ def status(self) -> str:
case ChargerType.Outlet:
ret = self._get_status_outlet()
case ChargerType.NoCharger:
ret = self._get_status_chargerless()
ret = self._get_status_no_charger()
case _:
ret = self._get_status()
self._status_type = ret
Expand Down Expand Up @@ -168,19 +170,21 @@ def _get_status(self) -> ChargeControllerStates:
_LOGGER.error(f"Chargecontroller returned faulty state. Charger reported {self._hub.sensors.chargerobject.value} as state.")
return ret

def _get_status_chargerless(self) -> ChargeControllerStates:
def _get_status_no_charger(self) -> ChargeControllerStates:
ret = ChargeControllerStates.Error
update_timer = True
free_charge = self._hub.sensors.locale.data.free_charge(self._hub.sensors.locale.data)
if self._hub.sensors.charger_enabled.value is False:
ret = ChargeControllerStates.Disabled
elif self._hub.sensors.power.killswitch.is_dead:
ret = ChargeControllerStates.Error
# elif self._hub.sensors.power.killswitch.is_dead:
# ret = ChargeControllerStates.Error
elif datetime.now().hour in self._hub.non_hours and free_charge is False and self._hub.timer.is_override is False:
ret = ChargeControllerStates.Stop
elif self._hub.svk.should_stop:
"""interim fix for svk peak hours"""
ret = ChargeControllerStates.Stop
else:
ret = self._get_status_connected()
if update_timer is True:
self.latest_charger_start = time.time()
return ret
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from homeassistant.core import HomeAssistant
from peaqevcore.hub.hub_options import HubOptions
from peaqevcore.models.chargertype.servicecalls_dto import ServiceCallsDTO
from peaqevcore.models.chargertype.servicecalls_options import ServiceCallsOptions
from peaqevcore.services.chargertype.chargertype_base import ChargerBase

_LOGGER = logging.getLogger(__name__)
Expand All @@ -10,6 +12,18 @@ class NoCharger(ChargerBase):
def __init__(self, hass: HomeAssistant, huboptions: HubOptions, chargertype):
self._type = chargertype

self._set_servicecalls(
domain=self.domain_name,
model=ServiceCallsDTO(
on=self.call_on,
off=self.call_off,
pause=self.call_pause,
resume=self.call_resume,
update_current=self.call_update_current
),
options=self.servicecalls_options
)

@property
def type(self):
"""type returns the implemented chargertype."""
Expand All @@ -18,4 +32,12 @@ def type(self):
@property
def domain_name(self) -> str:
"""declare the domain name as stated in HA"""
return "No charger"
return "No charger"

@property
def servicecalls_options(self) -> ServiceCallsOptions:
return ServiceCallsOptions(
allowupdatecurrent=False,
update_current_on_termination=False,
switch_controls_charger=False
)
16 changes: 9 additions & 7 deletions custom_components/peaqev/peaqservice/hub/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,15 @@ def is_initialized(self) -> bool:
def _set_chargingtracker_entities(self) -> list:
if self.chargertype.type is ChargerType.NoCharger:
return []
ret = [
self.sensors.chargerobject_switch.entity,
self.sensors.carpowersensor.entity,
self.sensors.charger_enabled.entity,
self.sensors.charger_done.entity,
f"sensor.{self.domain}_{ex.nametoid(CHARGERCONTROLLER)}",
]
ret = [f"sensor.{self.domain}_{ex.nametoid(CHARGERCONTROLLER)}"]
if hasattr(self.sensors, "chargerobject_switch"):
ret.append(self.sensors.chargerobject_switch.entity)
if hasattr(self.sensors, "carpowersensor"):
ret.append(self.sensors.carpowersensor.entity)
if hasattr(self.sensors, "charger_enabled"):
ret.append(self.sensors.charger_enabled.entity)
if hasattr(self.sensors, "charger_done"):
ret.append(self.sensors.charger_done.entity)

if self.chargertype.type is not ChargerType.Outlet:
ret.append(self.sensors.chargerobject.entity)
Expand Down
14 changes: 9 additions & 5 deletions custom_components/peaqev/peaqservice/hub/hub_initializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ def check(self):
return True

init_types = {
InitializerTypes.Hours: self.parent.hours.is_initialized,
InitializerTypes.CarPowerSensor: self.parent.sensors.carpowersensor.is_initialized,
InitializerTypes.ChargerObjectSwitch: self.parent.sensors.chargerobject_switch.is_initialized,
InitializerTypes.Power: self.parent.sensors.power.is_initialized,
InitializerTypes.ChargerObject: self.parent.sensors.chargerobject.is_initialized
InitializerTypes.Hours: self.parent.hours.is_initialized
}
if hasattr(self.parent.sensors, "carpowersensor"):
init_types[InitializerTypes.CarPowerSensor] = self.parent.sensors.carpowersensor.is_initialized
if hasattr(self.parent.sensors, "chargerobject_switch"):
init_types[InitializerTypes.ChargerObjectSwitch] = self.parent.sensors.chargerobject_switch.is_initialized
if hasattr(self.parent.sensors, "power"):
init_types[InitializerTypes.Power] = self.parent.sensors.power.is_initialized
if hasattr(self.parent.sensors, "chargerobject"):
init_types[InitializerTypes.ChargerObject] = self.parent.sensors.chargerobject.is_initialized

if all(init_types.values()):
self._initialized = True
Expand Down
52 changes: 38 additions & 14 deletions custom_components/peaqev/peaqservice/hub/state_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ async def update_sensor(self, entity, value):
if self._hub.options.peaqev_lite is True:
await self._update_sensor_lite(entity, value)
update_session = False
elif self._hub.chargertype.type is ChargerType.NoCharger:
update_session = await self._update_sensor_no_charger(entity, value)
else:
update_session = await self._update_sensor_regular(entity, value)
if self._hub.options.price.price_aware is True:
Expand All @@ -26,7 +28,7 @@ async def update_sensor(self, entity, value):
self.latest_nordpool_update = time.time()
await self._hub.nordpool.update_nordpool()
await self._handle_sensor_attribute()
if self._hub.charger.session_active and update_session:
if self._hub.charger.session_active and update_session and hasattr(self._hub.sensors, "carpowersensor"):
self._hub.charger.session.session_energy = self._hub.sensors.carpowersensor.value
if self._hub.options.price.price_aware is True:
self._hub.charger.session.session_price = float(self._hub.nordpool.state)
Expand Down Expand Up @@ -93,6 +95,27 @@ async def _update_sensor_regular(self, entity, value) -> bool:
update_session = True
return update_session

async def _update_sensor_no_charger(self, entity, value) -> bool:
update_session = False
match entity:
case self._hub.configpower_entity:
self._hub.sensors.power.update(
carpowersensor_value=0,
config_sensor_value=value
)
update_session = True
self._hub.power_canary.total_power = self._hub.sensors.power.total.value
case self._hub.sensors.totalhourlyenergy.entity:
await self._update_total_energy_and_peak(value)
case self._hub.sensors.powersensormovingaverage.entity:
self._hub.sensors.powersensormovingaverage.value = value
case self._hub.sensors.powersensormovingaverage24.entity:
self._hub.sensors.powersensormovingaverage24.value = value
case self._hub.nordpool.nordpool_entity:
await self._hub.nordpool.update_nordpool()
update_session = True
return update_session

async def _handle_outlet_updates(self):
if self._hub.chargertype.domainname is ChargerType.Outlet:
old_state = self._hub.sensors.chargerobject.value
Expand All @@ -107,19 +130,20 @@ async def _handle_outlet_updates(self):
_LOGGER.debug(f"smartoutlet is now {self._hub.sensors.chargerobject.value}")

async def _handle_sensor_attribute(self) -> None:
if self._hub.sensors.carpowersensor.use_attribute:
entity = self._hub.sensors.carpowersensor
try:
val = self._hub.hass.states.get(entity.entity).attributes.get(entity.attribute)
if val is not None:
self._hub.sensors.carpowersensor.value = val
self._hub.sensors.power.update(
carpowersensor_value=self._hub.sensors.carpowersensor.value,
config_sensor_value=None
)
return
except Exception as e:
_LOGGER.debug(f"Unable to get attribute-state for {entity.entity}|{entity.attribute}. {e}")
if hasattr(self._hub.sensors, "carpowersensor"):
if self._hub.sensors.carpowersensor.use_attribute:
entity = self._hub.sensors.carpowersensor
try:
val = self._hub.hass.states.get(entity.entity).attributes.get(entity.attribute)
if val is not None:
self._hub.sensors.carpowersensor.value = val
self._hub.sensors.power.update(
carpowersensor_value=self._hub.sensors.carpowersensor.value,
config_sensor_value=None
)
return
except Exception as e:
_LOGGER.debug(f"Unable to get attribute-state for {entity.entity}|{entity.attribute}. {e}")

async def _update_chargerobject_switch(self, value) -> None:
self._hub.sensors.chargerobject_switch.value = value
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from dataclasses import dataclass, field

from peaqevcore.models.const import CURRENTS_THREEPHASE_1_32, CURRENTS_THREEPHASE_1_16, CURRENTS_ONEPHASE_1_16, \
Expand All @@ -10,7 +12,7 @@ class PowerCanaryModel:
warning_threshold: float
cutoff_threshold: float
fuse: Fuses
allow_amp_adjustment: bool
allow_amp_adjustment: bool | None
threephase_amps: dict = field(init=False)
onephase_amps: dict = field(init=False)
fuse_max: int = field(init=False)
Expand All @@ -31,7 +33,11 @@ def is_valid(self) -> bool:
if self.fuse_max == 0:
return True
else:
return self.fuse_max == self.FUSES_DICT[self.fuse]
return all(
[
self.fuse_max == self.FUSES_DICT[self.fuse],
self.allow_amp_adjustment is not None
])

FUSES_DICT = {
Fuses.FUSE_3_16: 11000,
Expand Down
30 changes: 20 additions & 10 deletions custom_components/peaqev/sensors/create_sensor_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,32 @@
import custom_components.peaqev.peaqservice.util.extensionmethods as ex
from custom_components.peaqev.const import (
DOMAIN)
from custom_components.peaqev.peaqservice.chargertypes.models.chargertypes_enum import ChargerType
from custom_components.peaqev.peaqservice.util.constants import (
CONSUMPTION_TOTAL_NAME,
CONSUMPTION_INTEGRAL_NAME
)
from custom_components.peaqev.sensors.average_sensor import PeaqAverageSensor
from custom_components.peaqev.sensors.integration_sensor import PeaqIntegrationSensor
from custom_components.peaqev.sensors.money_sensor import PeaqMoneySensor
from custom_components.peaqev.sensors.peaq_binary_sensor import PeaqBinarySensorDone
from custom_components.peaqev.sensors.peaq_sensor import PeaqSensor
from custom_components.peaqev.sensors.power_sensor import (PeaqPowerSensor, PeaqAmpSensor, PeaqHousePowerSensor)
from custom_components.peaqev.sensors.powercanary_sensor import PowerCanaryStatusSensor, PowerCanaryPercentageSensor, \
PowerCanaryMaxAmpSensor
from custom_components.peaqev.sensors.prediction_sensor import PeaqPredictionSensor
from custom_components.peaqev.sensors.session_sensor import PeaqSessionSensor, PeaqSessionCostSensor
from custom_components.peaqev.sensors.threshold_sensor import PeaqThresholdSensor
from custom_components.peaqev.peaqservice.chargertypes.models.chargertypes_enum import ChargerType

_LOGGER = logging.getLogger(__name__)

async def gather_binary_sensors(hub) -> list:

ret = []
if hub.chargertype.type != ChargerType.NoCharger.value:
ret.append(PeaqBinarySensorDone(hub))
return ret

async def gather_sensors(hub, config) -> list:
ret = []

Expand Down Expand Up @@ -53,21 +61,23 @@ async def gather_sensors(hub, config) -> list:

if hub.options.price.price_aware is True:
ret.append(PeaqMoneySensor(hub, config.entry_id))
ret.append(PeaqSessionCostSensor(hub, config.entry_id))
if hub.chargertype.type != ChargerType.NoCharger:
ret.append(PeaqSessionCostSensor(hub, config.entry_id))
return ret

async def gather_integration_sensors(hub, entry_id):
ret = []

if hub.options.powersensor_includes_car is True or hub.chargertype.type == ChargerType.NoCharger:
ret.append(
PeaqIntegrationSensor(
hub,
f"sensor.{DOMAIN}_{hub.sensors.power.house.id}",
f"{ex.nametoid(CONSUMPTION_INTEGRAL_NAME)}",
entry_id
if hub.options.powersensor_includes_car is True or hub.chargertype.type is ChargerType.NoCharger:
if hub.chargertype.type is not ChargerType.NoCharger:
ret.append(
PeaqIntegrationSensor(
hub,
f"sensor.{DOMAIN}_{hub.sensors.power.house.id}",
f"{ex.nametoid(CONSUMPTION_INTEGRAL_NAME)}",
entry_id
)
)
)
ret.append(
PeaqIntegrationSensor(
hub,
Expand Down
Loading

0 comments on commit 2ebca37

Please sign in to comment.