Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 3 additions & 3 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
# - No PRs marked as no-stale
# - No issues (-1)
- name: 60 days stale PRs policy
uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 60
Expand Down Expand Up @@ -67,7 +67,7 @@ jobs:
# - No issues marked as no-stale or help-wanted
# - No PRs (-1)
- name: 90 days stale issues
uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
with:
repo-token: ${{ steps.token.outputs.token }}
days-before-stale: 90
Expand Down Expand Up @@ -97,7 +97,7 @@ jobs:
# - No Issues marked as no-stale or help-wanted
# - No PRs (-1)
- name: Needs more information stale issues policy
uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
with:
repo-token: ${{ steps.token.outputs.token }}
only-labels: "needs-more-information"
Expand Down
18 changes: 15 additions & 3 deletions homeassistant/components/egauge/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
from collections.abc import Callable
from dataclasses import dataclass

from egauge_async.json.models import RegisterType
from egauge_async.json.models import RegisterInfo, RegisterType

from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import UnitOfEnergy, UnitOfPower
from homeassistant.const import UnitOfElectricPotential, UnitOfEnergy, UnitOfPower
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

Expand All @@ -27,6 +27,7 @@ class EgaugeSensorEntityDescription(SensorEntityDescription):

native_value_fn: Callable[[EgaugeData, str], float]
available_fn: Callable[[EgaugeData, str], bool]
supported_fn: Callable[[RegisterInfo], bool]


SENSORS: tuple[EgaugeSensorEntityDescription, ...] = (
Expand All @@ -37,6 +38,7 @@ class EgaugeSensorEntityDescription(SensorEntityDescription):
native_unit_of_measurement=UnitOfPower.WATT,
native_value_fn=lambda data, register: data.measurements[register],
available_fn=lambda data, register: register in data.measurements,
supported_fn=lambda register_info: register_info.type == RegisterType.POWER,
),
EgaugeSensorEntityDescription(
key="energy",
Expand All @@ -46,6 +48,16 @@ class EgaugeSensorEntityDescription(SensorEntityDescription):
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
native_value_fn=lambda data, register: data.counters[register],
available_fn=lambda data, register: register in data.counters,
supported_fn=lambda register_info: register_info.type == RegisterType.POWER,
),
EgaugeSensorEntityDescription(
key="voltage",
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
native_value_fn=lambda data, register: data.measurements[register],
available_fn=lambda data, register: register in data.measurements,
supported_fn=lambda register_info: register_info.type == RegisterType.VOLTAGE,
),
)

Expand All @@ -61,7 +73,7 @@ async def async_setup_entry(
EgaugeSensor(coordinator, register_name, sensor)
for sensor in SENSORS
for register_name, register_info in coordinator.data.register_info.items()
if register_info.type == RegisterType.POWER
if sensor.supported_fn(register_info)
)


Expand Down
63 changes: 15 additions & 48 deletions homeassistant/components/osramlightify/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,8 @@ def __init__(self, luminary, update_func, changed):
self._luminary = luminary
self._changed = changed

self._unique_id = None
self._effect_list = []
self._is_on = False
self._available = True
self._brightness = None
self._attr_is_on = False
self._rgb_color = None
self._device_attributes = None

self.update_static_attributes()
self.update_dynamic_attributes()
Expand Down Expand Up @@ -253,36 +248,6 @@ def hs_color(self):
"""Return last hs color value set."""
return color_util.color_RGB_to_hs(*self._rgb_color)

@property
def brightness(self):
"""Return brightness of the luminary (0..255)."""
return self._brightness

@property
def is_on(self):
"""Return True if the device is on."""
return self._is_on

@property
def effect_list(self):
"""List of supported effects."""
return self._effect_list

@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id

@property
def extra_state_attributes(self):
"""Return device specific state attributes."""
return self._device_attributes

@property
def available(self) -> bool:
"""Return True if entity is available."""
return self._available

def play_effect(self, effect, transition):
"""Play selected effect."""
if effect == EFFECT_RANDOM:
Expand Down Expand Up @@ -313,19 +278,19 @@ def turn_on(self, **kwargs: Any) -> None:
self._attr_color_temp_kelvin = color_temp_kelvin
self._luminary.set_temperature(color_temp_kelvin, transition)

self._is_on = True
self._attr_is_on = True
if ATTR_BRIGHTNESS in kwargs:
self._brightness = kwargs[ATTR_BRIGHTNESS]
self._luminary.set_luminance(int(self._brightness / 2.55), transition)
self._attr_brightness = kwargs[ATTR_BRIGHTNESS]
self._luminary.set_luminance(int(self._attr_brightness / 2.55), transition)
else:
self._luminary.set_onoff(True)

def turn_off(self, **kwargs: Any) -> None:
"""Turn the device off."""
self._is_on = False
self._attr_is_on = False
if ATTR_TRANSITION in kwargs:
transition = int(kwargs[ATTR_TRANSITION] * 10)
self._brightness = DEFAULT_BRIGHTNESS
self._attr_brightness = DEFAULT_BRIGHTNESS
self._luminary.set_luminance(0, transition)
else:
self._luminary.set_onoff(False)
Expand All @@ -337,10 +302,10 @@ def update_luminary(self, luminary):

def update_static_attributes(self) -> None:
"""Update static attributes of the luminary."""
self._unique_id = self._get_unique_id()
self._attr_unique_id = self._get_unique_id()
self._attr_supported_color_modes = self._get_supported_color_modes()
self._attr_supported_features = self._get_supported_features()
self._effect_list = self._get_effect_list()
self._attr_effect_list = self._get_effect_list()
if ColorMode.COLOR_TEMP in self._attr_supported_color_modes:
self._attr_max_color_temp_kelvin = (
self._luminary.max_temp() or DEFAULT_KELVIN
Expand All @@ -354,10 +319,12 @@ def update_static_attributes(self) -> None:

def update_dynamic_attributes(self):
"""Update dynamic attributes of the luminary."""
self._is_on = self._luminary.on()
self._available = self._luminary.reachable() and not self._luminary.deleted()
self._attr_is_on = self._luminary.on()
self._attr_available = (
self._luminary.reachable() and not self._luminary.deleted()
)
if brightness_supported(self._attr_supported_color_modes):
self._brightness = int(self._luminary.lum() * 2.55)
self._attr_brightness = int(self._luminary.lum() * 2.55)

if ColorMode.COLOR_TEMP in self._attr_supported_color_modes:
self._attr_color_temp_kelvin = self._luminary.temp() or DEFAULT_KELVIN
Expand Down Expand Up @@ -399,7 +366,7 @@ def update_static_attributes(self):
if self._luminary.devicetype().name == "SENSOR":
attrs["sensor_values"] = self._luminary.raw_values()

self._device_attributes = attrs
self._attr_extra_state_attributes = attrs


class OsramLightifyGroup(Luminary):
Expand Down Expand Up @@ -444,4 +411,4 @@ def play_effect(self, effect, transition):
def update_static_attributes(self):
"""Update static attributes of the luminary."""
super().update_static_attributes()
self._device_attributes = {"lights": self._luminary.light_names()}
self._attr_extra_state_attributes = {"lights": self._luminary.light_names()}
2 changes: 1 addition & 1 deletion homeassistant/components/rainbird/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": ["pyrainbird"],
"requirements": ["pyrainbird==6.0.1"]
"requirements": ["pyrainbird==6.0.5"]
}
2 changes: 1 addition & 1 deletion requirements_all.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion requirements_test_all.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tests/components/egauge/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,21 @@ def mock_egauge_client() -> Generator[MagicMock]:
"Temp": RegisterInfo(
name="Temp", type=RegisterType.TEMPERATURE, idx=2, did=None
),
"L1": RegisterInfo(name="L1", type=RegisterType.VOLTAGE, idx=3, did=None),
}

# Dynamic measurements
client.get_current_measurements.return_value = {
"Grid": 1500.0,
"Solar": -2500.0,
"Temp": 45.0,
"L1": 123.4,
}
client.get_current_counters.return_value = {
"Grid": 450000000.0, # 125 kWh in Ws
"Solar": 315000000.0, # 87.5 kWh in Ws
"Temp": 0.0,
"L1": 12345678.0,
}

yield client
Expand Down
59 changes: 58 additions & 1 deletion tests/components/egauge/snapshots/test_sensor.ambr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# serializer version: 1
# name: test_sensors.8
# name: test_sensors.10
DeviceRegistryEntrySnapshot({
'area_id': None,
'config_entries': <ANY>,
Expand Down Expand Up @@ -147,6 +147,63 @@
'state': '1500.0',
})
# ---
# name: test_sensors[sensor.egauge_home_l1_voltage-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.egauge_home_l1_voltage',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Voltage',
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
}),
'original_device_class': <SensorDeviceClass.VOLTAGE: 'voltage'>,
'original_icon': None,
'original_name': 'Voltage',
'platform': 'egauge',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'ABC123456_L1_voltage',
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
})
# ---
# name: test_sensors[sensor.egauge_home_l1_voltage-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'voltage',
'friendly_name': 'egauge-home L1 Voltage',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
}),
'context': <ANY>,
'entity_id': 'sensor.egauge_home_l1_voltage',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '123.4',
})
# ---
# name: test_sensors[sensor.egauge_home_solar_energy-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
Expand Down
Loading