From 4d187e08d460fe7077dab8e226fe940ff253f6db Mon Sep 17 00:00:00 2001 From: arigilder <43716164+arigilder@users.noreply.github.com> Date: Thu, 10 Jan 2019 19:27:34 -0500 Subject: [PATCH] Add sensors to jewish_calendar for upcoming Shabbat times (#19278) * Initial pass of cleanup for shabbat_times * Switch to async defs * First pass of unit tests + fixture data * Completion of first round of unit tests, 100% passing * Unit tests for state restoring * Style fixes * More style fixes * Lint fix * Add upcoming candelighting and havdalah sensors * Add unit tests, remove havdalah offset * More unit tests + small bugfix for weekly_portion * Add issur melacha sensor * Remove old shabbat_times work-in-progress files * Bump required version of hdate * Add havdalah offset config parameter * Bump hdate version required * Pin hdate requirement * Lint fixes * Changes based on review + API changes for hdate 0.8.7 * Add three-day holiday unit tests * Remove debugging line * Add missing docstring * Fix doc lint comment --- .../components/sensor/jewish_calendar.py | 63 +++- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../components/sensor/test_jewish_calendar.py | 332 +++++++++++++++++- 4 files changed, 382 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/sensor/jewish_calendar.py b/homeassistant/components/sensor/jewish_calendar.py index 8058a411266..cc226337f02 100644 --- a/homeassistant/components/sensor/jewish_calendar.py +++ b/homeassistant/components/sensor/jewish_calendar.py @@ -17,7 +17,7 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.sun import get_astral_event_date import homeassistant.util.dt as dt_util -REQUIREMENTS = ['hdate==0.7.5'] +REQUIREMENTS = ['hdate==0.8.7'] _LOGGER = logging.getLogger(__name__) @@ -31,11 +31,24 @@ SENSOR_TYPES = { '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' @@ -46,6 +59,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ 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)]), }) @@ -59,6 +75,8 @@ async def async_setup_platform( 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") @@ -68,7 +86,8 @@ async def async_setup_platform( for sensor_type in config[CONF_SENSORS]: dev.append(JewishCalSensor( name, language, sensor_type, latitude, longitude, - hass.config.time_zone, diaspora)) + hass.config.time_zone, diaspora, candle_lighting_offset, + havdalah_offset)) async_add_entities(dev, True) @@ -77,7 +96,8 @@ class JewishCalSensor(Entity): def __init__( self, name, language, sensor_type, latitude, longitude, timezone, - diaspora): + diaspora, candle_lighting_offset=CANDLE_LIGHT_DEFAULT, + havdalah_offset=0): """Initialize the Jewish calendar sensor.""" self.client_name = name self._name = SENSOR_TYPES[sensor_type][0] @@ -88,6 +108,8 @@ class JewishCalSensor(Entity): 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 @@ -124,18 +146,45 @@ class JewishCalSensor(Entity): date = hdate.HDate( today, diaspora=self.diaspora, hebrew=self._hebrew) + 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, hebrew=self._hebrew) + if self.type == 'date': self._state = date.hebrew_date elif self.type == 'weekly_portion': - self._state = date.parasha + # Compute the weekly portion based on the upcoming shabbat. + self._state = 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(date.upcoming_shabbat.previous_day.gdate) + self._state = times.candle_lighting + elif self.type == 'upcoming_candle_lighting': + times = make_zmanim(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(date.upcoming_shabbat.gdate) + self._state = times.havdalah + elif self.type == 'upcoming_havdalah': + times = make_zmanim(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 else: - times = hdate.Zmanim( - date=today, latitude=self.latitude, longitude=self.longitude, - timezone=self.timezone, hebrew=self._hebrew).zmanim + times = make_zmanim(today).zmanim self._state = times[self.type].time() _LOGGER.debug("New value: %s", self._state) diff --git a/requirements_all.txt b/requirements_all.txt index 2bd62a5ddfe..45884ccf030 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -487,7 +487,7 @@ hangups==0.4.6 hbmqtt==0.9.4 # homeassistant.components.sensor.jewish_calendar -hdate==0.7.5 +hdate==0.8.7 # homeassistant.components.climate.heatmiser heatmiserV3==0.9.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index cb533e35227..7886047f4b2 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -98,7 +98,7 @@ hangups==0.4.6 hbmqtt==0.9.4 # homeassistant.components.sensor.jewish_calendar -hdate==0.7.5 +hdate==0.8.7 # homeassistant.components.binary_sensor.workday holidays==0.9.9 diff --git a/tests/components/sensor/test_jewish_calendar.py b/tests/components/sensor/test_jewish_calendar.py index 320bc903661..639364164e0 100644 --- a/tests/components/sensor/test_jewish_calendar.py +++ b/tests/components/sensor/test_jewish_calendar.py @@ -1,4 +1,5 @@ """The tests for the Jewish calendar sensor platform.""" +from collections import namedtuple from datetime import time from datetime import datetime as dt from unittest.mock import patch @@ -8,13 +9,34 @@ import pytest from homeassistant.util.async_ import run_coroutine_threadsafe from homeassistant.util.dt import get_time_zone, set_default_time_zone from homeassistant.setup import setup_component -from homeassistant.components.sensor.jewish_calendar import JewishCalSensor +from homeassistant.components.sensor.jewish_calendar import ( + JewishCalSensor, CANDLE_LIGHT_DEFAULT) from tests.common import get_test_home_assistant +_LatLng = namedtuple('_LatLng', ['lat', 'lng']) + +NYC_LATLNG = _LatLng(40.7128, -74.0060) +JERUSALEM_LATLNG = _LatLng(31.778, 35.235) + + +def make_nyc_test_params(dtime, results, havdalah_offset=0): + """Make test params for NYC.""" + return (dtime, 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.""" + return (dtime, CANDLE_LIGHT_DEFAULT, havdalah_offset, False, + 'Asia/Jerusalem', JERUSALEM_LATLNG.lat, JERUSALEM_LATLNG.lng, + results) + + class TestJewishCalenderSensor(): """Test the Jewish Calendar sensor.""" + # pylint: disable=attribute-defined-outside-init def setup_method(self, method): """Set up things to run when tests begin.""" self.hass = get_test_home_assistant() @@ -99,21 +121,315 @@ class TestJewishCalenderSensor(): "date_after_sunset" ] - @pytest.mark.parametrize(["time", "tzname", "latitude", "longitude", + @pytest.mark.parametrize(["cur_time", "tzname", "latitude", "longitude", "language", "sensor", "diaspora", "result"], test_params, ids=test_ids) - def test_jewish_calendar_sensor(self, time, tzname, latitude, longitude, - language, sensor, diaspora, result): + def test_jewish_calendar_sensor(self, cur_time, tzname, latitude, + longitude, language, sensor, diaspora, + result): """Test Jewish calendar sensor output.""" - tz = get_time_zone(tzname) - set_default_time_zone(tz) - test_time = tz.localize(time) + time_zone = get_time_zone(tzname) + set_default_time_zone(time_zone) + test_time = time_zone.localize(cur_time) self.hass.config.latitude = latitude self.hass.config.longitude = longitude sensor = JewishCalSensor( name='test', language=language, sensor_type=sensor, latitude=latitude, longitude=longitude, - timezone=tz, diaspora=diaspora) + timezone=time_zone, diaspora=diaspora) + sensor.hass = self.hass + with patch('homeassistant.util.dt.now', return_value=test_time): + run_coroutine_threadsafe( + sensor.async_update(), + self.hass.loop).result() + assert sensor.state == result + + shabbat_params = [ + make_nyc_test_params( + dt(2018, 9, 1, 16, 0), + {'upcoming_shabbat_candle_lighting': dt(2018, 8, 31, 19, 15), + 'upcoming_shabbat_havdalah': dt(2018, 9, 1, 20, 14), + 'weekly_portion': 'Ki Tavo', + 'hebrew_weekly_portion': 'כי תבוא'}), + make_nyc_test_params( + dt(2018, 9, 1, 16, 0), + {'upcoming_shabbat_candle_lighting': dt(2018, 8, 31, 19, 15), + 'upcoming_shabbat_havdalah': dt(2018, 9, 1, 20, 22), + 'weekly_portion': 'Ki Tavo', + 'hebrew_weekly_portion': 'כי תבוא'}, + havdalah_offset=50), + make_nyc_test_params( + dt(2018, 9, 1, 20, 21), + {'upcoming_shabbat_candle_lighting': dt(2018, 9, 7, 19, 4), + 'upcoming_shabbat_havdalah': dt(2018, 9, 8, 20, 2), + 'weekly_portion': 'Nitzavim', + 'hebrew_weekly_portion': 'נצבים'}), + make_nyc_test_params( + dt(2018, 9, 7, 13, 1), + {'upcoming_shabbat_candle_lighting': dt(2018, 9, 7, 19, 4), + 'upcoming_shabbat_havdalah': dt(2018, 9, 8, 20, 2), + 'weekly_portion': 'Nitzavim', + 'hebrew_weekly_portion': 'נצבים'}), + make_nyc_test_params( + dt(2018, 9, 8, 21, 25), + {'upcoming_candle_lighting': dt(2018, 9, 9, 19, 1), + 'upcoming_havdalah': dt(2018, 9, 11, 19, 57), + 'upcoming_shabbat_candle_lighting': dt(2018, 9, 14, 18, 52), + 'upcoming_shabbat_havdalah': dt(2018, 9, 15, 19, 50), + 'weekly_portion': 'Vayeilech', + 'hebrew_weekly_portion': 'וילך', + 'holiday_name': 'Erev Rosh Hashana', + 'hebrew_holiday_name': 'ערב ראש השנה'}), + make_nyc_test_params( + dt(2018, 9, 9, 21, 25), + {'upcoming_candle_lighting': dt(2018, 9, 9, 19, 1), + 'upcoming_havdalah': dt(2018, 9, 11, 19, 57), + 'upcoming_shabbat_candle_lighting': dt(2018, 9, 14, 18, 52), + 'upcoming_shabbat_havdalah': dt(2018, 9, 15, 19, 50), + 'weekly_portion': 'Vayeilech', + 'hebrew_weekly_portion': 'וילך', + 'holiday_name': 'Rosh Hashana I', + 'hebrew_holiday_name': "א' ראש השנה"}), + make_nyc_test_params( + dt(2018, 9, 10, 21, 25), + {'upcoming_candle_lighting': dt(2018, 9, 9, 19, 1), + 'upcoming_havdalah': dt(2018, 9, 11, 19, 57), + 'upcoming_shabbat_candle_lighting': dt(2018, 9, 14, 18, 52), + 'upcoming_shabbat_havdalah': dt(2018, 9, 15, 19, 50), + 'weekly_portion': 'Vayeilech', + 'hebrew_weekly_portion': 'וילך', + 'holiday_name': 'Rosh Hashana II', + 'hebrew_holiday_name': "ב' ראש השנה"}), + make_nyc_test_params( + dt(2018, 9, 28, 21, 25), + {'upcoming_shabbat_candle_lighting': dt(2018, 9, 28, 18, 28), + 'upcoming_shabbat_havdalah': dt(2018, 9, 29, 19, 25), + 'weekly_portion': 'none', + 'hebrew_weekly_portion': 'none'}), + make_nyc_test_params( + dt(2018, 9, 29, 21, 25), + {'upcoming_candle_lighting': dt(2018, 9, 30, 18, 25), + 'upcoming_havdalah': dt(2018, 10, 2, 19, 20), + 'upcoming_shabbat_candle_lighting': dt(2018, 10, 5, 18, 17), + 'upcoming_shabbat_havdalah': dt(2018, 10, 6, 19, 13), + 'weekly_portion': 'Bereshit', + 'hebrew_weekly_portion': 'בראשית', + 'holiday_name': 'Hoshana Raba', + 'hebrew_holiday_name': 'הושענא רבה'}), + make_nyc_test_params( + dt(2018, 9, 30, 21, 25), + {'upcoming_candle_lighting': dt(2018, 9, 30, 18, 25), + 'upcoming_havdalah': dt(2018, 10, 2, 19, 20), + 'upcoming_shabbat_candle_lighting': dt(2018, 10, 5, 18, 17), + 'upcoming_shabbat_havdalah': dt(2018, 10, 6, 19, 13), + 'weekly_portion': 'Bereshit', + 'hebrew_weekly_portion': 'בראשית', + 'holiday_name': 'Shmini Atzeret', + 'hebrew_holiday_name': 'שמיני עצרת'}), + make_nyc_test_params( + dt(2018, 10, 1, 21, 25), + {'upcoming_candle_lighting': dt(2018, 9, 30, 18, 25), + 'upcoming_havdalah': dt(2018, 10, 2, 19, 20), + 'upcoming_shabbat_candle_lighting': dt(2018, 10, 5, 18, 17), + 'upcoming_shabbat_havdalah': dt(2018, 10, 6, 19, 13), + 'weekly_portion': 'Bereshit', + 'hebrew_weekly_portion': 'בראשית', + 'holiday_name': 'Simchat Torah', + 'hebrew_holiday_name': 'שמחת תורה'}), + make_jerusalem_test_params( + dt(2018, 9, 29, 21, 25), + {'upcoming_candle_lighting': dt(2018, 9, 30, 18, 10), + 'upcoming_havdalah': dt(2018, 10, 1, 19, 2), + 'upcoming_shabbat_candle_lighting': dt(2018, 10, 5, 18, 3), + 'upcoming_shabbat_havdalah': dt(2018, 10, 6, 18, 56), + 'weekly_portion': 'Bereshit', + 'hebrew_weekly_portion': 'בראשית', + 'holiday_name': 'Hoshana Raba', + 'hebrew_holiday_name': 'הושענא רבה'}), + make_jerusalem_test_params( + dt(2018, 9, 30, 21, 25), + {'upcoming_candle_lighting': dt(2018, 9, 30, 18, 10), + 'upcoming_havdalah': dt(2018, 10, 1, 19, 2), + 'upcoming_shabbat_candle_lighting': dt(2018, 10, 5, 18, 3), + 'upcoming_shabbat_havdalah': dt(2018, 10, 6, 18, 56), + 'weekly_portion': 'Bereshit', + 'hebrew_weekly_portion': 'בראשית', + 'holiday_name': 'Shmini Atzeret', + 'hebrew_holiday_name': 'שמיני עצרת'}), + make_jerusalem_test_params( + dt(2018, 10, 1, 21, 25), + {'upcoming_shabbat_candle_lighting': dt(2018, 10, 5, 18, 3), + 'upcoming_shabbat_havdalah': dt(2018, 10, 6, 18, 56), + 'weekly_portion': 'Bereshit', + 'hebrew_weekly_portion': 'בראשית'}), + make_nyc_test_params( + dt(2016, 6, 11, 8, 25), + {'upcoming_candle_lighting': dt(2016, 6, 10, 20, 7), + 'upcoming_havdalah': dt(2016, 6, 13, 21, 17), + 'upcoming_shabbat_candle_lighting': dt(2016, 6, 10, 20, 7), + 'upcoming_shabbat_havdalah': None, + 'weekly_portion': 'Bamidbar', + 'hebrew_weekly_portion': 'במדבר', + 'holiday_name': 'Erev Shavuot', + 'hebrew_holiday_name': 'ערב שבועות'}), + make_nyc_test_params( + dt(2016, 6, 12, 8, 25), + {'upcoming_candle_lighting': dt(2016, 6, 10, 20, 7), + 'upcoming_havdalah': dt(2016, 6, 13, 21, 17), + 'upcoming_shabbat_candle_lighting': dt(2016, 6, 17, 20, 10), + 'upcoming_shabbat_havdalah': dt(2016, 6, 18, 21, 19), + 'weekly_portion': 'Nasso', + 'hebrew_weekly_portion': 'נשא', + 'holiday_name': 'Shavuot', + 'hebrew_holiday_name': 'שבועות'}), + make_jerusalem_test_params( + dt(2017, 9, 21, 8, 25), + {'upcoming_candle_lighting': dt(2017, 9, 20, 18, 23), + 'upcoming_havdalah': dt(2017, 9, 23, 19, 13), + 'upcoming_shabbat_candle_lighting': dt(2017, 9, 22, 19, 14), + 'upcoming_shabbat_havdalah': dt(2017, 9, 23, 19, 13), + 'weekly_portion': "Ha'Azinu", + 'hebrew_weekly_portion': 'האזינו', + 'holiday_name': 'Rosh Hashana I', + 'hebrew_holiday_name': "א' ראש השנה"}), + make_jerusalem_test_params( + dt(2017, 9, 22, 8, 25), + {'upcoming_candle_lighting': dt(2017, 9, 20, 18, 23), + 'upcoming_havdalah': dt(2017, 9, 23, 19, 13), + 'upcoming_shabbat_candle_lighting': dt(2017, 9, 22, 19, 14), + 'upcoming_shabbat_havdalah': dt(2017, 9, 23, 19, 13), + 'weekly_portion': "Ha'Azinu", + 'hebrew_weekly_portion': 'האזינו', + 'holiday_name': 'Rosh Hashana II', + 'hebrew_holiday_name': "ב' ראש השנה"}), + make_jerusalem_test_params( + dt(2017, 9, 23, 8, 25), + {'upcoming_candle_lighting': dt(2017, 9, 20, 18, 23), + 'upcoming_havdalah': dt(2017, 9, 23, 19, 13), + 'upcoming_shabbat_candle_lighting': dt(2017, 9, 22, 19, 14), + 'upcoming_shabbat_havdalah': dt(2017, 9, 23, 19, 13), + 'weekly_portion': "Ha'Azinu", + 'hebrew_weekly_portion': 'האזינו', + 'holiday_name': '', + 'hebrew_holiday_name': ''}), + ] + + shabbat_test_ids = [ + "currently_first_shabbat", + "currently_first_shabbat_with_havdalah_offset", + "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", + # Type 1 = Sat/Sun/Mon + "currently_first_day_of_three_day_type1_yomtov_in_diaspora", + "currently_second_day_of_three_day_type1_yomtov_in_diaspora", + # Type 2 = Thurs/Fri/Sat + "currently_first_day_of_three_day_type2_yomtov_in_israel", + "currently_second_day_of_three_day_type2_yomtov_in_israel", + "currently_third_day_of_three_day_type2_yomtov_in_israel", + ] + + @pytest.mark.parametrize(["now", "candle_lighting", "havdalah", "diaspora", + "tzname", "latitude", "longitude", "result"], + shabbat_params, ids=shabbat_test_ids) + def test_shabbat_times_sensor(self, now, candle_lighting, havdalah, + diaspora, tzname, latitude, longitude, + result): + """Test sensor output for upcoming shabbat/yomtov times.""" + time_zone = get_time_zone(tzname) + set_default_time_zone(time_zone) + test_time = time_zone.localize(now) + for sensor_type, value in result.items(): + if isinstance(value, dt): + result[sensor_type] = time_zone.localize(value) + self.hass.config.latitude = latitude + self.hass.config.longitude = longitude + + if ('upcoming_shabbat_candle_lighting' in result + and 'upcoming_candle_lighting' not in result): + result['upcoming_candle_lighting'] = \ + result['upcoming_shabbat_candle_lighting'] + if ('upcoming_shabbat_havdalah' in result + and 'upcoming_havdalah' not in result): + result['upcoming_havdalah'] = result['upcoming_shabbat_havdalah'] + + for sensor_type, result_value in result.items(): + language = 'english' + if sensor_type.startswith('hebrew_'): + language = 'hebrew' + sensor_type = sensor_type.replace('hebrew_', '') + sensor = JewishCalSensor( + name='test', language=language, sensor_type=sensor_type, + latitude=latitude, longitude=longitude, + timezone=time_zone, diaspora=diaspora, + havdalah_offset=havdalah, + candle_lighting_offset=candle_lighting) + sensor.hass = self.hass + with patch('homeassistant.util.dt.now', return_value=test_time): + run_coroutine_threadsafe( + sensor.async_update(), + self.hass.loop).result() + assert sensor.state == result_value, "Value for {}".format( + sensor_type) + + melacha_params = [ + make_nyc_test_params(dt(2018, 9, 1, 16, 0), True), + make_nyc_test_params(dt(2018, 9, 1, 20, 21), False), + make_nyc_test_params(dt(2018, 9, 7, 13, 1), False), + make_nyc_test_params(dt(2018, 9, 8, 21, 25), False), + make_nyc_test_params(dt(2018, 9, 9, 21, 25), True), + make_nyc_test_params(dt(2018, 9, 10, 21, 25), True), + make_nyc_test_params(dt(2018, 9, 28, 21, 25), True), + make_nyc_test_params(dt(2018, 9, 29, 21, 25), False), + make_nyc_test_params(dt(2018, 9, 30, 21, 25), True), + make_nyc_test_params(dt(2018, 10, 1, 21, 25), True), + make_jerusalem_test_params(dt(2018, 9, 29, 21, 25), False), + make_jerusalem_test_params(dt(2018, 9, 30, 21, 25), True), + make_jerusalem_test_params(dt(2018, 10, 1, 21, 25), False), + ] + 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) + def test_issur_melacha_sensor(self, now, candle_lighting, havdalah, + diaspora, tzname, latitude, longitude, + result): + """Test Issur Melacha sensor output.""" + time_zone = get_time_zone(tzname) + set_default_time_zone(time_zone) + test_time = time_zone.localize(now) + self.hass.config.latitude = latitude + self.hass.config.longitude = longitude + sensor = JewishCalSensor( + name='test', language='english', + sensor_type='issur_melacha_in_effect', + latitude=latitude, longitude=longitude, + timezone=time_zone, diaspora=diaspora, havdalah_offset=havdalah, + candle_lighting_offset=candle_lighting) sensor.hass = self.hass with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe(