Sensor to show expiry date of SSL certificate

If you’re not running HAOS or Supervised you should be able to find a docker container for LE like at linuxserver.io
Also look at Caddy with a DNS validation plugin as I already suggested.

Thanks for that. I’ll see if I can find a docker container for LE. I’m not sure if Caddy is a little more than I need. If I can find a LE docker container that handles auto-renewals would I need Caddy?

It’s totally up to you. I like a reverse proxy for the security it provides.

Does anyone use the isValid attribute? I’m trying to use it as an automation, I have to generate a pks file from the LE cert whenever it updates, but it’s only checking if the cert is valid and not if it’s valid for the URL you are checking on. This should be invalid IMO and consequently means I can’t trigger on isValid when the site shows as invalid SSL cert. If this is expected then I need to find an alternative sensor to determine if the cert is invalid for the site.

Hey everyone, I was trying the solution here, but failed with the sensor. There’ve been some changes to HomeAssistantOS lately.

This works for me:

#############################
########  certbot  ##########
#############################
- platform: template
  sensors:
    days_before_ssl_expiration:
      friendly_name: Days before SSL expiration
      value_template: >-
       {{((as_timestamp(states('sensor.cert_expiry_timestamp_my_domain_name_8123')) - as_timestamp(now())) / 86400) | int }}

After having set up the integration Certificate Expiry, the sensor gives the days till expiry.

And here’s my automation which should work out of the box:

alias: SSL Auto Certbot
description: ''
trigger:
  - platform: state
    entity_id: sensor.days_before_ssl_expiration
    to: '20'
condition: []
action:
  - service: hassio.addon_start
    data:
      addon: core_letsencrypt
  - delay:
      hours: 0
      minutes: 2
      seconds: 0
      milliseconds: 0
  - service: homeassistant.restart
mode: single

hey @CybDis , that sensor works, but i always get this error on restart HA

any idea?

2022-02-13 19:59:18 ERROR (MainThread) [homeassistant.helpers.event] Error while processing template: Template("{{((as_timestamp(states('sensor.cert_expiry_timestamp_XXX_com_8123')) - as_timestamp(now())) / 86400) | int }}")
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 407, in async_render
    render_result = _render_with_context(self.template, compiled, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1814, in _render_with_context
    return template.render(**kwargs)
  File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 1291, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 925, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<template>", line 1, in top-level template code
TypeError: unsupported operand type(s) for -: 'NoneType' and 'float'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 523, in async_render_to_info
    render_info._result = self.async_render(variables, strict=strict, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 409, in async_render
    raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: TypeError: unsupported operand type(s) for -: 'NoneType' and 'float'

I think because cert integration is giving unavaible first upon restart HA, and it cant calculate yet

you’re right, that’s the reason.
There are some discussions/solutions where it’s possible to check for ‘unavailable’ and then not cast it to float, but I was too lazy to implement that and just accept the error.

Here’s a possible fix, if you want to try: Issues with a template after update to 2021-10-0 - #2 by koying

yeah, already fixed :slight_smile:

would you mind sharing?

sure:

  - platform: template
    sensors:
      ssl_expiration:
        friendly_name: Days before SSL expiration
        unit_of_measurement: Days
        value_template: >-
          {{ ( ( states('sensor.cert_expiry_timestamp_xxx_8123') | as_timestamp(0) - now().timestamp() ) / 86400 ) | round(0) }}

I got annoy by cert error on start as some of the service is still down during home assistant startup… thus, here my template checking for validity, otherwise unknown

    hass_cert:
      unit_of_measurement: 'days'
      value_template: >-
          {% if is_state_attr('sensor.cert_expiry_timestamp_xxx', 'is_valid',1) %}
            {{ ((as_timestamp(states("sensor.cert_expiry_timestamp_xxx"),states("sensor.hass_cert")) - as_timestamp(now())  ) / 86400 ) | round(0, "floor") }}
          {% else %}
            {{ states('sensor.hass_cert') }}
          {% endif %}
2 Likes

Playing around Certificate Expiry integration sensor. I found one my expired certificate, configured domain and sensor integration with such expired certificate, and sensor return Unknow value with attributes “is valid: false” and “Error: unable to get local issuer certificate”. What is the expected return value for overdue certificate?
With valid certificate Certificate Expiry sensor returns expected value in my configuration.

Answering to myself: yes, Unknown value with attributes “is valid: false” and “Error: unable to get local issuer certificate” is expected for overdue certificate. Details: Python: how to get expired SSL cert date? - Stack Overflow

Hi All,
I’ve had this sensor installed and working for years without ever having any issues with it. Today I updated my LE Certs and suddenly the sensor reports:
image

I have rebooted HA (2022.11.4) and I have deleted the sensor and recreated it, but to no avail. The setting I use during creation is:

my.domain.com
443

Has anything changed lately? Even though the sensor only updates every 12 hour, I was expecting it to update once immediately upon creation, and also immediately on each reboot of HA before falling dormant for 12 hours?

@tyjtyj Thanks for sharing this.I want to implement this too, but I am struggling as to where (under what section) in configuration.yaml it should be placed.
Any guidance you can provide would be appreciated!

Much has changed since then.
Here is full template

template:
  - sensor:
      - name: hass_cert
        unique_id: hass_cert
        unit_of_measurement: 'days'
        state_class: measurement
        state: '{{ ((as_timestamp(states("sensor.cert_expiry_timestamp_xxxxx_32400"),states("sensor.hass_cert")) - as_timestamp(now())  ) / 86400 ) | round(0, "floor") }}'
        availability: "{{ is_state_attr('sensor.cert_expiry_timestamp_xxxxx_32400', 'is_valid',1) }}"

@tyjtyj Thanks for sharing the updated yaml code. That got it working for me! :smiley: