Update "issur_melacha_in_effect" via time tracking (#42485)

pull/48922/head
amitfin 2021-04-09 13:26:55 +03:00 committed by GitHub
parent 52e8c7166b
commit 2391134d26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 236 additions and 25 deletions

View File

@ -1,7 +1,11 @@
"""Support for Jewish Calendar binary sensors."""
import datetime as dt
import hdate
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.core import callback
from homeassistant.helpers import event
import homeassistant.util.dt as dt_util
from . import DOMAIN, SENSOR_TYPES
@ -32,8 +36,8 @@ class JewishCalendarBinarySensor(BinarySensorEntity):
self._hebrew = data["language"] == "hebrew"
self._candle_lighting_offset = data["candle_lighting_offset"]
self._havdalah_offset = data["havdalah_offset"]
self._state = False
self._prefix = data["prefix"]
self._update_unsub = None
@property
def icon(self):
@ -53,11 +57,16 @@ class JewishCalendarBinarySensor(BinarySensorEntity):
@property
def is_on(self):
"""Return true if sensor is on."""
return self._state
return self._get_zmanim().issur_melacha_in_effect
async def async_update(self):
"""Update the state of the sensor."""
zmanim = hdate.Zmanim(
@property
def should_poll(self):
"""No polling needed."""
return False
def _get_zmanim(self):
"""Return the Zmanim object for now()."""
return hdate.Zmanim(
date=dt_util.now(),
location=self._location,
candle_lighting_offset=self._candle_lighting_offset,
@ -65,4 +74,31 @@ class JewishCalendarBinarySensor(BinarySensorEntity):
hebrew=self._hebrew,
)
self._state = zmanim.issur_melacha_in_effect
async def async_added_to_hass(self):
"""Run when entity about to be added to hass."""
await super().async_added_to_hass()
self._schedule_update()
@callback
def _update(self, now=None):
"""Update the state of the sensor."""
self._update_unsub = None
self._schedule_update()
self.async_write_ha_state()
def _schedule_update(self):
"""Schedule the next update of the sensor."""
now = dt_util.now()
zmanim = self._get_zmanim()
update = zmanim.zmanim["sunrise"] + dt.timedelta(days=1)
candle_lighting = zmanim.candle_lighting
if candle_lighting is not None and now < candle_lighting < update:
update = candle_lighting
havdalah = zmanim.havdalah
if havdalah is not None and now < havdalah < update:
update = havdalah
if self._update_unsub:
self._update_unsub()
self._update_unsub = event.async_track_point_in_time(
self.hass, self._update, update
)

View File

@ -19,19 +19,118 @@ from . import (
from tests.common import async_fire_time_changed
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),
make_nyc_test_params(
dt(2018, 9, 1, 16, 0),
{
"state": STATE_ON,
"update": dt(2018, 9, 1, 20, 14),
"new_state": STATE_OFF,
},
),
make_nyc_test_params(
dt(2018, 9, 1, 20, 21),
{
"state": STATE_OFF,
"update": dt(2018, 9, 2, 6, 21),
"new_state": STATE_OFF,
},
),
make_nyc_test_params(
dt(2018, 9, 7, 13, 1),
{
"state": STATE_OFF,
"update": dt(2018, 9, 7, 19, 4),
"new_state": STATE_ON,
},
),
make_nyc_test_params(
dt(2018, 9, 8, 21, 25),
{
"state": STATE_OFF,
"update": dt(2018, 9, 9, 6, 27),
"new_state": STATE_OFF,
},
),
make_nyc_test_params(
dt(2018, 9, 9, 21, 25),
{
"state": STATE_ON,
"update": dt(2018, 9, 10, 6, 28),
"new_state": STATE_ON,
},
),
make_nyc_test_params(
dt(2018, 9, 10, 21, 25),
{
"state": STATE_ON,
"update": dt(2018, 9, 11, 6, 29),
"new_state": STATE_ON,
},
),
make_nyc_test_params(
dt(2018, 9, 11, 11, 25),
{
"state": STATE_ON,
"update": dt(2018, 9, 11, 19, 57),
"new_state": STATE_OFF,
},
),
make_nyc_test_params(
dt(2018, 9, 29, 16, 25),
{
"state": STATE_ON,
"update": dt(2018, 9, 29, 19, 25),
"new_state": STATE_OFF,
},
),
make_nyc_test_params(
dt(2018, 9, 29, 21, 25),
{
"state": STATE_OFF,
"update": dt(2018, 9, 30, 6, 48),
"new_state": STATE_OFF,
},
),
make_nyc_test_params(
dt(2018, 9, 30, 21, 25),
{
"state": STATE_ON,
"update": dt(2018, 10, 1, 6, 49),
"new_state": STATE_ON,
},
),
make_nyc_test_params(
dt(2018, 10, 1, 21, 25),
{
"state": STATE_ON,
"update": dt(2018, 10, 2, 6, 50),
"new_state": STATE_ON,
},
),
make_jerusalem_test_params(
dt(2018, 9, 29, 21, 25),
{
"state": STATE_OFF,
"update": dt(2018, 9, 30, 6, 29),
"new_state": STATE_OFF,
},
),
make_jerusalem_test_params(
dt(2018, 10, 1, 11, 25),
{
"state": STATE_ON,
"update": dt(2018, 10, 1, 19, 2),
"new_state": STATE_OFF,
},
),
make_jerusalem_test_params(
dt(2018, 10, 1, 21, 25),
{
"state": STATE_OFF,
"update": dt(2018, 10, 2, 6, 31),
"new_state": STATE_OFF,
},
),
]
MELACHA_TEST_IDS = [
@ -40,7 +139,8 @@ MELACHA_TEST_IDS = [
"friday_upcoming_shabbat",
"upcoming_rosh_hashana",
"currently_rosh_hashana",
"second_day_rosh_hashana",
"second_day_rosh_hashana_night",
"second_day_rosh_hashana_day",
"currently_shabbat_chol_hamoed",
"upcoming_two_day_yomtov_in_diaspora",
"currently_first_day_of_two_day_yomtov_in_diaspora",
@ -103,13 +203,9 @@ async def test_issur_melacha_sensor(
)
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
== result["state"]
)
entity = registry.async_get("binary_sensor.test_issur_melacha_in_effect")
target_uid = "_".join(
@ -129,3 +225,82 @@ async def test_issur_melacha_sensor(
)
)
assert entity.unique_id == target_uid
with alter_time(result["update"]):
async_fire_time_changed(hass, result["update"])
await hass.async_block_till_done()
assert (
hass.states.get("binary_sensor.test_issur_melacha_in_effect").state
== result["new_state"]
)
@pytest.mark.parametrize(
[
"now",
"candle_lighting",
"havdalah",
"diaspora",
"tzname",
"latitude",
"longitude",
"result",
],
[
make_nyc_test_params(
dt(2020, 10, 23, 17, 46, 59, 999999), [STATE_OFF, STATE_ON]
),
make_nyc_test_params(
dt(2020, 10, 24, 18, 44, 59, 999999), [STATE_ON, STATE_OFF]
),
],
ids=["before_candle_lighting", "before_havdalah"],
)
async def test_issur_melacha_sensor_update(
hass,
legacy_patchable_time,
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()
assert (
hass.states.get("binary_sensor.test_issur_melacha_in_effect").state
== result[0]
)
test_time += timedelta(microseconds=1)
with alter_time(test_time):
async_fire_time_changed(hass, test_time)
await hass.async_block_till_done()
assert (
hass.states.get("binary_sensor.test_issur_melacha_in_effect").state
== result[1]
)