I’d like to share my countdown sensor here in hopes that someone might find it useful or have the knowledge to get it properly implemented as a built-in sensor. As you can tell by the screenshots and config, I built this for a specific purpose it is intended for multi-day away events as opposed to being a timer. (it only updates once per minute)
To implement, create a custom_components directory in the root of your Home Assistant directory. Inside that, create a sensor directory. Inside that, create the file sensor.py with the following contents:
"""
Date Countdown
"""
import datetime
from datetime import timedelta
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import CONF_NAME
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
_LOGGER = logging.getLogger(__name__)
ATTR_DAYS = 'days'
ATTR_HOURS = 'hours'
ATTR_MINUTES = 'minutes'
DEFAULT_NAME = "Countdown"
CONF_DATE = 'date'
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=60)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_DATE): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up date countdown sensor."""
end_date = config.get(CONF_DATE)
sensor_name = config.get(CONF_NAME)
add_devices([Countdown(sensor_name, end_date)])
class Countdown(Entity):
"""Implementation of the date countdown sensor."""
def __init__(self, sensor_name, end_date):
"""Initialize the sensor."""
self.end_date = end_date
self._name = sensor_name
self._state = None
self._data = {}
self.update()
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def state(self):
"""Return the state of the sensor."""
return self._state
@property
def device_state_attributes(self):
return {
ATTR_DAYS: self._data.get("days"),
ATTR_HOURS: self._data.get("hours"),
ATTR_MINUTES: self._data.get("minutes")
}
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return 'mdi:calendar'
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Calculate time until end"""
end_date = datetime.datetime.strptime(self.end_date, '%d-%m-%Y %H:%M')
days = (end_date - datetime.datetime.now())
days, seconds = days.days, days.seconds
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60
self._data["days"] = days
self._data["hours"] = hours
self._data["minutes"] = minutes
self._state = str(days) + " days " + str(hours) \
+ " hours " + str(minutes) + " minutes"
Then follow the following format for your configuration/sensors.yaml:
I think you can probably build an automation that keys off the state attributes of the original sensor, but I built an automation for this sensor by adding another template sensor:
EDIT: Oops, this is a different custom component than I thought you were referencing. See Reminder Custom Component. I think this could be almost compatible with the code at the link.
I have started doing this as a real component for HASS. The PR is #9889. It’s still a work in progress and currently more targeted at short timespans (like motion controlled lights). But before someone reads this thread and starts implementing, it seems more efficient to point at an existing effort where collaborative work may lead to a better result.
Very cool. I’ve been following the discussion on Github about a potential timer component. I think this would be a great addition but lack the skills to do it myself. Does your timer persist/remember across restarts of HASS?
Currently not, which is very unfortunate for the usecase where a specific point in time should be tracked. While having lights in mind I didn’t care too much about persistence, but reading this thread it came to my mind. I’ll have a look at that over the weekend.
On top of that I’m still unsure if what this custom component is doing can be replicated 100%. The timer is like an egg-timer where you set a (modifiable) duration where the finished event fires after a specific duration from now. In case of a wedding you actually provide a fixed date, much like an alarm clock. So my component is in comparison more like the egg-timer. It does a similar thing, but in a different way.
I’ll see how my component evolves. Right now I think there should be a second component for tracking fixed dates, and my timer for variable ending times which can easily be extended.
@danielperna84 As your PR was merged recently does that mean my question here could be solved with your component easily in the next Home Assistant (probably 0.57) release?
Yes, that would be a usecase. Currently it is only controlled via services. But using these it would be very simple. You’d set up the timer with the doze time, and then use the state of the timer (active) as a trigger for the automation that mutes the sound. To start the timer, all you have to do is call the timer.start service. Afterwards you unmute either by monitoring the timers state (idle) or you use the timer.finished event as the trigger.