Skip to content

Commit

Permalink
Merge pull request #170 from tijsverkoyen/169-charging-station
Browse files Browse the repository at this point in the history
169 charging station
  • Loading branch information
tijsverkoyen authored Jul 11, 2024
2 parents 5fe02f6 + ec38136 commit 15c0e50
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 0 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,20 @@ It has some extra entities that can be used in automations:
* **Basic State Binary Sensor**, The state is according the state of all assigned players as configured for that action.
### Easee Chargingstation
__Remark:__ This device is not documented/supported by Niko.
This is exposed as a switch.
#### Entities
* **Charging Mode Select**, (only if supported), select the charging mode.
* **Charging Status Enum sensor**, (only if supported), The current charging status.
* **Electrical Power sensor**, (only if supported).
* **EV Status Enum sensor**, (only if supported).
* **Coupling Status Enum Sensor**, (only if supported), the connectivity status of the system.
## Not yet supported
* Sonos Speaker
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from homeassistant.components.select import SelectEntity

from ..nhccoco.devices.easee_chargingstation import CocoEaseeChargingstation
from .nhc_entity import NHCBaseEntity


class Nhc2EaseeChargingstationChargingModeEntity(NHCBaseEntity, SelectEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoEaseeChargingstation, hub, gateway):
"""Initialize a select entity."""
super().__init__(device_instance, hub, gateway)

self._attr_unique_id = device_instance.uuid + '_charging_mode'

self._attr_options = self._device.possible_charging_modes

@property
def name(self) -> str:
return 'Charging Mode'

@property
def current_option(self) -> str:
return self._device.charging_mode

async def async_select_option(self, option: str) -> None:
self._device.set_charging_mode(self._gateway, option)
self.schedule_update_ha_state()
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass

from ..nhccoco.devices.easee_chargingstation import CocoEaseeChargingstation
from .nhc_entity import NHCBaseEntity


class Nhc2EaseeChargingstationChargingStatusEntity(NHCBaseEntity, SensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoEaseeChargingstation, hub, gateway):
"""Initialize a sensor."""
super().__init__(device_instance, hub, gateway)

self._attr_unique_id = device_instance.uuid + '_charging_status'

self._attr_device_class = SensorDeviceClass.ENUM
self._attr_options = self._device.possible_charging_status
self._attr_native_value = self._device.charging_status

@property
def name(self) -> str:
return 'Charging Status'

@property
def state(self) -> str:
return self._device.charging_status
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass
from homeassistant.helpers.entity import EntityCategory

from ..nhccoco.devices.easee_chargingstation import CocoEaseeChargingstation
from .nhc_entity import NHCBaseEntity


class Nhc2EaseeChargingstationCouplingStatusEntity(NHCBaseEntity, SensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoEaseeChargingstation, hub, gateway):
"""Initialize a sensor."""
super().__init__(device_instance, hub, gateway)

self._attr_unique_id = device_instance.uuid + '_coupling_status'

self._attr_device_class = SensorDeviceClass.ENUM
self._attr_options = self._device.possible_coupling_status
self._attr_native_value = self._device.coupling_status
self._attr_entity_category = EntityCategory.DIAGNOSTIC

@property
def name(self) -> str:
return 'Coupling Status'

@property
def state(self) -> str:
return self._device.coupling_status
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass, SensorStateClass
from homeassistant.const import UnitOfPower

from ..nhccoco.devices.easee_chargingstation import CocoEaseeChargingstation
from .nhc_entity import NHCBaseEntity


class Nhc2EaseeChargingstationElectricalPowerEntity(NHCBaseEntity, SensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoEaseeChargingstation, hub, gateway):
"""Initialize a sensor."""
super().__init__(device_instance, hub, gateway)

self._attr_unique_id = device_instance.uuid + '_electrical_power'

self._attr_device_class = SensorDeviceClass.POWER
self._attr_native_value = self._device.electrical_power
self._attr_native_unit_of_measurement = UnitOfPower.WATT
self._attr_state_class = SensorStateClass.MEASUREMENT
self._attr_suggested_display_precision = 2
self._attr_native_precision = 2

@property
def name(self) -> str:
return 'Electrical Power'

@property
def native_value(self) -> float:
return self._device.electrical_power
26 changes: 26 additions & 0 deletions custom_components/nhc2/entities/easee_chargingstation_ev_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass

from ..nhccoco.devices.easee_chargingstation import CocoEaseeChargingstation
from .nhc_entity import NHCBaseEntity


class Nhc2EaseeChargingstationEvStatusEntity(NHCBaseEntity, SensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoEaseeChargingstation, hub, gateway):
"""Initialize a sensor."""
super().__init__(device_instance, hub, gateway)

self._attr_unique_id = device_instance.uuid + '_ev_status'

self._attr_device_class = SensorDeviceClass.ENUM
self._attr_options = self._device.possible_ev_status
self._attr_native_value = self._device.ev_status

@property
def name(self) -> str:
return 'EV Status'

@property
def state(self) -> str:
return self._device.ev_status
31 changes: 31 additions & 0 deletions custom_components/nhc2/entities/easee_chargingstation_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from homeassistant.components.switch import SwitchEntity, SwitchDeviceClass

from ..nhccoco.devices.easee_chargingstation import CocoEaseeChargingstation
from .nhc_entity import NHCBaseEntity


class Nhc2EaseeChargingstationStatusEntity(NHCBaseEntity, SwitchEntity):
_attr_has_entity_name = True
_attr_name = None

def __init__(self, device_instance: CocoEaseeChargingstation, hub, gateway):
"""Initialize a switch."""
super().__init__(device_instance, hub, gateway)

self._attr_unique_id = self._device.uuid

@property
def device_class(self) -> str:
return SwitchDeviceClass.SWITCH

@property
def is_on(self) -> bool:
return self._device.is_status_on

async def async_turn_on(self):
self._device.turn_on(self._gateway)
self.schedule_update_ha_state()

async def async_turn_off(self):
self._device.turn_off(self._gateway)
self.schedule_update_ha_state()
2 changes: 2 additions & 0 deletions custom_components/nhc2/nhccoco/coco.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .devices.condition_action import CocoConditionAction
from .devices.controller import CocoController
from .devices.dimmer_action import CocoDimmerAction
from .devices.easee_chargingstation import CocoEaseeChargingstation
from .devices.electricalheating_action import CocoElectricalheatingAction
from .devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter
from .devices.fan_action import CocoFanAction
Expand Down Expand Up @@ -356,6 +357,7 @@ def _process_devices_list(self, response):
'CocoGasCentralmeter',
'CocoGenericAudiocontrol',
'CocoGenericBrick',
'CocoGenericChargingstation',
'CocoGenericGatewayfw',
'CocoGenericLightsensor',
'CocoGenericRadio',
Expand Down
3 changes: 3 additions & 0 deletions custom_components/nhc2/nhccoco/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@
PROPERTY_CALL_PENDING = 'CallPending'
PROPERTY_CALL_PENDING_VALUE_TRUE = 'True'
PROPERTY_CALL_STATUS_01 = 'CallStatus01'
PROPERTY_CHARGING_MODE = 'ChargingMode'
PROPERTY_CHARGING_STATUS = 'ChargingStatus'
PROPERTY_CO2 = 'CO2'
PROPERTY_COOLING_MODE = 'CoolingMode'
PROPERTY_COOLING_MODE_VALUE_TRUE = 'True'
Expand All @@ -142,6 +144,7 @@
PROPERTY_ELECTRICAL_POWER_PRODUCTION_THRESHOLD_EXCEEDED_VALUE_TRUE = 'True'
PROPERTY_ELECTRICAL_POWER_SELF_CONSUMPTION = 'ElectricalPowerSelfConsumption'
PROPERTY_ELECTRICAL_POWER_TO_GRID = 'ElectricalPowerToGrid'
PROPERTY_EV_STATUS = 'EVStatus'
PROPERTY_FAN_SPEED = 'FanSpeed'
PROPERTY_FAN_SPEED_VALUE_AUTO = 'Auto'
PROPERTY_FAN_SPEED_VALUE_BOOST = 'Boost'
Expand Down
83 changes: 83 additions & 0 deletions custom_components/nhc2/nhccoco/devices/easee_chargingstation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from ..const import PROPERTY_CHARGING_MODE, PROPERTY_CHARGING_STATUS, PROPERTY_COUPLING_STATUS, \
PROPERTY_ELECTRICAL_POWER, PROPERTY_EV_STATUS, PROPERTY_STATUS, PROPERTY_STATUS_VALUE_OFF, PROPERTY_STATUS_VALUE_ON
from ..helpers import to_float_or_none
from .device import CoCoDevice


class CocoEaseeChargingstation(CoCoDevice):
@property
def supports_status(self) -> bool:
return self.has_property(PROPERTY_STATUS)

@property
def status(self) -> str:
return self.extract_property_value(PROPERTY_STATUS)

@property
def is_status_on(self) -> bool:
return self.status == PROPERTY_STATUS_VALUE_ON

@property
def charging_mode(self) -> str:
return self.extract_property_value(PROPERTY_CHARGING_MODE)

@property
def possible_charging_modes(self) -> list[str]:
return self.extract_property_definition_description_choices(PROPERTY_CHARGING_MODE)

@property
def supports_charging_mode(self) -> bool:
return self.has_property(PROPERTY_CHARGING_MODE)

@property
def charging_status(self) -> str:
return self.extract_property_value(PROPERTY_CHARGING_STATUS)

@property
def possible_charging_status(self) -> list:
return self.extract_property_definition_description_choices(PROPERTY_CHARGING_STATUS)

@property
def supports_charging_status(self) -> bool:
return self.has_property(PROPERTY_CHARGING_STATUS)

@property
def coupling_status(self) -> str:
return self.extract_property_value(PROPERTY_COUPLING_STATUS)

@property
def possible_coupling_status(self) -> list:
return self.extract_property_definition_description_choices(PROPERTY_COUPLING_STATUS)

@property
def supports_coupling_status(self) -> bool:
return self.has_property(PROPERTY_COUPLING_STATUS)

@property
def ev_status(self) -> str:
return self.extract_property_value(PROPERTY_EV_STATUS)

@property
def possible_ev_status(self) -> list:
return self.extract_property_definition_description_choices(PROPERTY_EV_STATUS)

@property
def supports_ev_status(self) -> bool:
return self.has_property(PROPERTY_EV_STATUS)

@property
def electrical_power(self) -> float:
return to_float_or_none(self.extract_property_value(PROPERTY_ELECTRICAL_POWER))

@property
def supports_electrical_power(self) -> bool:
return self.has_property(PROPERTY_ELECTRICAL_POWER)

def turn_on(self, gateway):
gateway.add_device_control(self.uuid, PROPERTY_STATUS, PROPERTY_STATUS_VALUE_ON)

def turn_off(self, gateway):
gateway.add_device_control(self.uuid, PROPERTY_STATUS, PROPERTY_STATUS_VALUE_OFF)

def set_charging_mode(self, gateway, charging_mode: str):
gateway.add_device_control(self.uuid, PROPERTY_CHARGING_MODE, charging_mode)
12 changes: 12 additions & 0 deletions custom_components/nhc2/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

from .nhccoco.coco import CoCo

from .entities.easee_chargingstation_charging_mode import Nhc2EaseeChargingstationChargingModeEntity
from .entities.generic_domestichotwaterunit_program import Nhc2GenericDomestichotwaterunitProgramEntity
from .nhccoco.devices.easee_chargingstation import CocoEaseeChargingstation
from .nhccoco.devices.generic_domestichotwaterunit import CocoGenericDomestichotwaterunit

from .const import DOMAIN, KEY_GATEWAY
Expand All @@ -32,3 +34,13 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(Nhc2GenericDomestichotwaterunitProgramEntity(device_instance, hub, gateway))

async_add_entities(entities)

device_instances = gateway.get_device_instances(CocoEaseeChargingstation)
_LOGGER.info('→ Found %s Easee Chargingstation Implementation (undocumented)', len(device_instances))
if len(device_instances) > 0:
entities = []
for device_instance in device_instances:
if device_instance.supports_charging_mode:
entities.append(Nhc2EaseeChargingstationChargingModeEntity(device_instance, hub, gateway))

async_add_entities(entities)
21 changes: 21 additions & 0 deletions custom_components/nhc2/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
from .entities.audiocontrol_action_speaker import Nhc2AudiocontrolActionSpeakerEntity
from .entities.alarms_action_basicstate import Nhc2AlarmsActionBasicStateEntity
from .entities.bellbutton_action_basicstate import Nhc2BellbuttonActionBasicStateEntity
from .entities.easee_chargingstation_charging_status import Nhc2EaseeChargingstationChargingStatusEntity
from .entities.easee_chargingstation_coupling_status import Nhc2EaseeChargingstationCouplingStatusEntity
from .entities.easee_chargingstation_electrical_power import Nhc2EaseeChargingstationElectricalPowerEntity
from .entities.easee_chargingstation_ev_status import Nhc2EaseeChargingstationEvStatusEntity
from .entities.electricity_clamp_centralmeter_electrical_power import \
Nhc2ElectricityClampCentralmeterElectricalPowerEntity
from .entities.electricity_clamp_centralmeter_electrical_power_consumption import \
Expand Down Expand Up @@ -62,6 +66,7 @@
from .nhccoco.devices.audiocontrol_action import CocoAudiocontrolAction
from .nhccoco.devices.alarms_action import CocoAlarmsAction
from .nhccoco.devices.bellbutton_action import CocoBellbuttonAction
from .nhccoco.devices.easee_chargingstation import CocoEaseeChargingstation
from .nhccoco.devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter
from .nhccoco.devices.gate_action import CocoGateAction
from .nhccoco.devices.garagedoor_action import CocoGaragedoorAction
Expand Down Expand Up @@ -392,3 +397,19 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(Nhc2GenericInverterElectricalPowerProductionEntity(device_instance, hub, gateway))

async_add_entities(entities)

device_instances = gateway.get_device_instances(CocoEaseeChargingstation)
_LOGGER.info('→ Found %s Easee Chargingstation Implementations (undocumented)', len(device_instances))
if len(device_instances) > 0:
entities = []
for device_instance in device_instances:
if device_instance.supports_coupling_status:
entities.append(Nhc2EaseeChargingstationCouplingStatusEntity(device_instance, hub, gateway))
if device_instance.supports_electrical_power:
entities.append(Nhc2EaseeChargingstationElectricalPowerEntity(device_instance, hub, gateway))
if device_instance.supports_ev_status:
entities.append(Nhc2EaseeChargingstationEvStatusEntity(device_instance, hub, gateway))
if device_instance.supports_charging_status:
entities.append(Nhc2EaseeChargingstationChargingStatusEntity(device_instance, hub, gateway))

async_add_entities(entities)
Loading

0 comments on commit 15c0e50

Please sign in to comment.