Skip to content
Mig edited this page Feb 8, 2024 · 31 revisions

Cette section inclus des exemples d'utilisation de l'intégration. Le projet ne supporte pas ces exemples, il devrait vous servir de base pour construire ou vous donner des idées. Si vous avez besoin d'aide, veuillez utiliser le forum de HA ou cette discussion

Lovelace / Dashboard

Les exemples qui ont un requis particulier de type "custom:*" nécessite d'installer ces composant. Soit via HACS ou via la méthode manuelle.

Intégration donnée d'énergie

Requis particulier:

  • custom:paper-buttons-row

Contributeur:

Capture d'écran

Capture d'écran énergie lovelace

yaml Code
- type: vertical-stack
  cards:
    - type: custom:paper-buttons-row
      buttons:
        - type: entity
          entity: sensor.hilo_gateway
          name: false
          action: none
          state: false
          state_styles:
            'on':
              button:
                color: green
            'off':
              button:
                color: red
        - type: entity
          entity: sensor.defi_hilo
          state: false
          action: none
          state_styles:
            'on':
              button:
                color: red
            scheduled:
              button:
                color: yellow
            pre_heat:
              button:
                color: red
            recovery:
              button:
                color: blue
            'off':
              button:
                color: green
        - type: entity
          entity: sensor.meter00_power
          name: false
          layout: icon|state
          action: none
          state: '{{ states(config.entity) }}'
          icon: mdi:speedometer
          style:
            button:
              color: |-
                {% if states(config.entity) | int(0) > 1000 %}
                  yellow
                {% elif states(config.entity) | int(0) > 1500 %}
                  orange
                {% elif states(config.entity) | int(0) > 2000 %}
                  red
                {% else%}
                  green
                {% endif %}
        - type: entity
          entity: sensor.hilo_rate_current
          name: false
          layout: icon|state
          action: none
          state: '{{ states(config.entity) }}'
          style:
            button:
              color: |-
                {% if states(config.entity) | float(0) > 0.07 %}
                  yellow
                {% elif states(config.entity) | float(0) > 0.1 %}
                  red
                {% else%}
                  green
                {% endif %}
    - type: energy-date-selection
    - type: energy-sources-table
    - type: energy-usage-graph
    - type: energy-distribution
      link_dashboard: true

Graphiques

Consommation Globale

Requis particulier:

  • custom:apexcharts-card

Contributeur:

Dans ce graphique, vous devrez ajuster les threshold selon votre consommation. Vous pouvez également ajuster la moyenne qui est fait au 5 minutes dans le group_by, duration.

Capture d'écran

Capture d'écran

yaml Code
type: custom:apexcharts-card
header:
  show: true
  show_states: true
experimental:
  color_threshold: true
graph_span: 12h
all_series_config:
  stroke_width: 4
yaxis:
  - id: kwh
    decimals: 0
    apex_config:
      tickAmount: 4
  - id: degree
    opposite: true
    decimals: 0
    apex_config:
      tickAmount: 4
series:
  - entity: sensor.meter00_power
    yaxis_id: kwh
    unit: W
    type: column
    color_threshold:
      - value: 0
        color: cyan
      - value: 1000
        color: green
      - value: 1500
        color: orange
      - value: 2500
        color: red
    group_by:
      duration: 5min
      func: avg
  - entity: sensor.temperature
    yaxis_id: degree
    name: Temperature
    unit: °C
    type: line

Consommation par thermostat

Requis particulier:

  • custom:apexcharts-card

Contributeur:

Dans ce graphique, vous devrez ajuster les nom des title et entity. Vous pouvez également ajuster les couleurs des lignes et ajouter d'autres thermostat et ajoutant des sections "- type: custom:apexcharts-card".

Capture d'écran

Capture d'écran

yaml Code
- type: horizontal-stack
  cards:
    - type: custom:apexcharts-card
      header:
        show: true
        title: Chambre principale
        show_states: true
        colorize_states: true
      graph_span: 8h
      cache: true
      series:
        - entity: climate.thermostat_chambre1
          attribute: current_temperature
          name: Temperature
          color: red
          fill_raw: last
        - entity: climate.thermostat_chambre1
          attribute: temperature
          name: Consigne
          fill_raw: last
    - type: custom:apexcharts-card
      header:
        show: true
        title: Chambre 2
        show_states: true
        colorize_states: true
      graph_span: 8h
      cache: true
      series:
        - entity: climate.thermostat_chambre2
          attribute: current_temperature
          name: Temperature
          color: red
          fill_raw: last
        - entity: climate.thermostat_chambre2
          attribute: temperature
          name: Consigne
          fill_raw: last
    - type: custom:apexcharts-card
      header:
        show: true
        title: Chambre 3
        show_states: true
        colorize_states: true
      graph_span: 8h
      cache: true
      series:
        - entity: climate.thermostat_chambre3
          attribute: current_temperature
          name: Temperature
          color: red
          fill_raw: last
        - entity: climate.thermostat_chambre3
          attribute: temperature
          name: Consigne
          fill_raw: last

Cartes Lovelace

Affichage des statistiques des défis de la saison en cours

Requis particulier:

  • Aucun

Contributeur:

Permet d'afficher les stats de la saison en cours. Ne sont pas inclus:

  • Les défis en cours ou planifiés
  • Les défis récemment terminés (le temps qu'ils soient disponibles dans Hilo)

Instructions:

  1. Ajouter une carte, rechercher type de carte "manuel"
  2. Tout supprimer du code par défaut
  3. Copier le code YAMl tel quel, en gardant tout le formatage tel quel
Capture d'écran

image

yaml Code
type: markdown
content: |-
  {% 

  set data = state_attr('sensor.recompenses_hilo','history')[0] 

  %}
  {% if data is defined %}

    <h2><center>Saison  {{data.season}}-{{data.season + 1}}</center></h2>  
    <ha-alert alert-type="success"><h3>
      Nb de défis: {{data.events | count}}<br>
      Récompense totale: {{"%.2f" | format(data.totalReward) }}$<br>
      Récompense moyenne: {{"%.2f" | format(data.totalReward /(data.events | count)) }}$
    </h3></ha-alert>      
    <br>

    <table width=100%>
      <tr>
        <th>#</th>
        <th>Date</th>
        <th>Plage</th>
        <th>Alloué</th>
        <th>Utilisé</th>
        <th>Prime</th>
      </tr>  

      {%- for event in data.events -%}    
        <tr>
        <td align=center>{{ "%02i"|format(loop.index) }}</td>
        <td align=center>{{ event.phases.reduction_start.timestamp() | timestamp_custom('%b %d (%a)') }}</td>
        <td align=center>{{ "Matin" if (event.period =="am") else "Soir" }}</td>
        <td align=center>{{ "%.1f"|format(event.allowed_kWh) }}</td> 
        <td align=center>{{ "%.1f"|format(event.used_kWh) }}</td>      
        <td align=center>{{ "%.2f"|format(max(0,event.allowed_kWh - event.used_kWh) * 0.55) }}$</td>
        </tr>
      {%- endfor -%}

    </table>

  {% else %}
  aucune donnée disponible
  {% endif %}


Automatisation


Pré-chauffer avant le prochain défi.

Requis particulier:

  • Créer une scène y ajouter les thermostat et y configurer la consigne désiré sur chacun d'entre eux.

Contributeur:

But: Phase de pré-chauffage de manière à emmagasiner la chaleurs dans les pièces et augmenter le maximum pour le défi et ainsi maximiser la récompense.

Résumé de l'automatisme:

  • Cet automatisme se déclenche à 4h am ou à 11h am.
  • Il sera exécuté seulement si le sensor.defi_hilo a pour valeur scheduled, donc lorsqu'il n'y a pas de défi de prévu, il ne s'exécute pas.
  • Lorsque la condition est satisfaite, une scène nommé "defi_hilo_preheat" sera appliqué
  • Une commande est envoyé à un RM4Pro pour envoyer la commande IR(précédemment enregistré) à la thermopompe pour chauffer. La commande est répetté 3 fois avec un délais de 2 secondes car le IR n'est pas parfait et des animaux/personnes peuvent l'obstruer parfois.
Code YAML
alias: TEMP - PréHeat DÉFI Hil
description: ''
trigger:
  - platform: time
    at: '04:00'
  - platform: time
    at: '11:00'
condition:
  - condition: state
    entity_id: sensor.defi_hilo
    state: scheduled
action:
  - scene: scene.defi_hilo_preheat
  - service: remote.send_command
    target:
      device_id: XXXXXXXXXXXXXXXXXXXXXXXXXXXX
    data:
      device: thermopompe
      command: heat25on
      num_repeats: 3
      delay_secs: 2
mode: single

Abaisser la consigne de chauffage après défi

Requis particulier:

  • Créer une scène y ajouter les thermostat et y configurer la consigne désiré sur chacun d'entre eux. Ex. 16 degré

Contributeur:

But: Baisser les thermostats au maximum pendant la durée du défi

Résumé de l'automatisme:

  • Cet automatisme se déclenche lorsque l'état du sensor.defi_hilo passe de pre_heat à reduction.
  • Dans ce cas une scène nommé "defi_hilo_en_cours_extra_audacieux" sera appliqué.
  • Une commande est envoyé à un RM4Pro pour envoyer la commande IR(précédemment enregistré) à la thermopompe pour s'arrêter. La commande est répetté 3 fois avec un délais de 2 secondes car le IR n'est pas parfait et des animaux/personnes peuvent l'obstruer parfois.
Code YAML
alias: TEMP - DÉFI Hilo en cours Extra audacieux
description: ''
trigger:
  - platform: state
    entity_id: sensor.defi_hilo
    from: pre_heat
    to: reduction
condition: []
action:
  - scene: scene.defi_hilo_en_cours_extra_audacieux
  - service: remote.send_command
    target:
      device_id: XXXXXXXXXXXXXXXXXXXX
    data:
      device: thermopompe
      command: heat25off
      num_repeats: 3
      delay_secs: 2
mode: single

Gestion du défi par Node-Red

Code JSON à importer
[
    {
        "id": "15df69096d73137f",
        "type": "subflow",
        "name": "Store current temperature",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 260,
                "y": 100,
                "wires": [
                    {
                        "id": "010a7f3c1f81c4d4"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 840,
                "y": 100,
                "wires": [
                    {
                        "id": "010a7f3c1f81c4d4",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [
            {
                "name": "phase",
                "type": "str",
                "value": ""
            }
        ],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "010a7f3c1f81c4d4",
        "type": "function",
        "z": "15df69096d73137f",
        "name": "Store current temperature",
        "func": "phase = env.get(\"phase\");\nfor (const [ key, value ] of Object.entries(msg.states)) {\n    if (key.startsWith(\"climate.thermostat\")) {\n        if (parseFloat(value.attributes.temperature) >= parseFloat(msg.states[\"input_number.auto_climate_threshold\"].state)) {\n            global.set(phase + \".\" + key, parseFloat(value.attributes.temperature));\n        }\n   }\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 590,
        "y": 100,
        "wires": [
            []
        ]
    },
    {
        "id": "132662309edd5344",
        "type": "subflow",
        "name": "Restore temperature",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 320,
                "y": 80,
                "wires": [
                    {
                        "id": "109e3fe7ab32a823"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 760,
                "y": 80,
                "wires": [
                    {
                        "id": "109e3fe7ab32a823",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [
            {
                "name": "phase",
                "type": "str",
                "value": ""
            }
        ],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "109e3fe7ab32a823",
        "type": "function",
        "z": "132662309edd5344",
        "name": "Restore original temperature",
        "func": "phase = env.get(\"phase\");\nmsg.payload = [];\nfor (const [ key, value ] of Object.entries(global.get(phase + \".climate\"))) {\n  msg.payload.push({new_temp: parseFloat(value), thermostat: \"climate.\" + key})\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 520,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "b802b35cdaea7755",
        "type": "subflow",
        "name": "Set low temperature",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 600,
                "y": 120,
                "wires": [
                    {
                        "id": "e1b02875ce96e7fb"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 1000,
                "y": 120,
                "wires": [
                    {
                        "id": "e1b02875ce96e7fb",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [
            {
                "name": "phase",
                "type": "str",
                "value": ""
            }
        ],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "e1b02875ce96e7fb",
        "type": "function",
        "z": "b802b35cdaea7755",
        "name": "Set low temperature",
        "func": "msg.payload = [];\nphase = env.get(\"phase\");\n\nfor (const [ key, value ] of Object.entries(global.get(phase + \".climate\"))) {\n  min_value = Math.max(value - msg.states[\"input_number.auto_climate_reduction\"].state, 17)\n  msg.payload.push({new_temp: parseFloat(min_value), thermostat: \"climate.\" + key})\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 760,
        "y": 120,
        "wires": [
            []
        ]
    },
    {
        "id": "74b05496d83ac642",
        "type": "subflow",
        "name": "Check away",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 60,
                "y": 80,
                "wires": [
                    {
                        "id": "0d7198f3c895a6bb"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 500,
                "y": 60,
                "wires": [
                    {
                        "id": "0d7198f3c895a6bb",
                        "port": 0
                    }
                ]
            },
            {
                "x": 500,
                "y": 120,
                "wires": [
                    {
                        "id": "0d7198f3c895a6bb",
                        "port": 1
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99",
        "outputLabels": [
            "We're away",
            "We're home"
        ]
    },
    {
        "id": "0d7198f3c895a6bb",
        "type": "switch",
        "z": "74b05496d83ac642",
        "name": "Check away",
        "property": "states[\"input_boolean.away_mode\"].state",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "on",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 290,
        "y": 80,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "7ba3b0276c9ecb25",
        "type": "subflow",
        "name": "Temperature adjust",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 40,
                "y": 120,
                "wires": [
                    {
                        "id": "e2fcd03a48603baf"
                    },
                    {
                        "id": "559286e3191669ef"
                    }
                ]
            }
        ],
        "out": [],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "e2fcd03a48603baf",
        "type": "split",
        "z": "7ba3b0276c9ecb25",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 190,
        "y": 80,
        "wires": [
            [
                "9fd385ccc529bf18"
            ]
        ]
    },
    {
        "id": "9fd385ccc529bf18",
        "type": "api-call-service",
        "z": "7ba3b0276c9ecb25",
        "name": "Set temperature",
        "server": "07108f66d0e2da5f",
        "version": 3,
        "debugenabled": true,
        "service_domain": "climate",
        "service": "set_temperature",
        "entityId": "{{ payload.thermostat }}",
        "data": "{ \"temperature\": payload.new_temp }",
        "dataType": "jsonata",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 400,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "9a13adeaad6da8c8",
        "type": "api-call-service",
        "z": "7ba3b0276c9ecb25",
        "name": "Notify me",
        "server": "07108f66d0e2da5f",
        "version": 3,
        "debugenabled": true,
        "service_domain": "notify",
        "service": "mobile_app_pixel_4a",
        "entityId": "",
        "data": "{'title': \"Setting temperature\", 'message': msg.notification }",
        "dataType": "jsonata",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 560,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "559286e3191669ef",
        "type": "function",
        "z": "7ba3b0276c9ecb25",
        "name": "Convert new temperatures to string",
        "func": "payload = \"\"\nmsg.payload.forEach(function(m){\n    payload += m.thermostat + \": \" + m.new_temp + \"\\r\\n\";\n})\nmsg.notification = payload\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 280,
        "y": 160,
        "wires": [
            [
                "9a13adeaad6da8c8"
            ]
        ]
    },
    {
        "id": "f6b9fd2ba5761ed0",
        "type": "server-state-changed",
        "z": "c2396addea5b319e",
        "name": "Defi Hilo - Pre Heat",
        "server": "07108f66d0e2da5f",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "sensor.defi_hilo",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "pre_heat",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 2,
        "output_only_on_state_change": true,
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": true,
        "ignorePrevStateUnknown": true,
        "ignorePrevStateUnavailable": true,
        "ignoreCurrentStateUnknown": true,
        "ignoreCurrentStateUnavailable": true,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            },
            {
                "property": "states",
                "propertyType": "msg",
                "value": "homeassistant.hass.states",
                "valueType": "global"
            }
        ],
        "x": 290,
        "y": 640,
        "wires": [
            [
                "be6ae55cd242d858"
            ],
            []
        ]
    },
    {
        "id": "9102960a487b1353",
        "type": "server-state-changed",
        "z": "c2396addea5b319e",
        "name": "Defi Hilo - Reduction",
        "server": "07108f66d0e2da5f",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "sensor.defi_hilo",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "reduction",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 2,
        "output_only_on_state_change": true,
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": true,
        "ignorePrevStateUnknown": true,
        "ignorePrevStateUnavailable": true,
        "ignoreCurrentStateUnknown": true,
        "ignoreCurrentStateUnavailable": true,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            },
            {
                "property": "message",
                "propertyType": "msg",
                "value": "Attention un défi Hilo est sur le point de commencer",
                "valueType": "str"
            },
            {
                "property": "states",
                "propertyType": "msg",
                "value": "homeassistant.hass.states",
                "valueType": "global"
            }
        ],
        "x": 290,
        "y": 720,
        "wires": [
            [
                "a1d70f5b91f5bc2f",
                "0c6abac254ed30dd"
            ],
            []
        ]
    },
    {
        "id": "f1fa932f47472f56",
        "type": "server-state-changed",
        "z": "c2396addea5b319e",
        "name": "Defi Hilo - Recovery",
        "server": "07108f66d0e2da5f",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "sensor.defi_hilo",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "recovery",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 2,
        "output_only_on_state_change": true,
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": true,
        "ignorePrevStateUnknown": true,
        "ignorePrevStateUnavailable": true,
        "ignoreCurrentStateUnknown": true,
        "ignoreCurrentStateUnavailable": true,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            },
            {
                "property": "states",
                "propertyType": "msg",
                "value": "homeassistant.hass.states",
                "valueType": "global"
            },
            {
                "property": "message",
                "propertyType": "msg",
                "value": "Le défi Hilo est terminé.",
                "valueType": "str"
            }
        ],
        "x": 290,
        "y": 800,
        "wires": [
            [
                "ae84636e2d59f2bc",
                "99059089b0d2fcb3"
            ],
            []
        ]
    },
    {
        "id": "62a30be2096b8849",
        "type": "subflow:7ba3b0276c9ecb25",
        "z": "c2396addea5b319e",
        "name": "",
        "env": [],
        "x": 1350,
        "y": 780,
        "wires": []
    },
    {
        "id": "4c7e4e14aafae44f",
        "type": "function",
        "z": "c2396addea5b319e",
        "name": "Set recovery temperature",
        "func": "msg.payload = [];\nfor (const [ key, value ] of Object.entries(global.get(\"before_pre_heat.climate\"))) {\n  min_value = Math.min(parseFloat(value) + parseFloat(msg.states[\"input_number.auto_climate_recovery\"].state), 25)\n  msg.payload.push({new_temp: parseFloat(min_value), thermostat: \"climate.\" + key})\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 890,
        "y": 780,
        "wires": [
            [
                "62a30be2096b8849",
                "69fc88d5b03020a8"
            ]
        ]
    },
    {
        "id": "ae84636e2d59f2bc",
        "type": "subflow:74b05496d83ac642",
        "z": "c2396addea5b319e",
        "name": "",
        "env": [],
        "x": 570,
        "y": 780,
        "wires": [
            [],
            [
                "4c7e4e14aafae44f",
                "4f83cdbe19481a67"
            ]
        ]
    },
    {
        "id": "be6ae55cd242d858",
        "type": "function",
        "z": "c2396addea5b319e",
        "name": "Generate payload",
        "func": "msg.payload = [];\nfor (const [ key, value ] of Object.entries(global.get(\"before_pre_heat.climate\"))) {\n  msg.payload.push({new_temp:  parseFloat(value) + parseFloat(msg.states[\"input_number.auto_climate_pre_heat\"].state)  / parseFloat(2), thermostat: \"climate.\" + key})\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 950,
        "y": 620,
        "wires": [
            [
                "62a30be2096b8849"
            ]
        ]
    },
    {
        "id": "a1d70f5b91f5bc2f",
        "type": "subflow:b802b35cdaea7755",
        "z": "c2396addea5b319e",
        "name": "",
        "env": [
            {
                "name": "phase",
                "value": "before_pre_heat",
                "type": "str"
            }
        ],
        "x": 660,
        "y": 680,
        "wires": [
            [
                "62a30be2096b8849",
                "69fc88d5b03020a8"
            ]
        ]
    },
    {
        "id": "7d4929089f05b561",
        "type": "subflow:132662309edd5344",
        "z": "c2396addea5b319e",
        "name": "",
        "env": [
            {
                "name": "phase",
                "value": "before_pre_heat",
                "type": "str"
            }
        ],
        "x": 1060,
        "y": 820,
        "wires": [
            [
                "62a30be2096b8849"
            ]
        ]
    },
    {
        "id": "ab26232241ff6d64",
        "type": "server-state-changed",
        "z": "c2396addea5b319e",
        "name": "Defi Hilo - Appreciation",
        "server": "07108f66d0e2da5f",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "sensor.defi_hilo",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "appreciation",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 2,
        "output_only_on_state_change": true,
        "for": 0,
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": true,
        "ignorePrevStateUnknown": true,
        "ignorePrevStateUnavailable": true,
        "ignoreCurrentStateUnknown": true,
        "ignoreCurrentStateUnavailable": true,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            },
            {
                "property": "states",
                "propertyType": "msg",
                "value": "homeassistant.hass.states",
                "valueType": "global"
            }
        ],
        "x": 300,
        "y": 560,
        "wires": [
            [
                "6c72a2387cb2f486"
            ],
            []
        ]
    },
    {
        "id": "6c72a2387cb2f486",
        "type": "subflow:15df69096d73137f",
        "z": "c2396addea5b319e",
        "name": "",
        "env": [
            {
                "name": "phase",
                "value": "before_pre_heat",
                "type": "str"
            }
        ],
        "x": 650,
        "y": 560,
        "wires": [
            [
                "3061107dac54f7ae"
            ]
        ]
    },
    {
        "id": "3061107dac54f7ae",
        "type": "function",
        "z": "c2396addea5b319e",
        "name": "Generate payload",
        "func": "msg.payload = [];\nfor (const [ key, value ] of Object.entries(global.get(\"before_pre_heat.climate\"))) {\n  msg.payload.push({new_temp:  parseFloat(value) + parseFloat(msg.states[\"input_number.auto_climate_pre_heat\"].state), thermostat: \"climate.\" + key})\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 930,
        "y": 560,
        "wires": [
            [
                "62a30be2096b8849"
            ]
        ]
    },
    {
        "id": "99059089b0d2fcb3",
        "type": "api-call-service",
        "z": "c2396addea5b319e",
        "name": "Turn on Chauffe-Eau",
        "server": "07108f66d0e2da5f",
        "version": 3,
        "debugenabled": false,
        "service_domain": "switch",
        "service": "turn_on",
        "entityId": "switch.switch_chauffe_eau",
        "data": "",
        "dataType": "jsonata",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 600,
        "y": 820,
        "wires": [
            []
        ]
    },
    {
        "id": "0c6abac254ed30dd",
        "type": "api-call-service",
        "z": "c2396addea5b319e",
        "name": "Turn off Chauffe-Eau",
        "server": "07108f66d0e2da5f",
        "version": 3,
        "debugenabled": false,
        "service_domain": "switch",
        "service": "turn_off",
        "entityId": "switch.switch_chauffe_eau",
        "data": "",
        "dataType": "jsonata",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 660,
        "y": 720,
        "wires": [
            []
        ]
    },
    {
        "id": "4f83cdbe19481a67",
        "type": "delay",
        "z": "c2396addea5b319e",
        "name": "",
        "pauseType": "delay",
        "timeout": "25",
        "timeoutUnits": "minutes",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 850,
        "y": 820,
        "wires": [
            [
                "7d4929089f05b561"
            ]
        ]
    },
    {
        "id": "07108f66d0e2da5f",
        "type": "server",
        "name": "hass",
        "version": 1,
        "legacy": false,
        "addon": false,
        "rejectUnauthorizedCerts": false,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true
    }
]

Templates

Créer plusieurs sensors relié au défi.

Requis particulier:

  • Une version récente du component Hilo.

Contributeur:

Résumé du/des template: Créer plusieurs sensors par rapport au défi.

Les sensors suivant seront rendu disponible pour afficher dans des dashboard ou utilisé dans des automatisme:

  • defi_hilo_in_progress
  • defi_hilo_allowed_kwh
  • defi_hilo_allowed_cash
  • defi_hilo_used_kwh
  • defi_hilo_used_cash
  • defi_hilo_remaining_cash
  • defi_hilo_predicted_cash
  • defi_hilo_currentdefi_cash
  • defi_hilo_avg_cash
  • defi_hilo_date_heure_next
  • defi_hilo_date_heure_last
  • defi_hilo_nb_defi_planifies
  • defi_hilo_nb_defi_completes
  • electricity_cost_today
  • electricity_kwh_today_consomme
Code YAML
sensor:
  - platform: template
    sensors:
      defi_hilo_in_progress:
        friendly_name: Défi Hilo en cours?
        value_template: "{{ is_state('sensor.defi_hilo', 'appreciation') or is_state('sensor.defi_hilo', 'pre_heat') or is_state('sensor.defi_hilo', 'reduction') }}" 

      defi_hilo_allowed_kwh:
        unit_of_measurement: 'kWh'
        friendly_name: Limite max defi
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{state_attr('sensor.defi_hilo', 'next_events')[0]['allowed_kWh']}}
            {% else%}
            {{0}}
            {% endif %}

      defi_hilo_allowed_cash:
        friendly_name: Montant max defi
        unit_of_measurement: '$'
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{ (state_attr('sensor.defi_hilo', 'next_events')[0]['allowed_kWh'] * 0.55) | round(2) }}
            {% else%}
            {{0}}
            {% endif %}

      defi_hilo_used_kwh:
        friendly_name: kWh utilise defi
        unit_of_measurement: 'kWh'
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{ state_attr('sensor.defi_hilo', 'next_events')[0]['used_kWh']}}
            {% else%}
            {{0}}
            {% endif %}

      defi_hilo_used_cash:
        friendly_name: Montant utilise defi
        unit_of_measurement: '$'
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{ (state_attr('sensor.defi_hilo', 'next_events')[0]['used_kWh'] * 0.55) | round(2) }}
            {% else%}
            {{0}}
            {% endif %}

      defi_hilo_remaining_cash:
        friendly_name: Montant restant defi
        unit_of_measurement: '$'
        value_template:  >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{(( state_attr('sensor.defi_hilo', 'next_events')[0]['allowed_kWh'] - state_attr('sensor.defi_hilo', 'next_events')[0]['used_kWh']) * 0.55) | round(2) }}
            {% else%}
            {{0}}
            {% endif %}

      defi_hilo_predicted_cash:
        friendly_name: Montant total predit defi
        unit_of_measurement: '$'
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {% set debutdefi = as_timestamp(state_attr('sensor.defi_hilo', 'next_events')[0]['phases']['reduction_start']) %}
            {% set maintenant =  (now().timestamp()) %}
            {% set delta = ((maintenant - debutdefi)) // 60 | float %}
            {% if delta <= 0  %}
            {% set delta = 1 %}
            {%endif %}
            {% if delta >= 240  %}
            {% set delta = 240 %}
            {%endif %}
            {%set predicteduse = (1/(delta/ 240 )) * float(states('sensor.defi_hilo_used_kwh'),0) %}
            {{((float(states('sensor.defi_hilo_allowed_kwh'),0) - predicteduse) * 0.55)  | round(2) }}
            {% else%}
            {{0}}
            {% endif %}        

      defi_hilo_currentdefi_cash:
        friendly_name: Montant accumule estime defi
        unit_of_measurement: '$'        
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {% set debutdefi = as_timestamp(state_attr('sensor.defi_hilo', 'next_events')[0]['phases']['reduction_start']) %}
            {% set maintenant =  (now().timestamp()) %}
            {% set delta = ((maintenant - debutdefi) // 60) +1 | int %}
            {% if delta <= 0  %}
            {% set delta = 1 %}
            {%endif %}
            {% if delta >= 240  %}
            {% set delta = 240 %}
            {%endif %}
            {{ (delta/ 240 * ((float(states('sensor.defi_hilo_allowed_kwh'),0) - ((1/(delta/ 240 ) * float(states('sensor.defi_hilo_used_kwh'),0)))) * 0.55))  | round(2) }}
            {% else%}
            {{0}}
            {% endif %}
           
      defi_hilo_avg_cash:
        friendly_name: Montant moyen defi
        unit_of_measurement: '$'
        value_template: >
          {% if state_attr('sensor.recompenses_hilo', 'history') | count > 0 %}  
            {% set recompense = states('sensor.recompenses_hilo') | float %}
            {% set nbdefis = states('sensor.defi_hilo_nb_defi_completes') | float %}
            {% if nbdefis > 0 %}
              {% set moyenne = (recompense / nbdefis) | round(2) %}
              {{"%.2f" | format(moyenne)}}
              {% else %}
                {{0}}
              {% endif %}
          {% else %}
            {{0}}
          {% endif %}
        
      defi_hilo_date_heure_next:
        friendly_name: Defi Hilo prochain moment
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{as_timestamp((state_attr('sensor.defi_hilo','next_events')[0]['phases']['reduction_start']))|timestamp_custom("%A %Y-%m-%d %H:%M")  }}
            {% else%}
            {{'-'}}
            {% endif %}
        
      defi_hilo_date_heure_last:
        friendly_name: Defi Hilo moment le plus loin
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 1 %}
            {{as_timestamp((state_attr('sensor.defi_hilo','next_events')[state_attr('sensor.defi_hilo', 'next_events') | length -1]['phases']['reduction_start']))|timestamp_custom("%A %Y-%m-%d %H:%M")  }}            
            {% else%}
            {{'-'}}
            {% endif %}
        
      defi_hilo_nb_defi_planifies:
        friendly_name: Nb de defis Hilo planifies
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{state_attr('sensor.defi_hilo', 'next_events') | length }}
            {% else%}
            {{'0'}}
            {% endif %}        
        
      defi_hilo_nb_defi_completes:
        friendly_name: Nb de defis Hilo completes saison actuelle
        value_template: >
            {% if state_attr('sensor.recompenses_hilo', 'history') | length  > 0 %}
            {{state_attr('sensor.recompenses_hilo', 'history')[0]['events'] | length}}
            {% else%}
            {{'0'}}
            {% endif %}

      electricity_cost_today:
        friendly_name: Cout electricite aujourd'hui
        unit_of_measurement: 'CAD'
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{ "%.2f"|format(1.15*(float(states.sensor.hilo_energy_total_low.state, 0) *    float(states.sensor.hilo_rate_low.state, 0) +    float(states.sensor.hilo_energy_total_medium.state, 0) *   float(states.sensor.hilo_rate_medium.state, 0) + 0.435))  | round(2)}}
            {% else%}
            {{'0'}}
            {% endif %} 

      electricity_kwh_today_consomme:
        friendly_name: kWh electricite aujourd'hui consomme
        unit_of_measurement: 'kWh'
        value_template: >
            {% if state_attr('sensor.defi_hilo', 'next_events') | length  > 0 %}
            {{ float(states.sensor.hilo_energy_total_low.state, 0) +    float(states.sensor.hilo_energy_total_medium.state, 0) }}
            {% else%}
            {{'0'}}
            {% endif %} 

Ajout des appareils dans HomeKit

Dans la configuration de HassBridge (au niveau des integration), c'est possible de sélectionner ce que HomeAssisstant enverra à Homekit. Dans la premiere fenêtre, on choisi "sensor" et dans la deuxième fenêtre on peut choisir d'ajouter ou exclure des entités.

Capture d’écran, le 2022-01-06 à 09 07 18 Capture d’écran, le 2022-01-06 à 09 17 19

Attention ça peux devenir bordélique rapidement.

Ensuite dans Homekit, on devrait y retrouver les sensor ou appareils.

C'est conseiller de placer la "passerelle virtuelle" de Home Assistant dans une "fausse pièce" dans Home Kit. Les appareils vont s'y retrouver.

Optimisation manuelle

Bien que vous recevrez quand même vos récompenses d'Hilo lorsque vous gérez vous même chacune des phases, c'est important de considérer les faits suivants:

  • Hydro-Québec exige une courbe de consommation de la part d'Hilo. Cette courbe inclue le pré-chauffage graduel et le retour graduel.
  • En ce moment, les récompenses sont uniquement attribuées en fonction du nombre de kWh utilisés lors de la phase de restriction.
  • Par contre, Les ingénieurs d'Hilo travaillent actuellement sur un algorithme pour que les récompenses soient attribuées en fonction de la courbe, en incluant la phase de pré-chauffage et la phase de retour.
  • C'est possible que la méthode Hilo ne soit pas optimale pour vos besoins. Grâce à cette intégration Home Assistant, vous pouvez l'adapter aux besoins de votre foyer.

En gros, Hilo est au courant qui a des gens qui adaptent la courbe selon leur besoin, et c'est possible qu'ils changent le format des récompenses.