diff --git a/custom_components/flagdays_dk/__init__.py b/custom_components/flagdays_dk/__init__.py index b1e8252..8db3b50 100644 --- a/custom_components/flagdays_dk/__init__.py +++ b/custom_components/flagdays_dk/__init__.py @@ -4,19 +4,21 @@ from .flagdays_dk import flagdays_dk from collections import OrderedDict +from datetime import datetime +from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_DATE from .const import ( - DOMAIN, + CONF_ATTRIBUTE_NAMES, CONF_CLIENT, CONF_EXCLUDE, CONF_FLAGDAYS, CONF_INCLUDE, CONF_OFFSET, CONF_PLATFORM, + DEFAULT_ATTRIBUTE_NAMES, DEFAULT_DATE_FORMAT, DEFAULT_OFFSET, - KEY_DATE, - KEY_FRIENDLY_NAME, + DOMAIN, KEY_NAME, KEY_PRIORITY, ) @@ -38,15 +40,29 @@ async def async_setup(hass, config): exclude=config[DOMAIN].get(CONF_EXCLUDE, []), ) + # Extract attribute names to search for - make it lowercase + attr_names = set([x.lower() for x in config[DOMAIN].get(CONF_ATTRIBUTE_NAMES, [])]) + def flagdayFromSensor(entity): flagdayObj = hass.states.get(customFlagday) - if KEY_DATE in flagdayObj.attributes: + + # Create a list of keys from the attribute names which are present in the attributes + attr_date_keys = list(attr_names.intersection(set(flagdayObj.attributes))) + + # find the first key of type datetime + attr_date_key = None + for date_key in attr_date_keys: + if type(flagdayObj.attributes[date_key]) is datetime: + attr_date_key = date_key + break + + # Did we find a key of datetime type + if attr_date_key: return { - flagdayObj.attributes[KEY_FRIENDLY_NAME]: { - KEY_DATE: flagdayObj.attributes[KEY_DATE].strftime( + flagdayObj.attributes[ATTR_FRIENDLY_NAME]: { + ATTR_DATE: flagdayObj.attributes[attr_date_key].strftime( DEFAULT_DATE_FORMAT - ), - KEY_PRIORITY: priorityCheck(flagdayObj.attributes), + ) } } diff --git a/custom_components/flagdays_dk/const.py b/custom_components/flagdays_dk/const.py index 5df2f21..1c0cb52 100644 --- a/custom_components/flagdays_dk/const.py +++ b/custom_components/flagdays_dk/const.py @@ -1,19 +1,23 @@ +CONF_ATTRIBUTE_NAMES = "attribute_names" CONF_CLIENT = "client" CONF_EXCLUDE = "exclude" CONF_FLAGDAYS = "flagdays" CONF_INCLUDE = "include" CONF_OFFSET = "offset" CONF_PLATFORM = "sensor" + +CREDITS = "J-Lindvig (https://github.com/J-Lindvig)" + +DEFAULT_ATTRIBUTE_NAMES = ["date"] DEFAULT_DATE_FORMAT = "%d-%m-%Y" DEFAULT_OFFSET = 10 -DOMAIN = "flagdays_dk" -UPDATE_INTERVAL = 60 -CREDITS = "J-Lindvig (https://github.com/J-Lindvig)" +DOMAIN = "flagdays_dk" KEY_DATE = "date" KEY_DATE_END = "date_end" KEY_FLAG = "flag" -KEY_FRIENDLY_NAME = "friendly_name" KEY_NAME = "name" KEY_PRIORITY = "priority" + +UPDATE_INTERVAL = 60 diff --git a/custom_components/flagdays_dk/flagdays_dk.py b/custom_components/flagdays_dk/flagdays_dk.py index db58c92..87c56af 100644 --- a/custom_components/flagdays_dk/flagdays_dk.py +++ b/custom_components/flagdays_dk/flagdays_dk.py @@ -1,10 +1,9 @@ from __future__ import annotations -import logging - +from .easter import easter from datetime import datetime from dateutil.relativedelta import relativedelta -from .easter import easter +import logging _LOGGER: logging.Logger = logging.getLogger(__package__) _LOGGER = logging.getLogger(__name__) @@ -197,7 +196,9 @@ def __init__(self, name=str, data=dict): self.halfMast = ( True if self.name == STRINGS["GOOD_FRIDAY"] - else datetime.strptime("12:00", "%H:%M").time() + else datetime.combine( + self.date, datetime.strptime("12:00", "%H:%M").time() + ) ) if name in STRINGS["ROYAL"]: @@ -219,6 +220,4 @@ def getDateEnd(self, dateFormat=None): return self.dateEnd.strftime(dateFormat) def getHalfMast(self, timeFormat="%H:%M"): - if type(self.halfMast) is bool: - return self.halfMast - return self.halfMast.strftime(timeFormat) + return self.halfMast diff --git a/custom_components/flagdays_dk/manifest.json b/custom_components/flagdays_dk/manifest.json index 89af08d..84b5142 100644 --- a/custom_components/flagdays_dk/manifest.json +++ b/custom_components/flagdays_dk/manifest.json @@ -8,5 +8,5 @@ "codeowners": ["@J-Lindvig"], "requirements": ["astral", "requests_html"], "iot_class": "calculated", - "version": "3.0.3" + "version": "3.1" } diff --git a/custom_components/flagdays_dk/sensor.py b/custom_components/flagdays_dk/sensor.py index 028cfc7..41e8db2 100644 --- a/custom_components/flagdays_dk/sensor.py +++ b/custom_components/flagdays_dk/sensor.py @@ -1,12 +1,14 @@ from __future__ import annotations -import logging from astral import Observer from astral.sun import sun from datetime import datetime, timedelta from dateutil import tz -from homeassistant.const import ATTR_ATTRIBUTION +import logging +import pytz + +from homeassistant.const import ATTR_ATTRIBUTION, ATTR_DATE, ATTR_DEVICE_CLASS from .const import ( CONF_CLIENT, CONF_OFFSET, @@ -17,14 +19,12 @@ ) ATTR_CONCURRENT = "concurrent_flagdays" -ATTR_DATE = "date" ATTR_DATE_END = "date_end" -ATTR_FLAGDAY_NAME = "flagday_name" +ATTR_DAYS = "days" ATTR_FLAG = "flag" +ATTR_FLAGDAY_NAME = "flagday_name" ATTR_FLAG_DOWN = "flag_down_time" -ATTR_FLAG_DOWN_TRIGGER = "flag_down_time_trigger" ATTR_FLAG_UP = "flag_up_time" -ATTR_FLAG_UP_TRIGGER = "flag_up_time_trigger" ATTR_HALF_MAST = "half_mast" ATTR_YEARS = "years" @@ -69,6 +69,8 @@ def __init__(self, hass, coordinator, flagdays) -> None: self.coordinator = coordinator self.flagdays = flagdays self.nextFlagday = flagdays.flagdays[0] + self.flagUpTime, self.flagDownTime = 0, 0 + self.entity_id = "sensor.kast_op" @property def name(self): @@ -80,44 +82,46 @@ def icon(self): @property def state(self): - return self.flagdays.days - - @property - def unique_id(self): - return "1708981ec9bb4fbfb5d183771a888af0" - - @property - def extra_state_attributes(self): - # Calculate the sunrise and sunset from the coordinates of the HA server geo = Observer( self.hass.config.latitude, self.hass.config.longitude, self.hass.config.elevation, ) - s = sun( - geo, date=self.nextFlagday.getDate(), tzinfo=tz.gettz("Europe/Copenhagen") - ) - - # Calculate the correct time for flag up - flagUpTime = ( + s = sun(geo, date=self.nextFlagday.date, tzinfo=tz.gettz("Europe/Copenhagen")) + self.flagUpTime = ( datetime.strptime("08:00", "%H:%M") if s["sunrise"].hour < 8 else s["sunrise"] ) + self.flagDownTime = s["sunset"] + dt_now = datetime.now().astimezone(pytz.timezone("Europe/Copenhagen")) + offset = timedelta(minutes=self.hass.data[DOMAIN][CONF_OFFSET]) + + if self.flagUpTime > dt_now: + return self.flagUpTime - offset + elif ( + type(self.nextFlagday.halfMast) is datetime + and self.nextFlagday.halfMast > dt_now + ): + return self.nextFlagday.halfMast - offset + else: + return self.flagDownTime - offset + + @property + def unique_id(self): + return "1708981ec9bb4fbfb5d183771a888af0" + + @property + def extra_state_attributes(self): attr = { ATTR_FLAGDAY_NAME: self.nextFlagday.name, + ATTR_DAYS: self.flagdays.days, ATTR_YEARS: self.nextFlagday.years, ATTR_FLAG: self.nextFlagday.flag, - ATTR_FLAG_UP: flagUpTime.strftime("%H:%M"), - ATTR_FLAG_DOWN: s["sunset"].strftime("%H:%M"), - ATTR_FLAG_UP_TRIGGER: ( - flagUpTime - timedelta(minutes=self.hass.data[DOMAIN][CONF_OFFSET]) - ).strftime("%H:%M"), - ATTR_FLAG_DOWN_TRIGGER: ( - s["sunset"] - timedelta(minutes=self.hass.data[DOMAIN][CONF_OFFSET]) - ).strftime("%H:%M"), - ATTR_HALF_MAST: self.nextFlagday.getHalfMast(), + ATTR_FLAG_UP: self.flagUpTime.strftime("%H:%M"), + ATTR_FLAG_DOWN: self.flagDownTime.strftime("%H:%M"), + ATTR_HALF_MAST: self.nextFlagday.halfMast, ATTR_CONCURRENT: self.flagdays.getConcurrentFlagdays(self.nextFlagday.date), } attr["future_flagdays"] = [] @@ -129,7 +133,7 @@ def extra_state_attributes(self): ATTR_DATE_END: flagday.getDateEnd("%-d-%-m"), } ) - attr[ATTR_ATTRIBUTION] = CREDITS + attr.update({ATTR_DEVICE_CLASS: "timestamp", ATTR_ATTRIBUTION: CREDITS}) return attr @property