History stat Temps d'utilisation avec automatisation

Mon problème

Bonjour,

Je voudrai que au bout de X minutes / heures passé devant la TV je reçoit une notification avec automation mais malgré ma bonne volonté je me heurte à quelque soucie de conversion en affichage horaire (ex: sa me met 2.98 en valeur qui signifie 2h58) puis la reprendre pour le déclenchement avec condition de l’automatisation.
Template sensor:

##########################################
##          Temps utilisation Tv        ##
##########################################
 
  - platform: history_stats
    name: watchtv_salon_today
    entity_id: media_player.tv_salon
    state: "on"
    type: time
    start: "{{ now().replace(hour=0, minute=0, second=0) }}"
    end: "{{ now() }}"

  - platform: history_stats
    name: watchtv_chambre_today
    entity_id: media_player.freebox_player_pop
    state: "playing"
    type: time
    start: "{{ now().replace(hour=0, minute=0, second=0) }}"
    end: "{{ now() }}"

  - platform: template
    sensors:
      watchtv_all:
        unit_of_measurement: "hour"
        value_template: "{{ (states('sensor.watchtv_salon_today') | float) + (states('sensor.watchtv_chambre_today') | float) }} "
        friendly_name: 'Combined TV Consumption' 

Automatisation:

- alias: '[NOTIFY] Watch TV Time'
  trigger:
    - platform: state
      entity_id: sensor.watchtv_all
  condition:
    - condition: numeric_state
      entity_id: sensor.watchtv_all
      above: '3.10'   # au dessus de 3h10 minutes
      below: '4.05'     # En dessous de 4h05 minutes
  action:
  - service: notify.notify
    data:
      title: Aujourd'hui vous avez regardé {{ states('sensor.watchtv_full') }}

Ma configuration


System Health

version core-2021.9.7
installation_type Home Assistant OS
dev false
hassio true
docker true
user root
virtualenv false
python_version 3.9.7
os_name Linux
os_version 5.10.61
arch x86_64
timezone Europe/Paris
Home Assistant Community Store
GitHub API ok
Github API Calls Remaining 4790
Installed Version 1.15.2
Stage running
Available Repositories 894
Installed Repositories 35
Home Assistant Supervisor
host_os Home Assistant OS 6.3
update_channel stable
supervisor_version supervisor-2021.09.0
docker_version 20.10.7
disk_total 30.8 GB
disk_used 12.5 GB
healthy true
supported true
board ova
supervisor_api ok
version_api ok
installed_addons Samba share (9.5.1), File editor (5.2.0), Log Viewer (0.9.1), Visual Studio Code (3.6.2), Samba Backup (4.5.0)
Lovelace
dashboards 1
resources 33
views 7
mode yaml
___

Le calcul est faux ici…

3,10 ne fait pas 3h10 mais 3,10*60min = 186min = 3h06min

Donc pour avoir 3h10 = 190min = 3,17*60min

Du coup, ne vaudrait-il pas mieux tout convertir en minutes ?

J’avoue, j’ai mis 3.1 a titre d’exemple mdr :stuck_out_tongue:

Oui, mais comment convertir en minutes ?

Ce n’est pas nécessaire :upside_down_face:

Si tu vas dans les Outils de développement, onglet ETATS, tu remarqueras que l’entité dispose d’un attribut exploitable :

Donc il suffit de déclencher l’automatisation sur cet attribut plutôt que de faire des calculs :

alias: Résumé de la journée
description: ''
trigger:
  - platform: state
    entity_id: sensor.lamp_on_today
    attribute: value
    to: 20h 59m
  - platform: state
    entity_id: sensor.lamp_on_today
    attribute: value
    to: 21h 0m
  - platform: state
    entity_id: sensor.lamp_on_today
    attribute: value
    to: 21h 1m
condition: []
action:
  - service: persistent_notification.create
    data:
      message: 'Résumé : Vous avez regardé {{state_attr("sensor.lamp_on_today","value")}}'
mode: single

J’ai mis plusieurs heures pour montrer le format :+1:

Ce qui donne :

image

Pas sur un mediaplayer.****
image

Ca n’a rien a voir
:sweat_smile:
Il te faut utiliser l’entité de l’intégration history_stats :upside_down_face:

Donc dans ton cas : sensor.watchtv_salon_today

:expressionless: :grin: :laughing:

Comment fait-on pour l’activer ? je n’est pas encore utilisé cette fonction a t-elle un lien avec le recorder ?

#config.YaML
recorder:
  purge_keep_days: 365
  auto_purge: true
  include:
    domains:
      - sensor
      - input_boolean
      - input_datetime
      - input_number
      - input_select
      - input_text
      - binary_sensor
      - light
      - cover
      - media_player
      - person
  exclude:
    domains:
      - automation
      - alarm_control_panel
      - calendar
      - camera
      - climate
      - device_tracker
      - group
      - proximity
      - scene
      - script
      - sun
      - switch
      - timer
      - vacuum
      - weather
      - zone
      - zwave
    event_types:
      - automation_triggered
      - script_started
      - service_registered
      - home_assistant_start
      - home_assistant_stop
      - home_assistant_stop
    entities:
      - sun.sun
      - sensor.last_boot
      - sensor.date
      - sensor.time
    entity_globs:
      - sensor.processor_*
      - sensor.memory_*


  
sun:
map:
zodiac:
person:
history:

Franchement là tu est complètement perdu dans tes pensées…

C’est toi même qui indique que tu utilises l’intégration history_stats :

Et tu demandes :

et je te réponds.

Je ne peux pas t’aider plus que ça (car je te donne la solution avec les explications…)

Là, tu me réponds des trucs complètements à côté…

Prends le temps de relire ta demande…
:+1:

Merci @Clemalex
j’avais en effet mal regardé s’agissant de ma premier utilisation de la fonction history je ne voyais pas ou avais la valeur value.

je viens de qu’une fois avoir créer le sensor.watchtv_salon en plateform history tu avais la valeur « value » dont tu m’as parler…:slight_smile:

Résultat ça fonctionne même si le template cumul d’utilisation s’affiche : « 1h 2m0m » plutôt bizarre une piste ?

voila le code sensor.

##########################################
##          Temps utilisation Tv        ##
##########################################
 
  - platform: history_stats
    name: watchtv_salon_today
    entity_id: media_player.tv_salon
    state: "playing"
    type: time
    start: "{{ now().replace(hour=0, minute=0, second=0) }}"
    end: "{{ now() }}"

  - platform: history_stats
    name: watchtv_chambre_today
    entity_id: media_player.freebox_player_pop
    state: "playing"
    type: time
    start: "{{ now().replace(hour=0, minute=0, second=0) }}"
    end: "{{ now() }}"

  - platform: template
    sensors:
      watchtv_all:
        unit_of_measurement: "hour"
        value_template: "{{ (states.sensor.watchtv_salon_today.attributes.value) + (states.sensor.watchtv_chambre_today.attributes.value)}}"
        friendly_name: 'Cumul utilisation de la TV' 

Il n’y a rien de bizarre cela correspond à ton code… :innocent:

Je repasse ce soir éditer mon post pour t’expliquer et te donner un exemple :+1:

edit:

Commençons par expliquer le code que tu as écris pour la valeur de watchtv_all :

  1. Déjà, pour récupérer un attribut, la documentation dit de préférer la méthode state_att(entité,attribut) (comme je te l’ai montré dans ma réponse plus haute) plutôt que la méthode states.domaine.entité.attributes.attribut, donc pourquoi ne pas faire comme le préconise la documentation ? :wink:

  2. Concernant ton code tu lui dit de récupérer le temps de 2 entités et de les concaténer ensemble.
    Donc si entité_1 = 1h 2m et entite_2 = 0m (pas encore regarder cette tv aujourd’hui) le résultat va donner… 1h 2m0m (comme dans ton message :wink: )

Alors pourquoi ? Car les résultats renvoyées par les fonctions states() , is_state() (et bien d’autre, voir la documentation pour tous les détails) sont au format string donc en texte. Et quand on écrit la formule {{ texte1 + texte 2 }} le résultat sera texte1texte2 (concaténation).

Pour faire des calculs de nombre, il faut donc les transformer en nombre via des filtres donc les plus connus sont |int (entier, pas de virgule) et |float (virgule flottante).

Donc prenons l’exemple de : texte1 = 12 et texte2 = 34 :

  1. Si on écrit {{texte1 + texte2}} le résultat sera 1234 (concaténation de chaines de caractères)
  2. Si on écrit {{texte1|int + texte2|int}} le résultat sera 46

Avec ces explications brèves, j’espère que tu comprends mieux ton résultat.

Donc pour en revenir à ta demande initiale, à savoir : Additionner le nombre total de temps de visionnage des TV, il faut donc passer par quelques conversions pour pouvoir additionner les valeurs dont nous disposons :wink:

Une démonstration de code juste pour le plaisir :smirk::

{% set hours = (states('sensor.lamp_on_today').split('.')[0]) %}
{% set minutes = '%02d'|format(((('0.' ~ states('sensor.lamp_on_today').split('.')[1]|first )|float)*60)|round) %}
{{hours}}h{{minutes}}m

Renverra le temps de visionnage d’une entité au format 12h34m (la seule différence avec l’attribut value est la disparition de l’espace… :upside_down_face: mais il y a beaucoup de notion dans le code donc je le mets… :yum:

Une façon plus rapide et moins fastidieuse serait de récupérer la valeur de l’attribut value et d’enlever l’espace en trop, mais (sinon ça ne serait pas amusant) dans le cas de 1h 3m nous préfèrerons voir 01h03m (on ne va pas pousser même si c’est faisable de ne pas afficher les heures pour 00h12m par exemple :grin:)

On obtient par exemple le code :

{% set hours = '%02d'|format(state_attr('sensor.lamp_on_today','value').split('h')[0]|int) %}
{% set minutes = '%02d'|format(state_attr('sensor.lamp_on_today','value').split('h')[1].split('m')[0]|trim|int)%}
{{hours}}h{{minutes}}m

pour le résultat 12h34m:expressionless: … oui le même résultat que le code précédent mais avec une autre approche…

J’arrête avec les codes inutiles (ou pas) et on attaque le problème :
On a donc 2 entité qui ont chacune un attribut value et un état state représentant le temps d’allumage et nous voulons les additionner…

Pour faire un calcul de durée, je le dis à chaque fois mais il faut passer par des variables de type datetime.

Donc convertissons ces entités et ajoutons les :thinking: :

{# 1ère entité #}
  {% set hours1 = '%02d'|format(state_attr('sensor.lamp_on_today','value').split('h')[0]|int) %}
  {% set minutes1 = '%02d'|format(state_attr('sensor.lamp_on_today','value').split('h')[1].split('m')[0]|trim|int)%}
  {% set time1 = hours1 ~ 'h' ~ minutes1 ~ 'm' %}
  {% set time1 = strptime(time1,'%Hh%Mm').time() %}
{# 2ème entité #}
  {% set hours2 = '%02d'|format(state_attr('sensor.lamp_on_today_2','value').split('h')[0]|int) %}
  {% set minutes2 = '%02d'|format(state_attr('sensor.lamp_on_today_2','value').split('h')[1].split('m')[0]|trim|int)%}
  {% set time2 = hours2 ~ 'h' ~ minutes2 ~ 'm' %}
  {% set time2 = strptime(time2,'%Hh%Mm').time() %}
{# On additionne les entités#}
  {% set seconds = time1.minute*60+time1.hour*3600+time2.minute*60+time2.hour*3600 %}
{# On affiche le résultat #}
  {{'%02d'|format(seconds//3600)}}:{{'%02d'|format(seconds//60%60)}}

On teste tout cela dans les outils de développements :

Et on crée une entité (ancien format car je l’avais sous la main… :frowning: :pleading_face:)

sensor:
  - platform: template
    sensors:
      temps_total:
        icon_template: mdi:timer-outline
        unit_of_measurement: " " #<- Espace insécable pour ne rien afficher dans lovelace (un espace) mais activer la vue historique
        value_template: >
          {# 1ère entité #}
            {% set hours1 = '%02d'|format(state_attr('sensor.lamp_on_today','value').split('h')[0]|int) %}
            {% set minutes1 = '%02d'|format(state_attr('sensor.lamp_on_today','value').split('h')[1].split('m')[0]|trim|int)%}
            {% set time1 = hours1 ~ 'h' ~ minutes1 ~ 'm' %}
            {% set time1 = strptime(time1,'%Hh%Mm').time() %}
          {# 2ème entité #}
            {% set hours2 = '%02d'|format(state_attr('sensor.lamp_on_today_2','value').split('h')[0]|int) %}
            {% set minutes2 = '%02d'|format(state_attr('sensor.lamp_on_today_2','value').split('h')[1].split('m')[0]|trim|int)%}
            {% set time2 = hours2 ~ 'h' ~ minutes2 ~ 'm' %}
            {% set time2 = strptime(time2,'%Hh%Mm').time() %}
          {# On additionne les entités#}
            {% set seconds = time1.minute*60+time1.hour*3600+time2.minute*60+time2.hour*3600 %}
          {# On affiche le résultat #}
            {{'%02d'|format(seconds//3600)}}:{{'%02d'|format(seconds//60%60)}}

Ce qui donne côté lovelace :


Voilà…

3 « J'aime »

Merci c’est… Impressionnant, je pense le lire et le relire parce-que c’est vraiment intéressent de pouvoir commencer à comprendre comment sa fonctionne :slightly_smiling_face:
Merci pour ta pédagogie @Clemalex en espérant que cela puisse aider au plus grand nombre sur ce forum :+1:

1 « J'aime »

:grin:

:slightly_smiling_face:

:revolving_hearts:

1 « J'aime »

de mon coter j’ai :

##########################################
##          Temps utilisation Tv        ##
##########################################
 
  - platform: history_stats
    name: watchtv_salon_today
    entity_id: media_player.tv_salon
    state: "playing"
    type: time
    start: "{{ now().replace(hour=0, minute=0, second=0) }}"
    end: "{{ now() }}"

  - platform: history_stats
    name: watchtv_chambre_today
    entity_id: media_player.freebox_player_pop
    state: "playing"
    type: time
    start: "{{ now().replace(hour=0, minute=0, second=0) }}"
    end: "{{ now() }}"

  - platform: template
    sensors:
      watchtv_all:
        icon_template: mdi:timer-outline
        unit_of_measurement: " " #<- Espace insécable pour ne rien afficher dans lovelace (un espace) mais activer la vue historique
        value_template: >
          {# 1ère entité #}
            {% set hours1 = '%02d'|format(state_attr('sensor.watchtv_salon_today','value').split('h')[0]|int) %}
            {% set minutes1 = '%02d'|format(state_attr('sensor.watchtv_salon_today','value').split('h')[1].split('m')[0]|trim|int)%}
            {% set time1 = hours1 ~ 'h' ~ minutes1 ~ 'm' %}
            {% set time1 = strptime(time1,'%Hh%Mm').time() %}
          {# 2ème entité #}
            {% set hours2 = '%02d'|format(state_attr('sensor.watchtv_chambre_today','value').split('h')[0]|int) %}
            {% set minutes2 = '%02d'|format(state_attr('sensor.watchtv_chambre_today','value').split('h')[1].split('m')[0]|trim|int)%}
            {% set time2 = hours2 ~ 'h' ~ minutes2 ~ 'm' %}
            {% set time2 = strptime(time2,'%Hh%Mm').time() %}
          {# On additionne les entités#}
            {% set seconds = time1.minute*60+time1.hour*3600+time2.minute*60+time2.hour*3600 %}
          {# On affiche le résultat #}
            {{'%02d'|format(seconds//3600)}}:{{'%02d'|format(seconds//60%60)}}

j’ai vérifié avec outils dev → modèle et j’ai erreur indifinie ??