mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Jewish calendar binary sensor (#26200)
* Move jewish calendar to its own platform * Fix tests for Jewish Calendar platform As part of this, move tests to use async_setup_component instead of testing JewishCalendarSensor as suggested by @MartinHjelmare here: https://github.com/home-assistant/home-assistant/pull/24958#pullrequestreview-259394226 * Get sensors to update during test * Use hass.config.set_time_zone instead of directly calling set_default_time_zone in tests * Cleanup log messages * Rename result from weekly_portion to parshat_hashavua * Fix english/hebrew tests * Fix updating of issue melacha binary sensor * Fix docstrings of binary sensor * Reset timezones before and after each test * Use correct entity_id for day of the omer tests * Fix omer tests * Cleanup and rearrange tests * Remove the old issur_melacha_in_effect sensor * Rename variables to make the code clearer Instead of using lagging_date, use after_tzais and after_shkia * Use dt_util.set_default_time_zone instead of hass.config.set_time_zone so as not to break other tests * Remove should_poll set to false (accidental copy/paste) * Remove _LOGGER messaging during init and impossible cases * Move binary tests to standalone test functions Move sensor tests to standalone test functions * Collect entities before calling add_entities * Fix pylint errors * Simplify logic in binary sensor until a future a PR adds more sensors * Rename test_id holyness to holiday_type * Fix time zone for binary sensor tests Fix time zone for sensor tests * Don't use unnecessary alter_time in sensors Don't use unnecessary alter time in binary sensor Remove unused alter_time * Simply set hass.config.time_zone instead of murking around with global values * Use async_fire_time_changed instead of directly calling async_update_entity * Removing debug messaging during init of integration * Capitalize constants * Collect all Entities before calling async_add_entities * Revert "Don't use unnecessary alter_time in sensors" This reverts commit 74371740eaeb6e73c1a374725b05207071648ee1. * Use test time instead of utc_now * Remove superfluous testing * Fix triggering of time changed * Fix failing tests due to side-effects * Use dt_util.as_utc instead of reimplementing it's functionality * Use dict[key] for default values * Move 3rd party imports to the top of the module * Fix imports
This commit is contained in:
parent
50cec91cf0
commit
815e7a70e9
@ -1 +1,109 @@
|
||||
"""The jewish_calendar component."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
import hdate
|
||||
|
||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
|
||||
from homeassistant.helpers.discovery import async_load_platform
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DOMAIN = "jewish_calendar"
|
||||
|
||||
SENSOR_TYPES = {
|
||||
"binary": {
|
||||
"issur_melacha_in_effect": ["Issur Melacha in Effect", "mdi:power-plug-off"]
|
||||
},
|
||||
"data": {
|
||||
"date": ["Date", "mdi:judaism"],
|
||||
"weekly_portion": ["Parshat Hashavua", "mdi:book-open-variant"],
|
||||
"holiday_name": ["Holiday name", "mdi:calendar-star"],
|
||||
"holiday_type": ["Holiday type", "mdi:counter"],
|
||||
"omer_count": ["Day of the Omer", "mdi:counter"],
|
||||
},
|
||||
"time": {
|
||||
"first_light": ["Alot Hashachar", "mdi:weather-sunset-up"],
|
||||
"gra_end_shma": ['Latest time for Shm"a GR"A', "mdi:calendar-clock"],
|
||||
"mga_end_shma": ['Latest time for Shm"a MG"A', "mdi:calendar-clock"],
|
||||
"plag_mincha": ["Plag Hamincha", "mdi:weather-sunset-down"],
|
||||
"first_stars": ["T'set Hakochavim", "mdi:weather-night"],
|
||||
"upcoming_shabbat_candle_lighting": [
|
||||
"Upcoming Shabbat Candle Lighting",
|
||||
"mdi:candle",
|
||||
],
|
||||
"upcoming_shabbat_havdalah": ["Upcoming Shabbat Havdalah", "mdi:weather-night"],
|
||||
"upcoming_candle_lighting": ["Upcoming Candle Lighting", "mdi:candle"],
|
||||
"upcoming_havdalah": ["Upcoming Havdalah", "mdi:weather-night"],
|
||||
},
|
||||
}
|
||||
|
||||
CONF_DIASPORA = "diaspora"
|
||||
CONF_LANGUAGE = "language"
|
||||
CONF_CANDLE_LIGHT_MINUTES = "candle_lighting_minutes_before_sunset"
|
||||
CONF_HAVDALAH_OFFSET_MINUTES = "havdalah_minutes_after_sunset"
|
||||
|
||||
CANDLE_LIGHT_DEFAULT = 18
|
||||
|
||||
DEFAULT_NAME = "Jewish Calendar"
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_DIASPORA, default=False): cv.boolean,
|
||||
vol.Inclusive(CONF_LATITUDE, "coordinates"): cv.latitude,
|
||||
vol.Inclusive(CONF_LONGITUDE, "coordinates"): cv.longitude,
|
||||
vol.Optional(CONF_LANGUAGE, default="english"): vol.In(
|
||||
["hebrew", "english"]
|
||||
),
|
||||
vol.Optional(
|
||||
CONF_CANDLE_LIGHT_MINUTES, default=CANDLE_LIGHT_DEFAULT
|
||||
): int,
|
||||
# Default of 0 means use 8.5 degrees / 'three_stars' time.
|
||||
vol.Optional(CONF_HAVDALAH_OFFSET_MINUTES, default=0): int,
|
||||
}
|
||||
)
|
||||
},
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
"""Set up the Jewish Calendar component."""
|
||||
name = config[DOMAIN][CONF_NAME]
|
||||
language = config[DOMAIN][CONF_LANGUAGE]
|
||||
|
||||
latitude = config[DOMAIN].get(CONF_LATITUDE, hass.config.latitude)
|
||||
longitude = config[DOMAIN].get(CONF_LONGITUDE, hass.config.longitude)
|
||||
diaspora = config[DOMAIN][CONF_DIASPORA]
|
||||
|
||||
candle_lighting_offset = config[DOMAIN][CONF_CANDLE_LIGHT_MINUTES]
|
||||
havdalah_offset = config[DOMAIN][CONF_HAVDALAH_OFFSET_MINUTES]
|
||||
|
||||
location = hdate.Location(
|
||||
latitude=latitude,
|
||||
longitude=longitude,
|
||||
timezone=hass.config.time_zone,
|
||||
diaspora=diaspora,
|
||||
)
|
||||
|
||||
hass.data[DOMAIN] = {
|
||||
"location": location,
|
||||
"name": name,
|
||||
"language": language,
|
||||
"candle_lighting_offset": candle_lighting_offset,
|
||||
"havdalah_offset": havdalah_offset,
|
||||
"diaspora": diaspora,
|
||||
}
|
||||
|
||||
hass.async_create_task(async_load_platform(hass, "sensor", DOMAIN, {}, config))
|
||||
|
||||
hass.async_create_task(
|
||||
async_load_platform(hass, "binary_sensor", DOMAIN, {}, config)
|
||||
)
|
||||
|
||||
return True
|
||||
|
66
homeassistant/components/jewish_calendar/binary_sensor.py
Normal file
66
homeassistant/components/jewish_calendar/binary_sensor.py
Normal file
@ -0,0 +1,66 @@
|
||||
"""Support for Jewish Calendar binary sensors."""
|
||||
import logging
|
||||
|
||||
import hdate
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
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 binary sensor devices."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
async_add_entities(
|
||||
[
|
||||
JewishCalendarBinarySensor(hass.data[DOMAIN], sensor, sensor_info)
|
||||
for sensor, sensor_info in SENSOR_TYPES["binary"].items()
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class JewishCalendarBinarySensor(BinarySensorDevice):
|
||||
"""Representation of an Jewish Calendar binary sensor."""
|
||||
|
||||
def __init__(self, data, sensor, sensor_info):
|
||||
"""Initialize the binary 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._state = False
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon of the entity."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the entity."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if sensor is on."""
|
||||
return self._state
|
||||
|
||||
async def async_update(self):
|
||||
"""Update the state of the sensor."""
|
||||
zmanim = hdate.Zmanim(
|
||||
date=dt_util.now(),
|
||||
location=self._location,
|
||||
candle_lighting_offset=self._candle_lighting_offset,
|
||||
havdalah_offset=self._havdalah_offset,
|
||||
hebrew=self._hebrew,
|
||||
)
|
||||
|
||||
self._state = zmanim.issur_melacha_in_effect
|
@ -1,140 +1,59 @@
|
||||
"""Platform to retrieve Jewish calendar information for Home Assistant."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
import hdate
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (
|
||||
CONF_LATITUDE,
|
||||
CONF_LONGITUDE,
|
||||
CONF_NAME,
|
||||
SUN_EVENT_SUNSET,
|
||||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
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__)
|
||||
|
||||
SENSOR_TYPES = {
|
||||
"date": ["Date", "mdi:judaism"],
|
||||
"weekly_portion": ["Parshat Hashavua", "mdi:book-open-variant"],
|
||||
"holiday_name": ["Holiday", "mdi:calendar-star"],
|
||||
"holyness": ["Holyness", "mdi:counter"],
|
||||
"first_light": ["Alot Hashachar", "mdi:weather-sunset-up"],
|
||||
"gra_end_shma": ['Latest time for Shm"a GR"A', "mdi:calendar-clock"],
|
||||
"mga_end_shma": ['Latest time for Shm"a MG"A', "mdi:calendar-clock"],
|
||||
"plag_mincha": ["Plag Hamincha", "mdi:weather-sunset-down"],
|
||||
"first_stars": ["T'set Hakochavim", "mdi:weather-night"],
|
||||
"upcoming_shabbat_candle_lighting": [
|
||||
"Upcoming Shabbat Candle Lighting",
|
||||
"mdi:candle",
|
||||
],
|
||||
"upcoming_shabbat_havdalah": ["Upcoming Shabbat Havdalah", "mdi:weather-night"],
|
||||
"upcoming_candle_lighting": ["Upcoming Candle Lighting", "mdi:candle"],
|
||||
"upcoming_havdalah": ["Upcoming Havdalah", "mdi:weather-night"],
|
||||
"issur_melacha_in_effect": ["Issur Melacha in Effect", "mdi:power-plug-off"],
|
||||
"omer_count": ["Day of the Omer", "mdi:counter"],
|
||||
}
|
||||
|
||||
CONF_DIASPORA = "diaspora"
|
||||
CONF_LANGUAGE = "language"
|
||||
CONF_SENSORS = "sensors"
|
||||
CONF_CANDLE_LIGHT_MINUTES = "candle_lighting_minutes_before_sunset"
|
||||
CONF_HAVDALAH_OFFSET_MINUTES = "havdalah_minutes_after_sunset"
|
||||
|
||||
CANDLE_LIGHT_DEFAULT = 18
|
||||
|
||||
DEFAULT_NAME = "Jewish Calendar"
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_DIASPORA, default=False): cv.boolean,
|
||||
vol.Optional(CONF_LATITUDE): cv.latitude,
|
||||
vol.Optional(CONF_LONGITUDE): cv.longitude,
|
||||
vol.Optional(CONF_LANGUAGE, default="english"): vol.In(["hebrew", "english"]),
|
||||
vol.Optional(CONF_CANDLE_LIGHT_MINUTES, default=CANDLE_LIGHT_DEFAULT): int,
|
||||
# Default of 0 means use 8.5 degrees / 'three_stars' time.
|
||||
vol.Optional(CONF_HAVDALAH_OFFSET_MINUTES, default=0): int,
|
||||
vol.Optional(CONF_SENSORS, default=["date"]): vol.All(
|
||||
cv.ensure_list, vol.Length(min=1), [vol.In(SENSOR_TYPES)]
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
"""Set up the Jewish calendar sensor platform."""
|
||||
language = config.get(CONF_LANGUAGE)
|
||||
name = config.get(CONF_NAME)
|
||||
latitude = config.get(CONF_LATITUDE, hass.config.latitude)
|
||||
longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
|
||||
diaspora = config.get(CONF_DIASPORA)
|
||||
candle_lighting_offset = config.get(CONF_CANDLE_LIGHT_MINUTES)
|
||||
havdalah_offset = config.get(CONF_HAVDALAH_OFFSET_MINUTES)
|
||||
|
||||
if None in (latitude, longitude):
|
||||
_LOGGER.error("Latitude or longitude not set in Home Assistant config")
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
dev = []
|
||||
for sensor_type in config[CONF_SENSORS]:
|
||||
dev.append(
|
||||
JewishCalSensor(
|
||||
name,
|
||||
language,
|
||||
sensor_type,
|
||||
latitude,
|
||||
longitude,
|
||||
hass.config.time_zone,
|
||||
diaspora,
|
||||
candle_lighting_offset,
|
||||
havdalah_offset,
|
||||
)
|
||||
)
|
||||
async_add_entities(dev, True)
|
||||
sensors = [
|
||||
JewishCalendarSensor(hass.data[DOMAIN], sensor, sensor_info)
|
||||
for sensor, sensor_info in SENSOR_TYPES["data"].items()
|
||||
]
|
||||
sensors.extend(
|
||||
JewishCalendarSensor(hass.data[DOMAIN], sensor, sensor_info)
|
||||
for sensor, sensor_info in SENSOR_TYPES["time"].items()
|
||||
)
|
||||
|
||||
async_add_entities(sensors)
|
||||
|
||||
|
||||
class JewishCalSensor(Entity):
|
||||
class JewishCalendarSensor(Entity):
|
||||
"""Representation of an Jewish calendar sensor."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
language,
|
||||
sensor_type,
|
||||
latitude,
|
||||
longitude,
|
||||
timezone,
|
||||
diaspora,
|
||||
candle_lighting_offset=CANDLE_LIGHT_DEFAULT,
|
||||
havdalah_offset=0,
|
||||
):
|
||||
def __init__(self, data, sensor, sensor_info):
|
||||
"""Initialize the Jewish calendar sensor."""
|
||||
self.client_name = name
|
||||
self._name = SENSOR_TYPES[sensor_type][0]
|
||||
self.type = sensor_type
|
||||
self._hebrew = language == "hebrew"
|
||||
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
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.timezone = timezone
|
||||
self.diaspora = diaspora
|
||||
self.candle_lighting_offset = candle_lighting_offset
|
||||
self.havdalah_offset = havdalah_offset
|
||||
_LOGGER.debug("Sensor %s initialized", self.type)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return f"{self.client_name} {self._name}"
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Icon to display in the front end."""
|
||||
return SENSOR_TYPES[self.type][1]
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
@ -143,9 +62,7 @@ class JewishCalSensor(Entity):
|
||||
|
||||
async def async_update(self):
|
||||
"""Update the state of the sensor."""
|
||||
import hdate
|
||||
|
||||
now = dt_util.as_local(dt_util.now())
|
||||
now = dt_util.now()
|
||||
_LOGGER.debug("Now: %s Timezone = %s", now, now.tzinfo)
|
||||
|
||||
today = now.date()
|
||||
@ -155,66 +72,65 @@ class JewishCalSensor(Entity):
|
||||
|
||||
_LOGGER.debug("Now: %s Sunset: %s", now, sunset)
|
||||
|
||||
location = hdate.Location(
|
||||
latitude=self.latitude,
|
||||
longitude=self.longitude,
|
||||
timezone=self.timezone,
|
||||
diaspora=self.diaspora,
|
||||
)
|
||||
|
||||
def make_zmanim(date):
|
||||
"""Create a Zmanim object."""
|
||||
return hdate.Zmanim(
|
||||
date=date,
|
||||
location=location,
|
||||
candle_lighting_offset=self.candle_lighting_offset,
|
||||
havdalah_offset=self.havdalah_offset,
|
||||
location=self._location,
|
||||
candle_lighting_offset=self._candle_lighting_offset,
|
||||
havdalah_offset=self._havdalah_offset,
|
||||
hebrew=self._hebrew,
|
||||
)
|
||||
|
||||
date = hdate.HDate(today, diaspora=self.diaspora, hebrew=self._hebrew)
|
||||
lagging_date = date
|
||||
date = hdate.HDate(today, diaspora=self._diaspora, hebrew=self._hebrew)
|
||||
|
||||
# Advance Hebrew date if sunset has passed.
|
||||
# Not all sensors should advance immediately when the Hebrew date
|
||||
# officially changes (i.e. after sunset), hence lagging_date.
|
||||
if now > sunset:
|
||||
date = date.next_day
|
||||
# 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 = make_zmanim(today)
|
||||
|
||||
if now > sunset:
|
||||
after_shkia_date = date.next_day
|
||||
|
||||
if today_times.havdalah and now > today_times.havdalah:
|
||||
lagging_date = lagging_date.next_day
|
||||
after_tzais_date = date.next_day
|
||||
|
||||
# Terminology note: by convention in py-libhdate library, "upcoming"
|
||||
# refers to "current" or "upcoming" dates.
|
||||
if self.type == "date":
|
||||
self._state = date.hebrew_date
|
||||
elif self.type == "weekly_portion":
|
||||
if self._type == "date":
|
||||
self._state = after_shkia_date.hebrew_date
|
||||
elif self._type == "weekly_portion":
|
||||
# Compute the weekly portion based on the upcoming shabbat.
|
||||
self._state = lagging_date.upcoming_shabbat.parasha
|
||||
elif self.type == "holiday_name":
|
||||
self._state = date.holiday_description
|
||||
elif self.type == "holyness":
|
||||
self._state = date.holiday_type
|
||||
elif self.type == "upcoming_shabbat_candle_lighting":
|
||||
times = make_zmanim(lagging_date.upcoming_shabbat.previous_day.gdate)
|
||||
self._state = after_tzais_date.upcoming_shabbat.parasha
|
||||
elif self._type == "holiday_name":
|
||||
self._state = after_shkia_date.holiday_description
|
||||
elif self._type == "holiday_type":
|
||||
self._state = after_shkia_date.holiday_type
|
||||
elif self._type == "upcoming_shabbat_candle_lighting":
|
||||
times = make_zmanim(after_tzais_date.upcoming_shabbat.previous_day.gdate)
|
||||
self._state = times.candle_lighting
|
||||
elif self.type == "upcoming_candle_lighting":
|
||||
elif self._type == "upcoming_candle_lighting":
|
||||
times = make_zmanim(
|
||||
lagging_date.upcoming_shabbat_or_yom_tov.first_day.previous_day.gdate
|
||||
after_tzais_date.upcoming_shabbat_or_yom_tov.first_day.previous_day.gdate
|
||||
)
|
||||
self._state = times.candle_lighting
|
||||
elif self.type == "upcoming_shabbat_havdalah":
|
||||
times = make_zmanim(lagging_date.upcoming_shabbat.gdate)
|
||||
elif self._type == "upcoming_shabbat_havdalah":
|
||||
times = make_zmanim(after_tzais_date.upcoming_shabbat.gdate)
|
||||
self._state = times.havdalah
|
||||
elif self.type == "upcoming_havdalah":
|
||||
times = make_zmanim(lagging_date.upcoming_shabbat_or_yom_tov.last_day.gdate)
|
||||
elif self._type == "upcoming_havdalah":
|
||||
times = make_zmanim(
|
||||
after_tzais_date.upcoming_shabbat_or_yom_tov.last_day.gdate
|
||||
)
|
||||
self._state = times.havdalah
|
||||
elif self.type == "issur_melacha_in_effect":
|
||||
self._state = make_zmanim(now).issur_melacha_in_effect
|
||||
elif self.type == "omer_count":
|
||||
self._state = date.omer_day
|
||||
elif self._type == "omer_count":
|
||||
self._state = after_shkia_date.omer_day
|
||||
else:
|
||||
times = make_zmanim(today).zmanim
|
||||
self._state = times[self.type].time()
|
||||
self._state = times[self._type].time()
|
||||
|
||||
_LOGGER.debug("New value: %s", self._state)
|
||||
|
@ -1 +1,72 @@
|
||||
"""Tests for the jewish_calendar component."""
|
||||
from datetime import datetime
|
||||
from collections import namedtuple
|
||||
from contextlib import contextmanager
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components import jewish_calendar
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
|
||||
_LatLng = namedtuple("_LatLng", ["lat", "lng"])
|
||||
|
||||
NYC_LATLNG = _LatLng(40.7128, -74.0060)
|
||||
JERUSALEM_LATLNG = _LatLng(31.778, 35.235)
|
||||
|
||||
ORIG_TIME_ZONE = dt_util.DEFAULT_TIME_ZONE
|
||||
|
||||
|
||||
def teardown_module():
|
||||
"""Reset time zone."""
|
||||
dt_util.set_default_time_zone(ORIG_TIME_ZONE)
|
||||
|
||||
|
||||
def make_nyc_test_params(dtime, results, havdalah_offset=0):
|
||||
"""Make test params for NYC."""
|
||||
if isinstance(results, dict):
|
||||
time_zone = dt_util.get_time_zone("America/New_York")
|
||||
results = {
|
||||
key: time_zone.localize(value) if isinstance(value, datetime) else value
|
||||
for key, value in results.items()
|
||||
}
|
||||
return (
|
||||
dtime,
|
||||
jewish_calendar.CANDLE_LIGHT_DEFAULT,
|
||||
havdalah_offset,
|
||||
True,
|
||||
"America/New_York",
|
||||
NYC_LATLNG.lat,
|
||||
NYC_LATLNG.lng,
|
||||
results,
|
||||
)
|
||||
|
||||
|
||||
def make_jerusalem_test_params(dtime, results, havdalah_offset=0):
|
||||
"""Make test params for Jerusalem."""
|
||||
if isinstance(results, dict):
|
||||
time_zone = dt_util.get_time_zone("Asia/Jerusalem")
|
||||
results = {
|
||||
key: time_zone.localize(value) if isinstance(value, datetime) else value
|
||||
for key, value in results.items()
|
||||
}
|
||||
return (
|
||||
dtime,
|
||||
jewish_calendar.CANDLE_LIGHT_DEFAULT,
|
||||
havdalah_offset,
|
||||
False,
|
||||
"Asia/Jerusalem",
|
||||
JERUSALEM_LATLNG.lat,
|
||||
JERUSALEM_LATLNG.lng,
|
||||
results,
|
||||
)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def alter_time(local_time):
|
||||
"""Manage multiple time mocks."""
|
||||
utc_time = dt_util.as_utc(local_time)
|
||||
patch1 = patch("homeassistant.util.dt.utcnow", return_value=utc_time)
|
||||
patch2 = patch("homeassistant.util.dt.now", return_value=local_time)
|
||||
|
||||
with patch1, patch2:
|
||||
yield
|
||||
|
97
tests/components/jewish_calendar/test_binary_sensor.py
Normal file
97
tests/components/jewish_calendar/test_binary_sensor.py
Normal file
@ -0,0 +1,97 @@
|
||||
"""The tests for the Jewish calendar binary sensors."""
|
||||
from datetime import timedelta
|
||||
from datetime import datetime as dt
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.const import STATE_ON, STATE_OFF
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.components import jewish_calendar
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
from . import alter_time, make_nyc_test_params, make_jerusalem_test_params
|
||||
|
||||
|
||||
MELACHA_PARAMS = [
|
||||
make_nyc_test_params(dt(2018, 9, 1, 16, 0), STATE_ON),
|
||||
make_nyc_test_params(dt(2018, 9, 1, 20, 21), STATE_OFF),
|
||||
make_nyc_test_params(dt(2018, 9, 7, 13, 1), STATE_OFF),
|
||||
make_nyc_test_params(dt(2018, 9, 8, 21, 25), STATE_OFF),
|
||||
make_nyc_test_params(dt(2018, 9, 9, 21, 25), STATE_ON),
|
||||
make_nyc_test_params(dt(2018, 9, 10, 21, 25), STATE_ON),
|
||||
make_nyc_test_params(dt(2018, 9, 28, 21, 25), STATE_ON),
|
||||
make_nyc_test_params(dt(2018, 9, 29, 21, 25), STATE_OFF),
|
||||
make_nyc_test_params(dt(2018, 9, 30, 21, 25), STATE_ON),
|
||||
make_nyc_test_params(dt(2018, 10, 1, 21, 25), STATE_ON),
|
||||
make_jerusalem_test_params(dt(2018, 9, 29, 21, 25), STATE_OFF),
|
||||
make_jerusalem_test_params(dt(2018, 9, 30, 21, 25), STATE_ON),
|
||||
make_jerusalem_test_params(dt(2018, 10, 1, 21, 25), STATE_OFF),
|
||||
]
|
||||
|
||||
MELACHA_TEST_IDS = [
|
||||
"currently_first_shabbat",
|
||||
"after_first_shabbat",
|
||||
"friday_upcoming_shabbat",
|
||||
"upcoming_rosh_hashana",
|
||||
"currently_rosh_hashana",
|
||||
"second_day_rosh_hashana",
|
||||
"currently_shabbat_chol_hamoed",
|
||||
"upcoming_two_day_yomtov_in_diaspora",
|
||||
"currently_first_day_of_two_day_yomtov_in_diaspora",
|
||||
"currently_second_day_of_two_day_yomtov_in_diaspora",
|
||||
"upcoming_one_day_yom_tov_in_israel",
|
||||
"currently_one_day_yom_tov_in_israel",
|
||||
"after_one_day_yom_tov_in_israel",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
[
|
||||
"now",
|
||||
"candle_lighting",
|
||||
"havdalah",
|
||||
"diaspora",
|
||||
"tzname",
|
||||
"latitude",
|
||||
"longitude",
|
||||
"result",
|
||||
],
|
||||
MELACHA_PARAMS,
|
||||
ids=MELACHA_TEST_IDS,
|
||||
)
|
||||
async def test_issur_melacha_sensor(
|
||||
hass, now, candle_lighting, havdalah, diaspora, tzname, latitude, longitude, result
|
||||
):
|
||||
"""Test Issur Melacha sensor output."""
|
||||
time_zone = dt_util.get_time_zone(tzname)
|
||||
test_time = time_zone.localize(now)
|
||||
|
||||
hass.config.time_zone = time_zone
|
||||
hass.config.latitude = latitude
|
||||
hass.config.longitude = longitude
|
||||
|
||||
with alter_time(test_time):
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
jewish_calendar.DOMAIN,
|
||||
{
|
||||
"jewish_calendar": {
|
||||
"name": "test",
|
||||
"language": "english",
|
||||
"diaspora": diaspora,
|
||||
"candle_lighting_minutes_before_sunset": candle_lighting,
|
||||
"havdalah_minutes_after_sunset": havdalah,
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
future = dt_util.utcnow() + timedelta(seconds=30)
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (
|
||||
hass.states.get("binary_sensor.test_issur_melacha_in_effect").state
|
||||
== result
|
||||
)
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user