Skip to content

Commit

Permalink
Update "issur_melacha_in_effect" via time tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
amitfin committed Jan 13, 2021
1 parent e05bb7e commit c8d0a53
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 26 deletions.
46 changes: 40 additions & 6 deletions homeassistant/components/jewish_calendar/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -32,8 +36,8 @@ def __init__(self, data, sensor, sensor_info):
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._next_update = None

@property
def icon(self):
Expand All @@ -53,16 +57,46 @@ def name(self):
@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,
havdalah_offset=self._havdalah_offset,
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
async def _update(self, now=None):
"""Update the state of the sensor."""
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._next_update == update:
return
self._next_update = update
event.async_track_point_in_time(self.hass, self._update, update)
198 changes: 178 additions & 20 deletions tests/components/jewish_calendar/test_binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,108 @@
make_nyc_test_params,
)

from tests.async_mock import patch
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),
},
),
make_nyc_test_params(
dt(2018, 9, 1, 20, 21),
{
"state": STATE_OFF,
"update": dt(2018, 9, 2, 6, 21),
},
),
make_nyc_test_params(
dt(2018, 9, 7, 13, 1),
{
"state": STATE_OFF,
"update": dt(2018, 9, 7, 19, 4),
},
),
make_nyc_test_params(
dt(2018, 9, 8, 21, 25),
{
"state": STATE_OFF,
"update": dt(2018, 9, 9, 6, 27),
},
),
make_nyc_test_params(
dt(2018, 9, 9, 21, 25),
{
"state": STATE_ON,
"update": dt(2018, 9, 10, 6, 28),
},
),
make_nyc_test_params(
dt(2018, 9, 10, 21, 25),
{
"state": STATE_ON,
"update": dt(2018, 9, 11, 6, 29),
},
),
make_nyc_test_params(
dt(2018, 9, 11, 11, 25),
{
"state": STATE_ON,
"update": dt(2018, 9, 11, 19, 57),
},
),
make_nyc_test_params(
dt(2018, 9, 29, 16, 25),
{
"state": STATE_ON,
"update": dt(2018, 9, 29, 19, 25),
},
),
make_nyc_test_params(
dt(2018, 9, 29, 21, 25),
{
"state": STATE_OFF,
"update": dt(2018, 9, 30, 6, 48),
},
),
make_nyc_test_params(
dt(2018, 9, 30, 21, 25),
{
"state": STATE_ON,
"update": dt(2018, 10, 1, 6, 49),
},
),
make_nyc_test_params(
dt(2018, 10, 1, 21, 25),
{
"state": STATE_ON,
"update": dt(2018, 10, 2, 6, 50),
},
),
make_jerusalem_test_params(
dt(2018, 9, 29, 21, 25),
{
"state": STATE_OFF,
"update": dt(2018, 9, 30, 6, 29),
},
),
make_jerusalem_test_params(
dt(2018, 10, 1, 11, 25),
{
"state": STATE_ON,
"update": dt(2018, 10, 1, 19, 2),
},
),
make_jerusalem_test_params(
dt(2018, 10, 1, 21, 25),
{
"state": STATE_OFF,
"update": dt(2018, 10, 2, 6, 31),
},
),
]

MELACHA_TEST_IDS = [
Expand All @@ -39,7 +125,8 @@
"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",
Expand Down Expand Up @@ -86,7 +173,9 @@ async def test_issur_melacha_sensor(

registry = await hass.helpers.entity_registry.async_get_registry()

with alter_time(test_time):
with alter_time(test_time), patch(
"homeassistant.helpers.event.async_track_point_in_time"
) as async_track_point_in_time:
assert await async_setup_component(
hass,
jewish_calendar.DOMAIN,
Expand All @@ -102,13 +191,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(
Expand All @@ -128,3 +213,76 @@ async def test_issur_melacha_sensor(
)
)
assert entity.unique_id == target_uid

assert async_track_point_in_time.call_args[0][2] == result["update"]


@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]
)

0 comments on commit c8d0a53

Please sign in to comment.