mirror of
https://github.com/Electric-Special/ha-core.git
synced 2026-03-21 04:05:20 +01:00
* Standardize times in time sensors Jewish calendar * Fix pylint errors * Add non-default time format test * Make black happy * Remove timestamp device class Timestamp device class requires ISO 8601 format * Revert "Remove timestamp device class" This reverts commit 8a2fda39831bc750c3a77aa774b84b054d78032c. * Remove time_format As this is part of the UI decision, it should be decided by lovelace. A nice addition for a future PR, might be the option to hint to lovelace the preferred way to display some data. * Update name of state_attributes * State of timestamp variable to be shown in UTC Although I don't understand it, I give up :) * Remove unnecessary attributes I don't really see the value in these attributes, if there are any they should be implemented in the sensor component for the timestamp device class
173 lines
5.8 KiB
Python
173 lines
5.8 KiB
Python
"""Platform to retrieve Jewish calendar information for Home Assistant."""
|
|
import logging
|
|
|
|
import hdate
|
|
|
|
from homeassistant.const import SUN_EVENT_SUNSET
|
|
from homeassistant.helpers.entity import Entity
|
|
from homeassistant.helpers.sun import get_astral_event_date
|
|
import homeassistant.util.dt as dt_util
|
|
|
|
from . import DOMAIN, SENSOR_TYPES
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
|
"""Set up the Jewish calendar sensor platform."""
|
|
if discovery_info is None:
|
|
return
|
|
|
|
sensors = [
|
|
JewishCalendarSensor(hass.data[DOMAIN], sensor, sensor_info)
|
|
for sensor, sensor_info in SENSOR_TYPES["data"].items()
|
|
]
|
|
sensors.extend(
|
|
JewishCalendarTimeSensor(hass.data[DOMAIN], sensor, sensor_info)
|
|
for sensor, sensor_info in SENSOR_TYPES["time"].items()
|
|
)
|
|
|
|
async_add_entities(sensors)
|
|
|
|
|
|
class JewishCalendarSensor(Entity):
|
|
"""Representation of an Jewish calendar sensor."""
|
|
|
|
def __init__(self, data, sensor, sensor_info):
|
|
"""Initialize the Jewish calendar sensor."""
|
|
self._location = data["location"]
|
|
self._type = sensor
|
|
self._name = f"{data['name']} {sensor_info[0]}"
|
|
self._icon = sensor_info[1]
|
|
self._hebrew = data["language"] == "hebrew"
|
|
self._candle_lighting_offset = data["candle_lighting_offset"]
|
|
self._havdalah_offset = data["havdalah_offset"]
|
|
self._diaspora = data["diaspora"]
|
|
self._state = None
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the name of the sensor."""
|
|
return self._name
|
|
|
|
@property
|
|
def icon(self):
|
|
"""Icon to display in the front end."""
|
|
return self._icon
|
|
|
|
@property
|
|
def state(self):
|
|
"""Return the state of the sensor."""
|
|
return self._state
|
|
|
|
async def async_update(self):
|
|
"""Update the state of the sensor."""
|
|
now = dt_util.now()
|
|
_LOGGER.debug("Now: %s Location: %r", now, self._location)
|
|
|
|
today = now.date()
|
|
sunset = dt_util.as_local(
|
|
get_astral_event_date(self.hass, SUN_EVENT_SUNSET, today)
|
|
)
|
|
|
|
_LOGGER.debug("Now: %s Sunset: %s", now, sunset)
|
|
|
|
date = hdate.HDate(today, diaspora=self._diaspora, hebrew=self._hebrew)
|
|
|
|
# The Jewish day starts after darkness (called "tzais") and finishes at
|
|
# sunset ("shkia"). The time in between is a gray area (aka "Bein
|
|
# Hashmashot" - literally: "in between the sun and the moon").
|
|
|
|
# For some sensors, it is more interesting to consider the date to be
|
|
# tomorrow based on sunset ("shkia"), for others based on "tzais".
|
|
# Hence the following variables.
|
|
after_tzais_date = after_shkia_date = date
|
|
today_times = self.make_zmanim(today)
|
|
|
|
if now > sunset:
|
|
after_shkia_date = date.next_day
|
|
|
|
if today_times.havdalah and now > today_times.havdalah:
|
|
after_tzais_date = date.next_day
|
|
|
|
self._state = self.get_state(after_shkia_date, after_tzais_date)
|
|
_LOGGER.debug("New value for %s: %s", self._type, self._state)
|
|
|
|
def make_zmanim(self, date):
|
|
"""Create a Zmanim object."""
|
|
return hdate.Zmanim(
|
|
date=date,
|
|
location=self._location,
|
|
candle_lighting_offset=self._candle_lighting_offset,
|
|
havdalah_offset=self._havdalah_offset,
|
|
hebrew=self._hebrew,
|
|
)
|
|
|
|
def get_state(self, after_shkia_date, after_tzais_date):
|
|
"""For a given type of sensor, return the state."""
|
|
# Terminology note: by convention in py-libhdate library, "upcoming"
|
|
# refers to "current" or "upcoming" dates.
|
|
if self._type == "date":
|
|
return after_shkia_date.hebrew_date
|
|
if self._type == "weekly_portion":
|
|
# Compute the weekly portion based on the upcoming shabbat.
|
|
return after_tzais_date.upcoming_shabbat.parasha
|
|
if self._type == "holiday_name":
|
|
return after_shkia_date.holiday_description
|
|
if self._type == "holiday_type":
|
|
return after_shkia_date.holiday_type
|
|
if self._type == "omer_count":
|
|
return after_shkia_date.omer_day
|
|
|
|
return None
|
|
|
|
|
|
class JewishCalendarTimeSensor(JewishCalendarSensor):
|
|
"""Implement attrbutes for sensors returning times."""
|
|
|
|
@property
|
|
def state(self):
|
|
"""Return the state of the sensor."""
|
|
return dt_util.as_utc(self._state) if self._state is not None else None
|
|
|
|
@property
|
|
def device_class(self):
|
|
"""Return the class of this sensor."""
|
|
return "timestamp"
|
|
|
|
@property
|
|
def device_state_attributes(self):
|
|
"""Return the state attributes."""
|
|
attrs = {}
|
|
|
|
if self._state is None:
|
|
return attrs
|
|
|
|
attrs["timestamp"] = self._state.timestamp()
|
|
|
|
return attrs
|
|
|
|
def get_state(self, after_shkia_date, after_tzais_date):
|
|
"""For a given type of sensor, return the state."""
|
|
if self._type == "upcoming_shabbat_candle_lighting":
|
|
times = self.make_zmanim(
|
|
after_tzais_date.upcoming_shabbat.previous_day.gdate
|
|
)
|
|
return times.candle_lighting
|
|
if self._type == "upcoming_candle_lighting":
|
|
times = self.make_zmanim(
|
|
after_tzais_date.upcoming_shabbat_or_yom_tov.first_day.previous_day.gdate
|
|
)
|
|
return times.candle_lighting
|
|
if self._type == "upcoming_shabbat_havdalah":
|
|
times = self.make_zmanim(after_tzais_date.upcoming_shabbat.gdate)
|
|
return times.havdalah
|
|
if self._type == "upcoming_havdalah":
|
|
times = self.make_zmanim(
|
|
after_tzais_date.upcoming_shabbat_or_yom_tov.last_day.gdate
|
|
)
|
|
return times.havdalah
|
|
|
|
times = self.make_zmanim(dt_util.now()).zmanim
|
|
return times[self._type]
|