Prochaine expiration du certificat de mes noms de domaine (ou autre liste)

Le code suivant remonte le nom de domaine du certificat qui sera le premier a expirer depuis une liste (j'ai plusieurs certificats car plusieurs ndd).

On récupère en sortie une entité dont l’état est le nom de domaine le plus près à expirer et un attribut qui correspond à la date d’expiration du certificat pour celui ci.

Il y a deux exemples pour arriver au même résultat.
Pour l’un, j’utilise une boucle pour l’autre je navigue dans une liste.

N’hésitez pas à poser des questions et à partager vos modèles :+1:

Prérequis

Utiliser l’intégration Certificate Expiry ou tout autre entité dont le format est strictement identique (YYYY-MM-DDTHH:mm:ss+00:00)

En utilisant une boucle

sensor:
  - platform: template
    sensors:
      prochaine_certificat_a_expirer_avec_boucle:
        friendly_name: "Prochain certificat à expirer"
        attribute_templates:
          timestamp: >
            {# Définition de la liste des entités #}
            {% set liste_des_entites= ['sensor.cert_expiry_timestamp_ndd1_duckdns_org','sensor.cert_expiry_timestamp_ndd2_duckdns_org'] %}
            {# Définition du `namespace` afin de pouvoir récupérer la valeur définie dans la boucle en dehors de celle-ci (spécificité du Jinja)#}
            {%set prochain_evenement = namespace(timestamp='')  %}
            {# Boucle parcourant tous les éléments de la liste `liste_des_entites` #}
            {% for entite in liste_des_entites %}
                {% if loop.first %}
                    {# Au premier passage on récupère les informations de la première entité de la liste #}        
                    {% set prochain_evenement.timestamp = (as_timestamp(states(entite))|float) %}
                {% else %}
                    {# On compare la valeur précédemment stockée avec celle correspondant au nouvel index de la boucle #}        
                    {% if (as_timestamp(states(entite))|float) < prochain_evenement.timestamp %}
                        {# la valeur de l'entité est inférieure à celle stockée, donc c'est elle qu'on stocke dorénavant #}        
                        {% set prochain_evenement.timestamp = (as_timestamp(states(entite))|float) %}
                    {% endif %}        
                {% endif %}
            {% endfor %}
            {{ prochain_evenement.timestamp }}
        value_template: >
          {# Définition de la liste des entités #}
          {% set liste_des_entites= ['sensor.cert_expiry_timestamp_ndd1_duckdns_org','sensor.cert_expiry_timestamp_ndd2_duckdns_org'] %}
          {# Définition du `namespace` afin de pouvoir récupérer la valeur définie dans la boucle #}
          {%set prochain_evenement = namespace(timestamp='', nom_de_l_entite='')  %}
          {# Boucle parcourant tous les éléments de la liste `liste_des_entites` #}
          {% for entite in liste_des_entites %}
              {% if loop.first %}
                  {# Au premier passage on récupère les informations de la première entité de la liste #}        
                  {% set prochain_evenement.timestamp = (as_timestamp(states(entite))|float) %}
                  {% set prochain_evenement.nom_de_l_entite = entite %}
              {% else %}
                  {# On compare la valeur précédemment stockée avec celle correspondant au nouvel index de la boucle #}        
                  {% if (as_timestamp(states(entite))|float) < prochain_evenement.timestamp %}
                      {# la valeur de l'entité est inférieure à celle stockée, donc c'est elle qu'on stocke dorénavant #}        
                      {% set prochain_evenement.timestamp = (as_timestamp(states(entite))|float) %}
                      {% set prochain_evenement.nom_de_l_entite = entite %}
                  {% endif %}        
              {% endif %}
          {% endfor %}
          {{ prochain_evenement.nom_de_l_entite.split('sensor.cert_expiry_timestamp_')[1] }}

En parcourant une liste

  - platform: template
    sensors:
      prochaine_certificat_a_expirer_sans_boucle:
        friendly_name: "Prochain certificat à expirer"
        attribute_templates:
          timestamp: >
            {# Définition de la liste des entités #}
            {% set liste_des_entites = ['sensor.cert_expiry_timestamp_ndd1_duckdns_org', 'sensor.cert_expiry_timestamp_ndd2_duckdns_org'] %}
            {% set timestamp_des_entites = [as_timestamp(states('sensor.cert_expiry_timestamp_ndd1_duckdns_org'))|float,as_timestamp(states('sensor.cert_expiry_timestamp_ndd2_duckdns_org'))|float] %}
            {% set entite_la_plus_petite = timestamp_des_entites|min %}
            {{timestamp_des_entites[timestamp_des_entites.index(entite_la_plus_petite)]}}
        value_template: >
          {# Définition de la liste des entités #}
          {% set liste_des_entites = ['sensor.cert_expiry_timestamp_ndd1_duckdns_org', 'sensor.cert_expiry_timestamp_ndd2_duckdns_org'] %}
          {% set timestamp_des_entites = [as_timestamp(states('sensor.cert_expiry_timestamp_ndd1_duckdns_org'))|float,as_timestamp(states('sensor.cert_expiry_timestamp_ndd2_duckdns_org'))|float] %}
          {% set entite_la_plus_petite = timestamp_des_entites|min %}
          {{liste_des_entites[timestamp_des_entites.index(entite_la_plus_petite)].split('sensor.cert_expiry_timestamp_')[1]}}
3 « J'aime »

Hummm certificat (signé par une authorité de certification) et nom de domaine (déclaré chez un Registrar) sont 2 choses. Et l’un peut expirer indépendamment de l’autre.

c’est corrigé ! a vouloir allez trop vite…

qu’est ce que cela fait de plus que l’intégration de base du custom ?

Je n’ai pas compris la phrase :expressionless:

par rapport au l’intégration certifica expiry qu’est ce que ton code jinja ajoute de plus

En français dans le texte… :grin:

C’est le 1er paragraphe qui explique ce que fait le code, le 2nd explique l’entité qui est produite par le code…

Donc pour résumer, j’ai 2 certificat pour ndd1 (expire le 1/2/2021) et ndd2 (expire le 30/1/2021) produits par l’intégration Certificate Expiry , mon code produit l’entité :

sensor.prochaine_certificat_a_expirer_avec_boucle:
  state: ndd2
  attributs:
    timestamp: 1612035599

ok donc en gros tu affiche le nombre de jour avant la fin du certificat tous en affichant dans la liste celui qui va expiré le plus prêt du jour J

1 « J'aime »

je tente désespérément d’adapter ce template à mon problème , sans succès.
la nouvelle version de l’integration livebox fournie un binary_sensor nommé call_missed ayant pour attributs un dictionnaire nommé call missed
ce dictionnaire ressemble à cela

{'phone_number': '0123456789', 'date': '2021-05-30 07:17:55+00:00', 'callId': '43'}, 
{'phone_number': '0123456789', 'date': '2021-05-30 18:59:26+00:00', 'callId': '44'}

je cherche à récupérer cette liste, inversée pour présenter le dernier numéro de l’appel manqué en premier, pour par exemple le transmettre via telegram
la seule chose que j’arrive à faire c’est afficher depuis le modèle des Outils de développement la liste complète

{% for attr in states.binary_sensor.call_missed.attributes   %}
{%- if not attr=="friendly_name" -%}
 le dictionnaire "{{attr}}" contient les entrées suivantes :  {{states.binary_sensor.call_missed.attributes[attr] }}
{%- endif %}
{%- endfor -%}

ou un élément du dictionnaire, via son numéro

{{states['binary_sensor.call_missed'].attributes['call missed'][0]['phone_number']}}
tableau[-1] #Dernier élément du tableau

:+1:

Un début de réponse

T’es sûr qu’il y a un espace dans le nom de l’attribut ?

{{(state_attr('binary_sensor.call_missed','call missed')) |reverse |list}}

merci pour le -1 je ne connaissais pas
le dictionnaire s’appelle bien « call missed »

{'call missed': [{'phone_number': '0123456789', 'date': '2021-05-30 07:17:55+00:00', 'callId': '43'}, {'phone_number': '0123456789', 'date': '2021-05-30 18:59:26+00:00', 'callId': '44'}], 'friendly_name': 'Call missed'}

Etonnant de voir un espace et non un _ (underscore)

Avec ma deuxième réponse le dernier numéro se retrouve donc en première position : [0]

oui ce n’est pas l’idéal mais c’est un bon début
merci, je continu à gratter

C’est quoi l’idéal ? Car je pense avoir répondu à ta demande non ?

le binary_sensor est toujours on,
d’une manière plus générale il me faudra donc surveiller la date et heure pour savoir si il y a un nouvel appel. du coup je suis pas encore arrivé au résultat escompté. mais tu n’es en rien responsable :slight_smile: