Entities Calendar - turn your entities into a calendar

This project started off with me creating a custom Lovelace Calendar card, based on FullCalender.io, but then HA 0.110 came along with its new Calendar panel ironically also based on FullCalendar.io. The only thing my card added, was support for displaying entities as well as calendars. So, I decided to turn that functionality into a custom component:

The component will allow you to create calendars based on entities, which will then show in the new Calendar panel.

This is not currently added as a default repository in HACS, but you can add it is a custom repository
Edit: Now available as a default repository in HACS, simply search for “Entities Calendar”

Here is an example of the config:

calendar:
  - platform: entities_calendar
    calendars:
      - name: Bin Collection
        entities:
          - entity: sensor.bin_collection_general
            name: General Waste Collection
          - entity: sensor.bin_collection_recycling
            name: Recycling Collection
          - entity: sensor.bin_collection_garden
            name: Garden Waste Collection
      - name: Other Calendar
        entities:
          - entity: sensor.date
            name: Today

This initial release only fully supports sensors with a device_class of “timestamp”.
These will create all-day calendar events using the state of the sensor as the date.

Other entity types can be used, but these will create all-day events based on the last_changed attribute.
Support for other types of sensors (and for events which are not all-day) may be added in future releases.

7 Likes

Version 0.0.3 has been released (0.0.2 was a metadata only release to allow it to be added as a default repository to HACS) with a fix to filter out timestamp entities with a state of “unknown” or “unavailable” (these would previously prevent the calendar from loading).

I have release a beta version, 0.0.4b1, with a new feature allowing you to have more control over the of start and end time of calendar event. This is done via two options start_time and end_time on the entity, which take a time object:

time object

Option Description
timestamp_in_state (Optional) Setting this to true forces the state to be used for the start/end time event if the device class is not “timestamp”
timestamp_attribute (Optional) Setting this to the name of an attribute will use that for the time (even for “timestamp”) entities

Example

Given three sensors:

  • sensor.attribute_test - a sensor with a start_time and end_time attribute
  • sensor.state_test - a sensor with a timestamp in the state but without a device_class of “timestamp”
  • sensor.default_test - a sensor with a device_class of “timestamp”

The following configuration would be used:

calendar:
  - platform: entities_calendar
    calendars:
      - name: Entities
        entities:
          - entity: sensor.attribute_test
            name: Attribute Test
            start_time:
              timestamp_attribute: start_time
            end_time:
              timestamp_attribute: end_time
          - entity: sensor.state_test
            name: State Test
            start_time:
              timestamp_in_state: true
            end_time:
              timestamp_in_state: true
          - entity: sensor.default_test
            name: Default Test

If start_time or end_time are not used they default to using the state (if device_class is “timestamp”) or the last_changed property.

You can even mix and match states and attributes so, for example, if you have a sensor which has the start time in the state and the end time in an attribute you would use:

calendar:
  - platform: entities_calendar
    calendars:
      - name: Entities
        entities:
          - entity: sensor.combined_test
            name: Combined
            start_time:
              timestamp_in_state: true
            end_time:
              timestamp_attribute: end_time

Or, if it has a device_class of “timestamp”, just:

calendar:
  - platform: entities_calendar
    calendars:
      - name: Entities
        entities:
          - entity: sensor.combined_test
            name: Combined
            end_time:
              timestamp_attribute: end_time

am i missing something

I have

calendar:
  - platform: entities_calendar
    calendars:
      - name: Roster Calendar
        entities:
          - entity: sensor.stephan_4x4x12
            start_time:
              timestamp_attribute: start_time
            end_time:
              timestamp_attribute: end_time

when i do a Check Im getting this

Invalid config for [calendar.entities_calendar]: [start_time] is an invalid option for [calendar.entities_calendar]. Check: calendar.entities_calendar->calendars->0->entities->0->start_time. (See ?, line ?). 

and the sensor look like

image

image

which I build up from Python Script I wrote that runs when HA starts

if i do this

calendar:
  - platform: entities_calendar
    calendars:
      - name: Roster Calendar
        entities:
          - entity: sensor.stephan_4x4x12
#            start_time:
#              timestamp_attribute: start_time
#            end_time:
#              timestamp_attribute: end_time

the check PASSES

but nothing in calendar I know as the sensor has a on/off status
which breaks the calendar ie no data is displayed

if I do this
image

i get

What am i missing

FIT IT added a name:

also manually down loaded a fresh copy

Roster day on the 8th is what I want to See

THANKS

The new feature was in a beta release, so it looks like you didn’t have betas enabled for this integration in HACS. Manually downloading from the master branch of the repository, if that’s what you did, would also have fixed it because the beta was based on the master branch.

To enable betas for an integration in HACS you need to:

  • Open HACS
  • Find the integration you want to enable betas for
  • Click the three dots menu button
  • Select Reinstall from the menu
  • Toggle on “Show beta versions”
  • Select the latest beta version from the dropdown (in this case 0.0.4b1)
  • Click Install

From then on HACS should notify you of any updates to that integration, even betas.

All good bro

one Question
if there is a message attribute could that replace the name bit
image

where i have ‘stephan work’ is the name:

but as the sensor knows that im on holiday I have put in to the message part of the attribute
bee cool to show it there

looking at the code dont know where to change it still get my head around the python stuff
most of the time im breaking it love the ctrl+z

Thanks again for your hard work.

That’s not possible currently, but it’s a good idea. I’ll see what I can do.
You can possibly work around this for now by creating a template sensor. For example:

sensor:
  - platform: template
    sensors:
      stephan_work:
        value_template: '{{ states("sensor.stephan_4x4x12") }}'
        friendly_name_template: '{{ state_attr("sensor.stephan_4x4x12", "message") }}'
        attribute_templates:
          start_time: '{{ state_attr("sensor.stephan_4x4x12", "start_time") }}'
          end_time: '{{ state_attr("sensor.stephan_4x4x12", "end_time") }}'

That would create a sensor called sensor.stephan_work which picks up the start_time and end_time attributes from the original sensor and sets the friendly name based on the message. You would then use that sensor in the calendar instead of the original.

1 Like

arrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr

like your thinking

10 out 10 bro

thanks
play some more

can’t get the friendly_name to work
if I take the name: out of the config i get this

and nothing show up in calendar

putting name back in I see the name in the config not the friendly_name

image

Can you try updating to the latest release version, 0.0.4, which should fix this issue?

that it

:beers:

WORKING

hay was it line 227 and 249 you change

Yes, those were the lines :slight_smile:

1 Like

I have release version 0.0.5 now.
This has one new feature and one fix.

Added support for non-allday events

It will determine if an event is all-day as follows:

  • If timestamp is a date only, or a date with a time of midnight it will be treated as allday
  • anything else will be treated as non-allday

This may sometimes be incorrect (e.g. due to time zones or daylight saving). In this case you can override the default handling by using the new all_day option for entities, for example:

calendar:
  - platform: entities_calendar
    calendars:
      - name: Test
        entities:
          - entity: sensor.not_allday
            name: Not All Day
            all_day: false
          - entity: sensor.allday
            name: All Day
            all_day: true

Improved handling of missing entities, states, or attributes

If any entities or their states or attributes are missing (unavailable or None) they will be filtered out until they are available.

I’m using a modified version of mf_social’s date_countdown technique to produce “countdown sensors” that look like this:

The sensor’s state shows the number of days remaining until the event (John’s birthday). “Days remaining” is a very handy value but it’s not the timestamp your Entities Calendar integration needs to use this sensor (plus the sensor lacks a timestamp device_class).

What this countdown sensor does have is a date attribute that could be used to represent an all-day event. However, I’ve been unable to find the correct combination of options to make it work. For example, I tried this:

            start_time:
              timestamp_attribute: date

but that failed to work. I then added this:

            end_time:
              timestamp_attribute: date

but the combination made no improvement nor did adding all_day: true.

My guess is what I’m attempting to do (use the sensor’s date attribute to represent an all-day event) is not currently supported. Or is there some successful combination I haven’t tried?

FWIW, I have control over the countdown sensor’s design so I could easily swap the values in state and date (i.e. the state would hold the event’s date and an attribute would report the remaining days until the event date) plus add a device_class: timestamp.

Although it would satisfy the needs of Entities Calendar, it would eliminate the convenience of seeing the countdown in the States column (and bury it within Attributes). Not horrible but awkward considering it’s supposed to be a countdown sensor.

What would be handy is a dedicated option to specify which attribute to use in order to create an all-day event.

think you have to have the

timestamp_attribute:

in a right time format

“YYYY-MM-DD HH:MM:SS”

With that example, the date attribute appears to be the date they were born, rather than their next birthday. It looks like there is also a nextoccur attribute, which looks like the one you would need, so:

start_time:
  timestamp_attribute: nextoccur
end_time:
  timestamp_attribute: nextoccur

should do the trick.

You shouldn’t need to worry about the timestamp format, entities_calendar works OK with date-only timestamps.

1 Like

Thanks! Came back to say that, after some experimentation, it occurred to me that it can’t assume anything about a given date (like, it’s a birthday so it recurs every year). So, duh, just specifying a birth date won’t make it magically appear every year in the Calendar view. :man_facepalming:

I proved that to myself using a simple Template Sensor like this:

      event_birthday_ed:
        friendly_name: "Ed's birthday"
        value_template: "2020-08-05"
        device_class: "timestamp

That automatically appears in the Calendar view, as an all-day event, using this:

calendar:
  - platform: entities_calendar
    calendars:
      - name: Birthday
        entities:
          - entity: sensor.event_birthday_ed

OK, so now that’s clear in my mind, it’s clear I have to use nextoccur.

I don’t mean to sound lazy and ungrateful but it would be nice if there was a single option to specify an all-day event, based on a single attribute, as opposed to pointing two options (start_time and end_time) to the same attribute. For example, specifying just start_time alone, without an end_time, would default to creating an all-day event. This would be all that’s needed to do the trick:

start_time:
  timestamp_attribute: nextoccur

I’ve checked the logic and, you shouldn’t need the end_time option if you are creating all-day events which only cover a single day. If the end_time option is not present, it just uses the same settings as for start_time. Have you tried with just start_time defined?

Not yet but I will (later; on mobile now and on the run). Thanks again!