Skip to content

Commit

Permalink
Implemented Electricity Metering module
Browse files Browse the repository at this point in the history
  • Loading branch information
tijsverkoyen committed Jan 27, 2023
1 parent 3da4610 commit f8bfe50
Show file tree
Hide file tree
Showing 13 changed files with 376 additions and 48 deletions.
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,19 @@ This is the energy metering linked to a zigbee smart plug. The smart plug itself

The totals are not available as they are not exposed by the API.

### Energy Home
### Electricity Metering module (with clamp) (untested)

#### Entities

* **Electrical Power Sensor**, the realtime power usage in W. Possitive means power consumed, negative is power
produced.
* **Report Instant Usage Binary Sensor**, indicates if the Electrical Power is received. When disabled, it will
automatically be enabled.
* **Flow Sensor**. Producer or Consumer
* **Segment Sensor**. Central or Subsegment
* **Clamp Type Sensor**. 63A or 120A

### Energy Home (untested)

#### Entities

Expand Down Expand Up @@ -187,7 +199,6 @@ The totals are not available as they are not exposed by the API.
* Generic Zigbee Smart plug
* Sonos Speaker
* Bose Speaker
* Electricity Metering module (with clamp)
* Generic Ventilation Implementation
* Generic Heating/Cooling Implementation
* Generic Warm Water Implementation
Expand Down
12 changes: 12 additions & 0 deletions custom_components/nhc2/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from .entities.alloff_action_active import Nhc2AlloffActionActiveEntity
from .entities.alloff_action_basicstate import Nhc2AlloffActionBasicStateEntity
from .entities.dimmer_action_alligned import Nhc2DimmerActionAlignedEntity
from .entities.electricity_clamp_centralmeter_report_instant_usage import \
Nhc2ElectricityClampCentralmeterReportInstantUsageEntity
from .entities.generic_energyhome_electrical_power_production_threshold_exceeded import \
Nhc2GenericEnergyhomeElectricalPowerProductionThresholdExceededEntity
from .entities.generic_energyhome_report_instant_usage import Nhc2GenericEnergyhomeReportInstantUsageEntity
Expand All @@ -22,6 +24,7 @@
from .nhccoco.devices.accesscontrol_action import CocoAccesscontrolAction
from .nhccoco.devices.alloff_action import CocoAlloffAction
from .nhccoco.devices.dimmer_action import CocoDimmerAction
from .nhccoco.devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter
from .nhccoco.devices.gate_action import CocoGateAction
from .nhccoco.devices.generic_energyhome import CocoGenericEnergyhome
from .nhccoco.devices.hvacthermostat_hvac import CocoHvacthermostatHvac
Expand Down Expand Up @@ -108,6 +111,15 @@ async def async_setup_entry(hass, config_entry, async_add_entities):

async_add_entities(entities)

device_instances = gateway.get_device_instances(CocoElectricityClampCentralmeter)
_LOGGER.info('→ Found %s Electricity Metering modules', len(device_instances))
if len(device_instances) > 0:
entities = []
for device_instance in device_instances:
entities.append(Nhc2ElectricityClampCentralmeterReportInstantUsageEntity(device_instance, hub, gateway))

async_add_entities(entities)

device_instances = gateway.get_device_instances(CocoGenericEnergyhome)
_LOGGER.info('→ Found %s Energy Home\'s', len(device_instances))
if len(device_instances) > 0:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass
from homeassistant.helpers.entity import EntityCategory

from ..const import DOMAIN, BRAND

from ..nhccoco.devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter


class Nhc2ElectricityClampCentralmeterClampTypeEntity(SensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoElectricityClampCentralmeter, hub, gateway):
"""Initialize a binary sensor."""
self._device = device_instance
self._hub = hub
self._gateway = gateway

self._device.after_change_callbacks.append(self.on_change)

self._attr_available = self._device.is_online
self._attr_unique_id = device_instance.uuid + '_clamp_type'
self._attr_should_poll = False

self._attr_device_class = SensorDeviceClass.ENUM
self._attr_options = self._device.possible_clamp_types
self._attr_native_value = self._device.clamp_type
self._attr_state_class = None
self._attr_entity_category = EntityCategory.DIAGNOSTIC

@property
def name(self) -> str:
return 'Electricity Metering Module Segment'

@property
def device_info(self):
"""Return the device info."""
return {
'identifiers': {
(DOMAIN, self._device.uuid)
},
'name': self._device.name,
'manufacturer': BRAND,
'model': str.title(f'{self._device.model} ({self._device.type})'),
'via_device': self._hub
}

def on_change(self):
self.schedule_update_ha_state()
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass, SensorStateClass
from homeassistant.const import UnitOfPower

from ..const import DOMAIN, BRAND

from ..nhccoco.devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter

class Nhc2ElectricityClampCentralmeterElectricalPowerEntity(SensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoElectricityClampCentralmeter, hub, gateway):
"""Initialize a binary sensor."""
self._device = device_instance
self._hub = hub
self._gateway = gateway

self._device.after_change_callbacks.append(self.on_change)

self._attr_available = self._device.is_online
self._attr_unique_id = device_instance.uuid + '_electrical_power'
self._attr_should_poll = False

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

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

@property
def device_info(self):
"""Return the device info."""
return {
'identifiers': {
(DOMAIN, self._device.uuid)
},
'name': self._device.name,
'manufacturer': BRAND,
'model': str.title(f'{self._device.model} ({self._device.type})'),
'via_device': self._hub
}

@property
def state(self) -> float:
return self._device.electrical_power

def on_change(self):
self.schedule_update_ha_state()
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass
from homeassistant.helpers.entity import EntityCategory

from ..const import DOMAIN, BRAND

from ..nhccoco.devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter


class Nhc2ElectricityClampCentralmeterFlowEntity(SensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoElectricityClampCentralmeter, hub, gateway):
"""Initialize a binary sensor."""
self._device = device_instance
self._hub = hub
self._gateway = gateway

self._device.after_change_callbacks.append(self.on_change)

self._attr_available = self._device.is_online
self._attr_unique_id = device_instance.uuid + '_flow'
self._attr_should_poll = False

self._attr_device_class = SensorDeviceClass.ENUM
self._attr_options = self._device.possible_flows
self._attr_native_value = self._device.flow
self._attr_state_class = None
self._attr_entity_category = EntityCategory.DIAGNOSTIC

@property
def name(self) -> str:
return 'Electricity Metering Module Flow'

@property
def device_info(self):
"""Return the device info."""
return {
'identifiers': {
(DOMAIN, self._device.uuid)
},
'name': self._device.name,
'manufacturer': BRAND,
'model': str.title(f'{self._device.model} ({self._device.type})'),
'via_device': self._hub
}

def on_change(self):
self.schedule_update_ha_state()
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.helpers.entity import EntityCategory

from ..const import DOMAIN, BRAND

from ..nhccoco.devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter

import logging

_LOGGER = logging.getLogger(__name__)


class Nhc2ElectricityClampCentralmeterReportInstantUsageEntity(BinarySensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoElectricityClampCentralmeter, hub, gateway):
"""Initialize a binary sensor."""
self._device = device_instance
self._hub = hub
self._gateway = gateway

self._device.after_change_callbacks.append(self.on_change)

self._attr_available = self._device.is_online
self._attr_unique_id = device_instance.uuid + '_report_instant_usage'
self._attr_should_poll = False

self._attr_state = self._device.is_report_instant_usage
self._attr_state_class = None
self._attr_entity_category = EntityCategory.DIAGNOSTIC

@property
def name(self) -> str:
return 'Report Instant Usage'

@property
def device_info(self):
"""Return the device info."""
return {
'identifiers': {
(DOMAIN, self._device.uuid)
},
'name': self._device.name,
'manufacturer': BRAND,
'model': str.title(f'{self._device.model} ({self._device.type})'),
'via_device': self._hub
}

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

def on_change(self):
# Re-enable reporting when it is turned off
if self._device.is_report_instant_usage is False:
_LOGGER.debug(f'{self.name} re-enabled')
self._device.enable_report_instant_usage(self._gateway)

self.schedule_update_ha_state()
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass
from homeassistant.helpers.entity import EntityCategory

from ..const import DOMAIN, BRAND

from ..nhccoco.devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter


class Nhc2ElectricityClampCentralmeterSegmentEntity(SensorEntity):
_attr_has_entity_name = True

def __init__(self, device_instance: CocoElectricityClampCentralmeter, hub, gateway):
"""Initialize a binary sensor."""
self._device = device_instance
self._hub = hub
self._gateway = gateway

self._device.after_change_callbacks.append(self.on_change)

self._attr_available = self._device.is_online
self._attr_unique_id = device_instance.uuid + '_segment'
self._attr_should_poll = False

self._attr_device_class = SensorDeviceClass.ENUM
self._attr_options = self._device.possible_segments
self._attr_native_value = self._device.segment
self._attr_state_class = None
self._attr_entity_category = EntityCategory.DIAGNOSTIC

@property
def name(self) -> str:
return 'Electricity Metering Module Segment'

@property
def device_info(self):
"""Return the device info."""
return {
'identifiers': {
(DOMAIN, self._device.uuid)
},
'name': self._device.name,
'manufacturer': BRAND,
'model': str.title(f'{self._device.model} ({self._device.type})'),
'via_device': self._hub
}

def on_change(self):
self.schedule_update_ha_state()
1 change: 1 addition & 0 deletions custom_components/nhc2/nhccoco/coco.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .devices.alarms_action import CocoAlarmsAction
from .devices.alloff_action import CocoAlloffAction
from .devices.dimmer_action import CocoDimmerAction
from .devices.electricity_clamp_centralmeter import CocoElectricityClampCentralmeter
from .devices.fan_action import CocoFanAction
from .devices.garagedoor_action import CocoGaragedoorAction
from .devices.gate_action import CocoGateAction
Expand Down
15 changes: 0 additions & 15 deletions custom_components/nhc2/nhccoco/coco_device_class.py

This file was deleted.

31 changes: 0 additions & 31 deletions custom_components/nhc2/nhccoco/coco_energy.py

This file was deleted.

9 changes: 9 additions & 0 deletions custom_components/nhc2/nhccoco/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,22 @@

PARAMETER_ACTION = 'Action'
PARAMETER_BUTTON_ID = 'ButtonId'
PARAMETER_CLAMP_TYPE = 'ClampType'
PARAMETER_CLAMP_TYPE_VALUE_63A = '63A'
PARAMETER_CLAMP_TYPE_VALUE_120A = '120A'
PARAMETER_DECLINE_CALL_APPLIED_ON_ALL_DEVICES = 'DeclineCallAppliedOnAllDevices'
PARAMETER_DECLINE_CALL_APPLIED_ON_ALL_DEVICES_VALUE_TRUE = 'True'
PARAMETER_FEEDBACK_ENABLED = 'FeedbackEnabled'
PARAMETER_FEEDBACK_ENABLED_VALUE_TRUE = 'True'
PARAMETER_FLOW = 'Flow'
PARAMETER_FLOW_VALUE_PRODUCER = 'Producer'
PARAMETER_FLOW_VALUE_CONSUMER = 'Consumer'
PARAMETER_MEASURING_ONLY = 'MeasuringOnly'
PARAMETER_MEASURING_ONLY_VALUE_TRUE = 'True'
PARAMETER_RINGTONE = 'Ringtone'
PARAMETER_SEGMENT = 'Segment'
PARAMETER_SEGMENT_VALUE_CENTRAL = 'Central'
PARAMETER_SEGMENT_VALUE_SUBSEGMENT = 'Subsegment'

PROPERTY_ACTION = 'Action'
PROPERTY_ACTION_VALUE_CLOSE = 'Close'
Expand Down
Loading

0 comments on commit f8bfe50

Please sign in to comment.