Skip to content

Commit 273d8b6

Browse files
committed
Use a base class to keep timestamp sensor inheritance
1 parent c47384f commit 273d8b6

File tree

2 files changed

+77
-77
lines changed

2 files changed

+77
-77
lines changed

homeassistant/components/jewish_calendar/entity.py

-45
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,16 @@
22

33
from dataclasses import dataclass
44
import datetime as dt
5-
import logging
65

76
from hdate import HDateInfo, Location, Zmanim
87
from hdate.translator import Language, set_language
98

109
from homeassistant.config_entries import ConfigEntry
11-
from homeassistant.const import SUN_EVENT_SUNSET
1210
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
1311
from homeassistant.helpers.entity import Entity, EntityDescription
14-
from homeassistant.helpers.sun import get_astral_event_date
15-
from homeassistant.util import dt as dt_util
1612

1713
from .const import DOMAIN
1814

19-
_LOGGER = logging.getLogger(__name__)
20-
2115
type JewishCalendarConfigEntry = ConfigEntry[JewishCalendarData]
2216

2317

@@ -71,42 +65,3 @@ def make_zmanim(self, date: dt.date) -> Zmanim:
7165
candle_lighting_offset=self.data.candle_lighting_offset,
7266
havdalah_offset=self.data.havdalah_offset,
7367
)
74-
75-
async def async_update_data(self) -> None:
76-
"""Update the state of the sensor."""
77-
now = dt_util.now()
78-
_LOGGER.debug("Now: %s Location: %r", now, self.data.location)
79-
80-
today = now.date()
81-
event_date = get_astral_event_date(self.hass, SUN_EVENT_SUNSET, today)
82-
83-
if event_date is None:
84-
_LOGGER.error("Can't get sunset event date for %s", today)
85-
return
86-
87-
sunset = dt_util.as_local(event_date)
88-
89-
_LOGGER.debug("Now: %s Sunset: %s", now, sunset)
90-
91-
daytime_date = HDateInfo(today, diaspora=self.data.diaspora)
92-
93-
# The Jewish day starts after darkness (called "tzais") and finishes at
94-
# sunset ("shkia"). The time in between is a gray area
95-
# (aka "Bein Hashmashot" # codespell:ignore
96-
# - literally: "in between the sun and the moon").
97-
98-
# For some sensors, it is more interesting to consider the date to be
99-
# tomorrow based on sunset ("shkia"), for others based on "tzais".
100-
# Hence the following variables.
101-
after_tzais_date = after_shkia_date = daytime_date
102-
today_times = self.make_zmanim(today)
103-
104-
if now > sunset:
105-
after_shkia_date = daytime_date.next_day
106-
107-
if today_times.havdalah and now > today_times.havdalah:
108-
after_tzais_date = daytime_date.next_day
109-
110-
self.data.results = JewishCalendarDataResults(
111-
daytime_date, after_shkia_date, after_tzais_date, today_times
112-
)

homeassistant/components/jewish_calendar/sensor.py

+77-32
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from collections.abc import Callable
66
from dataclasses import dataclass
77
import datetime as dt
8+
import logging
89

910
from hdate import HDateInfo, Zmanim
1011
from hdate.holidays import HolidayDatabase
@@ -15,28 +16,38 @@
1516
SensorEntity,
1617
SensorEntityDescription,
1718
)
18-
from homeassistant.const import EntityCategory
19+
from homeassistant.const import SUN_EVENT_SUNSET, EntityCategory
1920
from homeassistant.core import HomeAssistant
20-
from homeassistant.helpers.entity import EntityDescription
2121
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
22+
from homeassistant.helpers.sun import get_astral_event_date
23+
from homeassistant.util import dt as dt_util
2224

2325
from .entity import (
2426
JewishCalendarConfigEntry,
2527
JewishCalendarDataResults,
2628
JewishCalendarEntity,
2729
)
2830

31+
_LOGGER = logging.getLogger(__name__)
32+
33+
34+
@dataclass(frozen=True, kw_only=True)
35+
class JewishCalendarBaseSensorDescription(SensorEntityDescription):
36+
"""Base class describing Jewish Calendar sensor entities."""
37+
38+
value_fn: Callable | None
39+
2940

3041
@dataclass(frozen=True, kw_only=True)
31-
class JewishCalendarSensorDescription(SensorEntityDescription):
42+
class JewishCalendarSensorDescription(JewishCalendarBaseSensorDescription):
3243
"""Class describing Jewish Calendar sensor entities."""
3344

3445
value_fn: Callable[[JewishCalendarDataResults], str | int]
3546

3647

3748
@dataclass(frozen=True, kw_only=True)
38-
class JewishCalendarTimestampSensorDescription(SensorEntityDescription):
39-
"""Class describing Jewish Calendar sensor entities."""
49+
class JewishCalendarTimestampSensorDescription(JewishCalendarBaseSensorDescription):
50+
"""Class describing Jewish Calendar sensor timestamp entities."""
4051

4152
value_fn: (
4253
Callable[[HDateInfo, Callable[[dt.date], Zmanim]], dt.datetime | None] | None
@@ -209,29 +220,75 @@ async def async_setup_entry(
209220
async_add_entities: AddConfigEntryEntitiesCallback,
210221
) -> None:
211222
"""Set up the Jewish calendar sensors ."""
212-
async_add_entities(
213-
[
214-
JewishCalendarSensor(config_entry, description)
215-
for description in INFO_SENSORS
216-
]
217-
)
218-
async_add_entities(
219-
[
220-
JewishCalendarTimeSensor(config_entry, description)
221-
for description in TIME_SENSORS
222-
]
223+
sensors: list[JewishCalendarBaseSensor] = [
224+
JewishCalendarSensor(config_entry, description) for description in INFO_SENSORS
225+
]
226+
sensors.extend(
227+
JewishCalendarTimeSensor(config_entry, description)
228+
for description in TIME_SENSORS
223229
)
230+
async_add_entities(sensors)
224231

225232

226-
class JewishCalendarSensor(JewishCalendarEntity, SensorEntity):
227-
"""Representation of an Jewish calendar sensor."""
233+
class JewishCalendarBaseSensor(JewishCalendarEntity, SensorEntity):
234+
"""Base class for Jewish calendar sensors."""
228235

229236
_attr_entity_category = EntityCategory.DIAGNOSTIC
230237

238+
async def async_added_to_hass(self) -> None:
239+
"""Call when entity is added to hass."""
240+
await super().async_added_to_hass()
241+
await self.async_update_data()
242+
243+
async def async_update_data(self) -> None:
244+
"""Update the state of the sensor."""
245+
now = dt_util.now()
246+
_LOGGER.debug("Now: %s Location: %r", now, self.data.location)
247+
248+
today = now.date()
249+
event_date = get_astral_event_date(self.hass, SUN_EVENT_SUNSET, today)
250+
251+
if event_date is None:
252+
_LOGGER.error("Can't get sunset event date for %s", today)
253+
return
254+
255+
sunset = dt_util.as_local(event_date)
256+
257+
_LOGGER.debug("Now: %s Sunset: %s", now, sunset)
258+
259+
daytime_date = HDateInfo(today, diaspora=self.data.diaspora)
260+
261+
# The Jewish day starts after darkness (called "tzais") and finishes at
262+
# sunset ("shkia"). The time in between is a gray area
263+
# (aka "Bein Hashmashot" # codespell:ignore
264+
# - literally: "in between the sun and the moon").
265+
266+
# For some sensors, it is more interesting to consider the date to be
267+
# tomorrow based on sunset ("shkia"), for others based on "tzais".
268+
# Hence the following variables.
269+
after_tzais_date = after_shkia_date = daytime_date
270+
today_times = self.make_zmanim(today)
271+
272+
if now > sunset:
273+
after_shkia_date = daytime_date.next_day
274+
275+
if today_times.havdalah and now > today_times.havdalah:
276+
after_tzais_date = daytime_date.next_day
277+
278+
self.data.results = JewishCalendarDataResults(
279+
daytime_date, after_shkia_date, after_tzais_date, today_times
280+
)
281+
282+
283+
class JewishCalendarSensor(JewishCalendarBaseSensor):
284+
"""Representation of an Jewish calendar sensor."""
285+
231286
entity_description: JewishCalendarSensorDescription
232287

233288
def __init__(
234-
self, config_entry: JewishCalendarConfigEntry, description: EntityDescription
289+
self,
290+
config_entry: JewishCalendarConfigEntry,
291+
description: SensorEntityDescription,
235292
) -> None:
236293
"""Initialize the Jewish calendar sensor."""
237294
super().__init__(config_entry, description)
@@ -249,11 +306,6 @@ def native_value(self) -> str | int | dt.datetime | None:
249306
return None
250307
return self.entity_description.value_fn(self.data.results)
251308

252-
async def async_added_to_hass(self) -> None:
253-
"""Call when entity is added to hass."""
254-
await super().async_added_to_hass()
255-
await self.async_update_data()
256-
257309
@property
258310
def extra_state_attributes(self) -> dict[str, str]:
259311
"""Return the state attributes."""
@@ -276,12 +328,10 @@ def extra_state_attributes(self) -> dict[str, str]:
276328
return {}
277329

278330

279-
class JewishCalendarTimeSensor(JewishCalendarEntity, SensorEntity):
331+
class JewishCalendarTimeSensor(JewishCalendarBaseSensor):
280332
"""Implement attributes for sensors returning times."""
281333

282-
_attr_entity_category = EntityCategory.DIAGNOSTIC
283334
_attr_device_class = SensorDeviceClass.TIMESTAMP
284-
285335
entity_description: JewishCalendarTimestampSensorDescription
286336

287337
@property
@@ -294,8 +344,3 @@ def native_value(self) -> dt.datetime | None:
294344
return self.entity_description.value_fn(
295345
self.data.results.after_tzais_date, self.make_zmanim
296346
)
297-
298-
async def async_added_to_hass(self) -> None:
299-
"""Call when entity is added to hass."""
300-
await super().async_added_to_hass()
301-
await self.async_update_data()

0 commit comments

Comments
 (0)