Jewish calendar sensor (#16393)
* Initial commit for jewish calendar sensor * Make check for logging errors into it's own function * Can't use f-strings as we need to support python3.5 * Implement basic functionality: printing of date * Update requirements_all.txt * Allow user to specify date for sensor * Add hdate to test requirements * Update to match pull request * Support date output in hebrew * Limit languages to english and hebrew * Add name back to sensor * Change icon to be calendar-today * Add multiple sensors * Fix tests * Make Hound happy, remove unused imported class * hdate expects datetime.date not datetime.datetime * Return sensor name * Times should be returned as time object, not datetime * Add myself to codeowners for jewish calendar component * Return actual reading, not index * Add more tests. Currently failing. Will need to update hdate API and version before continuing. * Fix weekly portion test * Make all tests pass * Make travis happy and add a test so it doesnt happen again * Remove defaults in __init__ method * Change sensor state variable to local variable in update() method * Minor changespull/16568/merge
parent
4b30cbbf3b
commit
25712f16b3
|
@ -72,6 +72,7 @@ homeassistant/components/sensor/airvisual.py @bachya
|
|||
homeassistant/components/sensor/filter.py @dgomes
|
||||
homeassistant/components/sensor/gearbest.py @HerrHofrat
|
||||
homeassistant/components/sensor/irish_rail_transport.py @ttroy50
|
||||
homeassistant/components/sensor/jewish_calendar.py @tsvi
|
||||
homeassistant/components/sensor/miflora.py @danielhiversen @ChristianKuehnel
|
||||
homeassistant/components/sensor/nsw_fuel_station.py @nickw444
|
||||
homeassistant/components/sensor/pollen.py @bachya
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
"""
|
||||
Platform to retrieve Jewish calendar information for Home Assistant.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/sensor.jewish_calendar/
|
||||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
REQUIREMENTS = ['hdate==0.6.3']
|
||||
|
||||
_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'],
|
||||
}
|
||||
|
||||
CONF_DIASPORA = 'diaspora'
|
||||
CONF_LANGUAGE = 'language'
|
||||
CONF_SENSORS = 'sensors'
|
||||
|
||||
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_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)
|
||||
|
||||
if None in (latitude, longitude):
|
||||
_LOGGER.error("Latitude or longitude not set in Home Assistant config")
|
||||
return
|
||||
|
||||
dev = []
|
||||
for sensor_type in config[CONF_SENSORS]:
|
||||
dev.append(JewishCalSensor(
|
||||
name, language, sensor_type, latitude, longitude, diaspora))
|
||||
async_add_entities(dev, True)
|
||||
|
||||
|
||||
class JewishCalSensor(Entity):
|
||||
"""Representation of an Jewish calendar sensor."""
|
||||
|
||||
def __init__(
|
||||
self, name, language, sensor_type, latitude, longitude, diaspora):
|
||||
"""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._state = None
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.diaspora = diaspora
|
||||
_LOGGER.debug("Sensor %s initialized", self.type)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return '{} {}'.format(self.client_name, self._name)
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Icon to display in the front end."""
|
||||
return SENSOR_TYPES[self.type][1]
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
async def async_update(self):
|
||||
"""Update the state of the sensor."""
|
||||
import hdate
|
||||
|
||||
today = dt_util.now().date()
|
||||
|
||||
date = hdate.HDate(
|
||||
today, diaspora=self.diaspora, hebrew=self._hebrew)
|
||||
|
||||
if self.type == 'date':
|
||||
self._state = hdate.date.get_hebrew_date(
|
||||
date.h_day, date.h_month, date.h_year, hebrew=self._hebrew)
|
||||
elif self.type == 'weekly_portion':
|
||||
self._state = hdate.date.get_parashe(
|
||||
date.get_reading(self.diaspora), hebrew=self._hebrew)
|
||||
elif self.type == 'holiday_name':
|
||||
try:
|
||||
self._state = next(
|
||||
x.description[self._hebrew].long
|
||||
for x in hdate.htables.HOLIDAYS
|
||||
if x.index == date.get_holyday())
|
||||
except StopIteration:
|
||||
self._state = None
|
||||
elif self.type == 'holyness':
|
||||
self._state = hdate.date.get_holyday_type(date.get_holyday())
|
||||
else:
|
||||
times = hdate.Zmanim(
|
||||
date=today,
|
||||
latitude=self.latitude, longitude=self.longitude,
|
||||
hebrew=self._hebrew).zmanim
|
||||
self._state = times[self.type].time()
|
||||
|
||||
_LOGGER.debug("New value: %s", self._state)
|
|
@ -435,6 +435,9 @@ haversine==0.4.5
|
|||
# homeassistant.components.mqtt.server
|
||||
hbmqtt==0.9.4
|
||||
|
||||
# homeassistant.components.sensor.jewish_calendar
|
||||
hdate==0.6.3
|
||||
|
||||
# homeassistant.components.climate.heatmiser
|
||||
heatmiserV3==0.9.1
|
||||
|
||||
|
|
|
@ -80,6 +80,9 @@ haversine==0.4.5
|
|||
# homeassistant.components.mqtt.server
|
||||
hbmqtt==0.9.4
|
||||
|
||||
# homeassistant.components.sensor.jewish_calendar
|
||||
hdate==0.6.3
|
||||
|
||||
# homeassistant.components.binary_sensor.workday
|
||||
holidays==0.9.7
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ TEST_REQUIREMENTS = (
|
|||
'ha-ffmpeg',
|
||||
'haversine',
|
||||
'hbmqtt',
|
||||
'hdate',
|
||||
'holidays',
|
||||
'home-assistant-frontend',
|
||||
'homematicip',
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
"""The tests for the Jewish calendar sensor platform."""
|
||||
import unittest
|
||||
from datetime import datetime as dt
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.util.async_ import run_coroutine_threadsafe
|
||||
from homeassistant.setup import setup_component
|
||||
from homeassistant.components.sensor.jewish_calendar import JewishCalSensor
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
||||
class TestJewishCalenderSensor(unittest.TestCase):
|
||||
"""Test the Jewish Calendar sensor."""
|
||||
|
||||
TEST_LATITUDE = 31.778
|
||||
TEST_LONGITUDE = 35.235
|
||||
|
||||
def setUp(self):
|
||||
"""Set up things to run when tests begin."""
|
||||
self.hass = get_test_home_assistant()
|
||||
|
||||
def tearDown(self):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
def checkForLoggingErrors(self):
|
||||
"""Check whether logger spitted out errors."""
|
||||
errors = [rec for rec in self.cm.records if rec.levelname == "ERROR"]
|
||||
self.assertFalse(errors, ("Logger reported error(s): ",
|
||||
[err.getMessage() for err in errors]))
|
||||
|
||||
def test_jewish_calendar_min_config(self):
|
||||
"""Test minimum jewish calendar configuration."""
|
||||
config = {
|
||||
'sensor': {
|
||||
'platform': 'jewish_calendar'
|
||||
}
|
||||
}
|
||||
with self.assertLogs() as self.cm:
|
||||
assert setup_component(self.hass, 'sensor', config)
|
||||
self.checkForLoggingErrors()
|
||||
|
||||
def test_jewish_calendar_hebrew(self):
|
||||
"""Test jewish calendar sensor with language set to hebrew."""
|
||||
config = {
|
||||
'sensor': {
|
||||
'platform': 'jewish_calendar',
|
||||
'language': 'hebrew',
|
||||
}
|
||||
}
|
||||
with self.assertLogs() as self.cm:
|
||||
assert setup_component(self.hass, 'sensor', config)
|
||||
self.checkForLoggingErrors()
|
||||
|
||||
def test_jewish_calendar_multiple_sensors(self):
|
||||
"""Test jewish calendar sensor with multiple sensors setup."""
|
||||
config = {
|
||||
'sensor': {
|
||||
'platform': 'jewish_calendar',
|
||||
'sensors': [
|
||||
'date', 'weekly_portion', 'holiday_name',
|
||||
'holyness', 'first_light', 'gra_end_shma',
|
||||
'mga_end_shma', 'plag_mincha', 'first_stars'
|
||||
]
|
||||
}
|
||||
}
|
||||
with self.assertLogs() as self.cm:
|
||||
assert setup_component(self.hass, 'sensor', config)
|
||||
self.checkForLoggingErrors()
|
||||
|
||||
def test_jewish_calendar_sensor_date_output(self):
|
||||
"""Test Jewish calendar sensor date output."""
|
||||
test_time = dt(2018, 9, 3)
|
||||
sensor = JewishCalSensor(
|
||||
name='test', language='english', sensor_type='date',
|
||||
latitude=self.TEST_LATITUDE, longitude=self.TEST_LONGITUDE,
|
||||
diaspora=False)
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
run_coroutine_threadsafe(
|
||||
sensor.async_update(),
|
||||
self.hass.loop).result()
|
||||
self.assertEqual(sensor.state, '23 Elul 5778')
|
||||
|
||||
def test_jewish_calendar_sensor_date_output_hebrew(self):
|
||||
"""Test Jewish calendar sensor date output in hebrew."""
|
||||
test_time = dt(2018, 9, 3)
|
||||
sensor = JewishCalSensor(
|
||||
name='test', language='hebrew', sensor_type='date',
|
||||
latitude=self.TEST_LATITUDE, longitude=self.TEST_LONGITUDE,
|
||||
diaspora=False)
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
run_coroutine_threadsafe(
|
||||
sensor.async_update(),
|
||||
self.hass.loop).result()
|
||||
self.assertEqual(sensor.state, "כ\"ג באלול ה\' תשע\"ח")
|
||||
|
||||
def test_jewish_calendar_sensor_holiday_name(self):
|
||||
"""Test Jewish calendar sensor date output in hebrew."""
|
||||
test_time = dt(2018, 9, 10)
|
||||
sensor = JewishCalSensor(
|
||||
name='test', language='hebrew', sensor_type='holiday_name',
|
||||
latitude=self.TEST_LATITUDE, longitude=self.TEST_LONGITUDE,
|
||||
diaspora=False)
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
run_coroutine_threadsafe(
|
||||
sensor.async_update(),
|
||||
self.hass.loop).result()
|
||||
self.assertEqual(sensor.state, "א\' ראש השנה")
|
||||
|
||||
def test_jewish_calendar_sensor_holyness(self):
|
||||
"""Test Jewish calendar sensor date output in hebrew."""
|
||||
test_time = dt(2018, 9, 10)
|
||||
sensor = JewishCalSensor(
|
||||
name='test', language='hebrew', sensor_type='holyness',
|
||||
latitude=self.TEST_LATITUDE, longitude=self.TEST_LONGITUDE,
|
||||
diaspora=False)
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
run_coroutine_threadsafe(
|
||||
sensor.async_update(),
|
||||
self.hass.loop).result()
|
||||
self.assertEqual(sensor.state, 1)
|
||||
|
||||
def test_jewish_calendar_sensor_torah_reading(self):
|
||||
"""Test Jewish calendar sensor date output in hebrew."""
|
||||
test_time = dt(2018, 9, 8)
|
||||
sensor = JewishCalSensor(
|
||||
name='test', language='hebrew', sensor_type='weekly_portion',
|
||||
latitude=self.TEST_LATITUDE, longitude=self.TEST_LONGITUDE,
|
||||
diaspora=False)
|
||||
with patch('homeassistant.util.dt.now', return_value=test_time):
|
||||
run_coroutine_threadsafe(
|
||||
sensor.async_update(),
|
||||
self.hass.loop).result()
|
||||
self.assertEqual(sensor.state, "פרשת נצבים")
|
Loading…
Reference in New Issue