Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add counters to iskra integration #126046

Merged
merged 4 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions homeassistant/components/iskra/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@
ATTR_PHASE2_CURRENT = "phase2_current"
ATTR_PHASE3_CURRENT = "phase3_current"

# Counters
ATTR_NON_RESETTABLE_COUNTER = "non_resettable_counter_{}"
ATTR_RESETTABLE_COUNTER = "resettable_counter_{}"

# Frequency
ATTR_FREQUENCY = "frequency"
2 changes: 1 addition & 1 deletion homeassistant/components/iskra/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["pyiskra"],
"requirements": ["pyiskra==0.1.8"]
"requirements": ["pyiskra==0.1.11"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please bump in a separate PR

}
59 changes: 59 additions & 0 deletions homeassistant/components/iskra/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from dataclasses import dataclass

from pyiskra.devices import Device
from pyiskra.helper import Counter, CounterType

from homeassistant.components.sensor import (
SensorDeviceClass,
Expand All @@ -17,6 +18,7 @@
UnitOfApparentPower,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfFrequency,
UnitOfPower,
UnitOfReactivePower,
Expand All @@ -27,6 +29,7 @@
from . import IskraConfigEntry
from .const import (
ATTR_FREQUENCY,
ATTR_NON_RESETTABLE_COUNTER,
ATTR_PHASE1_CURRENT,
ATTR_PHASE1_POWER,
ATTR_PHASE1_VOLTAGE,
Expand All @@ -36,6 +39,7 @@
ATTR_PHASE3_CURRENT,
ATTR_PHASE3_POWER,
ATTR_PHASE3_VOLTAGE,
ATTR_RESETTABLE_COUNTER,
ATTR_TOTAL_ACTIVE_POWER,
ATTR_TOTAL_APPARENT_POWER,
ATTR_TOTAL_REACTIVE_POWER,
Expand Down Expand Up @@ -163,6 +167,46 @@ class IskraSensorEntityDescription(SensorEntityDescription):
)


def get_counter_sensor(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we refactor this to return a EntityDescription?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for sure, will do

coordinator: IskraDataUpdateCoordinator,
counter: Counter,
index: int,
entity_name: str,
) -> IskraSensor:
"""Dynamically create IskraSensor object as energy meter's counters are customizable."""

key = entity_name.format(index + 1)
sensor_description = {
"key": key,
"translation_key": key,
"state_class": SensorStateClass.TOTAL_INCREASING,
"native_unit_of_measurement": counter.units,
}

if entity_name == ATTR_NON_RESETTABLE_COUNTER:
sensor_description.update(
{"value_func": lambda device: device.counters.non_resettable[index].value}
)
else:
sensor_description.update(
{"value_func": lambda device: device.counters.resettable[index].value}
)
Copy link
Member

@joostlek joostlek Sep 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part should be like

if ...:
    entity_description = IskraSensorEntityDescription()
else:
    entity_description = IskraSensorEntityDescription()

and the thing down below can use .replace to add the UoM and device class

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with .replace you meant like that?
entity_description.native_unit_of_measurement = UnitOfEnergy.WATT_HOUR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dataclasses.replace


# Set unit of measurement and device class based on counter type
# HA's Energy device class supports only active energy
if counter.counter_type in [CounterType.ACTIVE_IMPORT, CounterType.ACTIVE_EXPORT]:
sensor_description.update(
{
"native_unit_of_measurement": UnitOfEnergy.WATT_HOUR,
"device_class": SensorDeviceClass.ENERGY,
}
)

description = IskraSensorEntityDescription(**sensor_description)

return IskraSensor(coordinator, description)


async def async_setup_entry(
hass: HomeAssistant,
entry: IskraConfigEntry,
Expand Down Expand Up @@ -205,6 +249,21 @@ async def async_setup_entry(
if description.key in sensors
)

if device.supports_counters:
for index, counter in enumerate(device.counters.non_resettable[:4]):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will the unique_id be?

Copy link
Contributor Author

@iskrakranj iskrakranj Sep 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unique_id is assembled in entity.py using device serial and entity description key. entity description key is ATTR_RESETTABLE_COUNTER or ATTR_NON_RESETTABLE_COUNTER with added counter index

In line 177 in sensor.py (get_counter_entity_description) i use .format to add index

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i hope this is OK.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the counter change? We want to avoid setting up and having the data point that previously represented counter 1 to be counter 2 and vice versa

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they cannot those counters are directly from the energy meter's registers, always in same order

entities.append(
get_counter_sensor(
coordinator, counter, index, ATTR_NON_RESETTABLE_COUNTER
)
)

for index, counter in enumerate(device.counters.resettable[:8]):
entities.append(
get_counter_sensor(
coordinator, counter, index, ATTR_RESETTABLE_COUNTER
)
)

async_add_entities(entities)


Expand Down
36 changes: 36 additions & 0 deletions homeassistant/components/iskra/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,42 @@
},
"phase3_current": {
"name": "Phase 3 current"
},
"non_resettable_counter_1": {
"name": "Non Resettable counter 1"
},
"non_resettable_counter_2": {
"name": "Non Resettable counter 2"
},
"non_resettable_counter_3": {
"name": "Non Resettable counter 3"
},
"non_resettable_counter_4": {
"name": "Non Resettable counter 4"
},
"resettable_counter_1": {
"name": "Resettable counter 1"
},
"resettable_counter_2": {
"name": "Resettable counter 2"
},
"resettable_counter_3": {
"name": "Resettable counter 3"
},
"resettable_counter_4": {
"name": "Resettable counter 4"
},
"resettable_counter_5": {
"name": "Resettable counter 5"
},
"resettable_counter_6": {
"name": "Resettable counter 6"
},
"resettable_counter_7": {
"name": "Resettable counter 7"
},
"resettable_counter_8": {
"name": "Resettable counter 8"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1963,7 +1963,7 @@ pyiqvia==2022.04.0
pyirishrail==0.0.2

# homeassistant.components.iskra
pyiskra==0.1.8
pyiskra==0.1.11

# homeassistant.components.iss
pyiss==1.0.1
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,7 @@ pyipp==0.16.0
pyiqvia==2022.04.0

# homeassistant.components.iskra
pyiskra==0.1.8
pyiskra==0.1.11

# homeassistant.components.iss
pyiss==1.0.1
Expand Down
Loading