OpenHASP - utiliser un esp avec écran tactile pour contrôler Home assistant

j’avais zapper c’est ajout lol. je vais le rajouter dans le tuto.
Juste /config , suffit.

homeassistant:
  allowlist_external_dirs:
  - /config

Chez moi
image

Ou peut on trouver la listes codes des icones genre « \uE335 » ?

Sur la doc de OpenHASP.

Super merci :+1:
Bon ben, ya plus qu’a.

Merci pour cet excellent tuto qui est maintenant parfait :wink:

Bonjour,

J’en suis a vouloir afficher quelques info meteo
Je me suis inspiré de ton template mais il ne fonctionne plus
Apres des recherches, j’ai vu que le code a changé
J’ai essayé d’adapter mais je coince.

Pourrais tu reposter ton template meteo mis a jour avec weather.get_forecasts

merci

Oui, le template fonctionne plus depuis avril. J’ai pas mis a jour encore, je vais le faire.

Ok,
J’ai essayé ca mais ca remonte rien

- trigger:
      - platform: state
        entity_id: weather.toulouse #entité météo france
  action:
      - service: weather.get_forecasts
        data:
          type: daily
        target:
          entity_id: weather.toulouse
        response_variable: daily
  sensor:
    - name: Météo toulouse J0
      unique_id: meteo_toulouse_j0
      state: "{{ daily['weather.toulouse'].forecast[0].condition | default(0) }}"
      attributes: 
        temperature: "{{daily['weather.toulouse'].forecast[0].temperature | float(0) }}"
        templow: "{{ daily['weather.toulouse'].forecast[0].templow | float(0) }}"
        humidite: "{{ daily['weather.toulouse'].forecast[0].humidity | int(0) }}"
        precipitation: "{{ daily['weather.toulouse'].forecast[0].precipitation | float(0) }}"

@jcr
J’ai maj le tuto, avec les templates a jour.

Ca marche nickel :+1::grin:
Et quelle réactivité !

bravo et merci

1 « J'aime »

Bonjour et merci pour le travail déjà accompli , j’ai à cause de toi acheté l’elecrow 7" .
Petite bug sur la météo avec la direction du vent exemple pour moi qui suis nantais mais peut importe la ville

- obj: "p1b220"
  properties:
    "text": "{{ states('sensor.direction_vent_nantes') }}"

le sensor.direction_vent_nantes n’existe pas, au plus proche y a l’attribut wind speed de weather.nantes qui à une direction cardinale
je suis un peu boulet et ne sais pas trop comment corrigé

Bonjour @tomj44300,
J’utilise un template et j’ai oublier de le partager.

{% set direction = ['N','NNE','NE','ENE','E','ESE','SE','SSE','S','SSO','SO','OSO','O','ONO','NO','NNO','N'] %}
{% set degree = state_attr('weather.xxxxx', 'wind_bearing')|int(0) %}
{% if degree > 1 %}
  {{ direction[((degree+11.25)/22.5)|int(0)] }}
{% else %}
  {{ "\uE156" }}
{% endif %}

Tu peut créer un template directement du UI, dans paramètre / appareils et service / onglet entrée.

Edit:
ajouter au tuto.

1 « J'aime »

salut merci pour la correction mais j’ai encore un petit bug , j’ai souvent X qui s’affiche à la place de la direction
image
orange ESE , vert NSE ,jaune ENE, rouge N
mais je crois que c’est parce qu’il n’y en a quasiment pas (je confirme visuellement) et que météo France ne remonte pas l’info dans ce cas
image
le X ont doit comprend pas de vent je suppose

C’est exactement ça. J’ai mis une icones X pour dire pas de vent. Quand ta moins de 4km/h du vent , sa affichera la croix.

Bonjour, merci encore pour vos partages cela m’aide beaucoup.
J’ai regardé sur ce fil et sur le fil ha anglais
https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://community.home-assistant.io/t/openhasp-an-mqtt-driven-touchscreen-scene-controller/300853%3Fpage%3D12&ved=2ahUKEwj_xobXwKiGAxUJRaQEHd4vAxQQFnoECAkQAQ&usg=AOvVaw1tB25tNmPbXBOgSaWp-QK8
Mais je ne trouve pas de solution.

Je souhaiterais afficher des graphiques présent dans HA sur l’écran openhasp.

Sur le github :
https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://github.com/HASwitchPlate/openHASP/discussions/35&ved=2ahUKEwj_xobXwKiGAxUJRaQEHd4vAxQQFnoECAwQAQ&usg=AOvVaw1fxKE0adKEOQPpOTkH0bZy
Il est indiqué pour une question relative aux graphiques :
« Nous utilisons LVGL 7.11 dans openHASP. Le widget Graphique n’est pas encore disponible via openHASP jsonl, mais est accessible à l’aide d’ un code personnalisé .
Pour le graphique à secteurs, vous devez utiliser un canevas dans LVGL 7.11 ou utiliser LVGL 8.x qui inclut un widget de graphique à secteurs. »
Je n’ai pas idée comment utilisé cette information.
Si quelqu’un arrivé à faire des graphiques ou a des idées par tout hasard…
Merci d’avance

Je progresse bien avec mon petit écran
Tes exemples sont une mine d’or :blush:

Mon écran d’accueil :

J’attaque maintenant la page de réglage des thermostats
…et je bloque sur les scripts « script.thermostat_sejour_down_temp » et up pour régler en manuel la temp (boutons + et -)

Qui y a t il dedans?

Comme je n’arrive pas à faire des graphiques, je réalise des screenshots de mes dashboard et je les envois sur l’openhasp.
Pour faire les screenshots, j’utilise :

Puis avec un script automatique j’envoie les screenshots sur l’openhasp :

###### Push image ###########
- id: push_image
  alias: push image
  trigger:
  - platform: time_pattern
    minutes: "/5"
  action:
    - service: openhasp.push_image
      target:
        entity_id: openhasp.plate01
      data:
        image: http://192.168.1.28:5000/
    # Set the IP address to YOUR HA server
        obj: p3b2
        width: 480
        height: 480
        fitscreen: true

En espérant que ça puisse aider certains

2 « J'aime »

Salut,

voila les scripts que j’utilise:

alias: Thermostat salon down temp
sequence:
  - service: climate.set_temperature
    data:
      temperature: >-
        {{ state_attr('climate.versatile_thermostat_salon', 'temperature') -
        value | float(0) }}
    target:
      entity_id: climate.versatile_thermostat_salon
icon: mdi:minus
mode: single
alias: Thermostat salon up temp
sequence:
  - service: climate.set_temperature
    data:
      temperature: >-
        {{ state_attr('climate.versatile_thermostat_salon', 'temperature') +
        value | float(0) }}
    target:
      entity_id: climate.versatile_thermostat_salon
icon: mdi:plus
mode: single
1 « J'aime »

Super !
Marche impec :+1:

Encore merci :pray::blush:

1 « J'aime »

Bonjour,
je me permets de vous solliciter pour avoir votre aide sur le thermostat et openhasp/home assistant.
Je suis parti des exemple de openhasp (Example Configurations - openHASP) pour réaliser le thermostat.
Je suis arrivé à configurer le bouton déroulant, la consigne et la barre/arc.
Cependant je souhaiterais modifier le nom afficher dans le bouton déroulant. Les noms sont : On - Off - Heating et Cooling.

image

image

J’ai essayé de modifier le nom dans le fichier openhasp.yaml sur le objet p3b43 qui contrôle le menu déroulant, mais sans succès. Il est lié au climate de HA il me semble.

Code dans le yaml :

   # Page 3: Thermostat

      - obj: "p3b20"  # arc slider
        properties:
          "val": "{{ state_attr('climate.pompe_a_chaleur','temperature') * 10 | int if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"
          "min": "{{ state_attr('climate.pompe_a_chaleur','min_temp') * 10 | int if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"
          "max": "{{ state_attr('climate.pompe_a_chaleur','max_temp') * 10 | int if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"
          "line_color1": >
            {% if is_state('climate.pompe_a_chaleur', 'cool') %}
            {{ "#346beb" }}
            {%-elif is_state('climate.pompe_a_chaleur', 'heat_cool') %}
            {{ "#34bdeb" }}
            {%-elif is_state('climate.pompe_a_chaleur', 'heat') %}
            {{ "#eb3434" }}
            {%-elif is_state('climate.pompe_a_chaleur', 'dry') %}
            {{ "#ebeb34" }}
            {%-else %}
            {{ "#9f96b0" }}
            {% endif %}
        event:
          "changed":
            - service: climate.set_temperature
              target:
                entity_id: climate.pompe_a_chaleur
              data:
                temperature: "{{ val | int / 10 }}"
          "up":
            - service: climate.set_temperature
              target:
                entity_id: climate.pompe_a_chaleur
              data:
                temperature: "{{ val | int / 10 }}"

      - obj: "p3b21"  # gauge current temp
        properties:
          "val": "{{ state_attr('climate.pompe_a_chaleur','temperature') * 10  | int if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"
          "min": "{{ state_attr('climate.pompe_a_chaleur','min_temp') * 10 | int if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"
          "max": "{{ state_attr('climate.pompe_a_chaleur','max_temp') * 10 | int if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"
          "critical_value": "{{ (state_attr('climate.pompe_a_chaleur','max_temp') * 10 | int + 1) if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"
          "label_count": "{{ (state_attr('climate.pompe_a_chaleur','max_temp') | int - state_attr('climate.pompe_a_chaleur','min_temp') | int + 1) if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"
          "line_count": "{{ ((state_attr('climate.pompe_a_chaleur','max_temp') | int - state_attr('climate.pompe_a_chaleur','min_temp') | int) * 2 + 1) if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"


      - obj: "p3b23"  # label current temp (and +/- with short/long touch)
        properties:
          "text": >
            {% if (is_state('sensor.netatmo_interieur_temperature','unavailable') or is_state('sensor.netatmo_interieur_temperature','unknown')) %}
            {{ "--.-" }}
            {%-else %}
            {{ states('sensor.netatmo_interieur_temperature') | round(1,default=0) }}
            {%- endif %}
          "click": "{{ 'false' if (is_state('climate.pompe_a_chaleur','unavailable') or is_state('climate.pompe_a_chaleur','unknown')) else 'true' }}"
          "opacity": "{{ 60 if (is_state('climate.pompe_a_chaleur','unavailable') or is_state('climate.pompe_a_chaleur','unknown')) else 255 }}"
        event:
          "up":
            - service: climate.set_temperature
              target:
                entity_id: climate.pompe_a_chaleur
              data:
                temperature: "{{ state_attr('climate.pompe_a_chaleur','temperature') + state_attr('climate.pompe_a_chaleur','target_temp_step') | float(default=1)}}" 
          "long":
            - service: climate.set_temperature
              target:
                entity_id: climate.pompe_a_chaleur
              data:
                temperature: "{{ state_attr('climate.pompe_a_chaleur','temperature') - state_attr('climate.pompe_a_chaleur','target_temp_step') | float(default=1)}}" 





      - obj: "p3b25"  # label target temp
        properties:
          "text": "{{ state_attr('climate.pompe_a_chaleur','temperature') if not (is_state('climate.pompe_a_chaleur','unavailable')) }}"



      - obj: "p3b30"  # tab dots
        event:
          "changed":
            - service: openhasp.command
              target:
                entity_id: openhasp.your_plate
              data:
                keyword: p3b26.text
                parameters: >
                  {% if val == 0 %}
                  {{ "#000000 \u2022# #909090 \u2022# #909090 \u2022#" | e }}
                  {%-elif val == 1 %}
                  {{ "#909090 \u2022# #000000 \u2022# #909090 \u2022#" | e }}
                  {%-elif val == 2 %}
                  {{ "#909090 \u2022# #909090 \u2022# #000000 \u2022#" | e }}
                  {% endif %}

      - obj: "p3b43"  # dropdown with hvac_modes
        properties:
          "options": >
            {% if not (is_state('climate.pompe_a_chaleur','unavailable')) %}{%for mode in state_attr('climate.pompe_a_chaleur','hvac_modes')%}
            {%- if mode == 'off' -%}
            Off{{"\n"|e}}
            {%- elif mode == 'heat' -%}
            Heating{{"\n"|e}}
            {%- elif mode == 'cool' -%}
            Cooling{{"\n"|e}}
            {%- elif mode == 'heat_cool' -%}
            Heat/Cool{{"\n"|e}}
            {%- elif mode == 'dry' -%}
            Drying{{"\n"|e}}
            {%- else -%}
            On{{"\n"|e}}
            {%- endif -%}
            {%-if not loop.last%}{%-endif%}{%-endfor%}{% endif %}
          "val": >
            {% if not (is_state('climate.pompe_a_chaleur','unavailable')) %}{%for mode in state_attr('climate.pompe_a_chaleur','hvac_modes')%}
            {{loop.index -1 if mode == states('climate.pompe_a_chaleur') }}
            {%-endfor%}{% endif %}
        event:
          "changed":
            - service: climate.set_hvac_mode
              target:
                entity_id: climate.pompe_a_chaleur
              data:
                hvac_mode: >
                  {% if text == "Off" -%}
                  off
                  {% elif text == 'Heating' -%}
                  heat
                  {% elif text == 'Cooling' -%}
                  cool
                  {% elif text == 'Heat/Cool' -%}
                  heat_cool
                  {% elif text == 'Drying' -%}
                  dry
                  {% endif -%}

Si vous avez une idée ou une solution.
Merci par avance.
jpjobe

Salut tout le monde, j’me suis procuré un Crowpanel 7", est mise à part la fidélité des couleurs complètement dans les choux, j’ai pu faire ce que je voulais, voici le moment du partage!

Je suis parti sur une interface inspirée de StarTrek LCARS, pas spécialement fan de la série mais je trouve le design « simple et élégant » ^^
Me reste 3 boutons sur la gauche pour les futures pages (ouvrants, arrosage et… j’sais pas quoi)

pages.jsonl
// 120d38 -> dark
// 5b19e2 -> mid
// 01fde0 -> light
// ff6c00 -> orange
// ff00ff -> rose
// 01fde0 -> cyan

{"comment":"Designer Config","page_size":"7inch_800x480_landscape","plate_name":"elecrow"}

// ================================================================ MEDIA PLAYER PAGE 01
{"page":1,"id":1,"obj":"img","x":0,"y":0,"src":"L:/uss_nirlnaeth_p01.png"}

// ----------------------------------------------------------- media information
{"page":1,"id":11,"obj":"label","x":530,"y":70,"w":260,"h":50,"comment":"artist","text":"-","mode":"loop","align":"center"}
{"page":1,"id":12,"obj":"label","x":530,"y":130,"w":260,"h":50,"comment":"title","text":"-","mode":"loop","align":"center"}

// -------------------------------------------------------------- media controls
{"page":1,"id":20,"obj":"arc","x":510,"y":190,"w":300,"h":300,"bg_opa":"0","min":5,"max":60,"border_side":0,"type":0,"rotation":0,"start_angle":120,"end_angle":60,"start_angle10":120,"end_angle10":60,"adjustable":true,"line_width":"5","line_width10":"7","line_color":"#120d38","line_color10":"#ff00ff","bg_color20":"#ff00ff","border_width20":2,"border_color20":"#120d38","pad_top20":8,"pad_bottom20":8,"pad_left20":8,"pad_right20":8}    {"page":1,"id":21,"obj":"btn","x":40,"y":120,"w":60,"h":60,"comment":"previous","border_side":0,"bg_color":"#120d38","text_color":"#cad3f5","text":"\uE4AE","text_font":32,"align":"center","parentid":20}
    {"page":1,"id":22,"obj":"btn","x":110,"y":110,"w":80,"h":80,"comment":"play_pause","border_side":0,"bg_color":"#120d38","text_color":"#ff6c00","text":"\uE40A","text_font":36,"align":"center","parentid":20}
    {"page":1,"id":23,"obj":"btn","x":200,"y":120,"w":60,"h":60,"comment":"next","border_side":0,"bg_color":"#120d38","text_color":"#cad3f5","text":"\uE4AD","text_font":32,"align":"center","parentid":20}
    {"page":1,"id":24,"obj":"btn","x":120,"y":40,"w":60,"h":60,"comment":"mute","border_side":0,"bg_color":"#120d38","text_color":"#cad3f5","text":"\uE75F","text_font":32,"align":"center","parentid":20}
    {"page":1,"id":25,"obj":"btn","x":120,"y":200,"w":60,"h":60,"comment":"power","border_side":0,"bg_color":"#120d38","text_color":"#cad3f5","text":"\uE425","text_font":32,"align":"center","parentid":20}

// ----------------------------------------------------------------- media cover
{"page":1,"id":30,"obj":"obj","x":80,"y":20,"w":440,"h":440,"radius":10,"border_side":0,"clip_corner":1}
    {"page":1,"id":31,"obj":"img","src":"L:/mass_off_440x440.png","parentid":30}
    {"page":1,"id":32,"obj":"img","src":"","hidden":"true","parentid":30}
    
{"page":1,"id":41,"obj":"img","x":610,"y":80,"w":100,"h":100,"src":"L:/logo_spotify_100x100.png"}

// ------------------------------------------------------------ misc information
{"page":1,"id":91,"obj":"label","x":555,"y":12,"h":30,"w":200,"text":"Mercremanche 66 Octobrier","text_font":22,"align":"left","text_color":"#cad3f5"}
{"page":1,"id":92,"obj":"label","x":725,"y":8,"h":30,"w":200,"text":"33:33","text_font":24,"align":"left","text_color":"#cad3f5"}
{"page":1,"id":93,"obj":"btn","x":180,"y":0,"w":25,"h":15,"comment":"alarme state","bg_color":"#8ecfdb","radius":0,"border_side":0}

// // ============================================================================= PAGE 02
// {"page":2,"id":1,"obj":"img","x":0,"y":0,"src":"L:/uss_nirlnaeth_p0x.png"}

// // ============================================================================= PAGE 03
// {"page":3,"id":1,"obj":"img","x":0,"y":0,"src":"L:/uss_nirlnaeth_p0x.png"}

// // ============================================================================= PAGE 04
// {"page":4,"id":1,"obj":"img","x":0,"y":0,"src":"L:/uss_nirlnaeth_p0x.png"}

// ===================================================================== CAMERAS PAGE 05
{"page":5,"id":1,"obj":"img","x":0,"y":0,"src":"L:/uss_nirlnaeth_p05.png"}

// -------------------------------------------------------------------- snapshot
{"page":5,"id":10,"obj":"obj","btn_pos":1,"x":80,"y":0,"w":640,"h":480,"radius":10,"clip_corner":1}
    {"page":5,"id":11,"obj":"img","src":"","parentid":10,"comment":"height 470"}

// ------------------------------------------------------------- cameras buttons
{"page":5,"id":21,"obj":"btn","x":725,"y":85,"w":75,"h":50,"bg_color":"#120d38","text":"CHEMIN","text_color":"#cad3f5","text_color01":"black","radius":0,"border_side":0,"text_font":18,"toggle":"true"}
{"page":5,"id":22,"obj":"btn","x":725,"y":140,"w":75,"h":50,"bg_color":"#120d38","text":"JARDIN","text_color":"#cad3f5","text_color01":"black","radius":0,"border_side":0,"text_font":18,"toggle":"true"}
{"page":5,"id":23,"obj":"btn","x":725,"y":195,"w":75,"h":50,"bg_color":"#120d38","text":"PARKING","text_color":"#cad3f5","text_color01":"black","radius":0,"border_side":0,"text_font":18,"toggle":"true"}
{"page":5,"id":24,"obj":"btn","x":725,"y":250,"w":75,"h":50,"bg_color":"#120d38","text":"RUE","text_color":"#cad3f5","text_color01":"black","radius":0,"border_side":0,"text_font":18,"toggle":"true"}
// ---------------------------------------------------------------- misc buttons
{"page":5,"id":25,"obj":"btn","x":725,"y":320,"w":75,"h":50,"bg_color":"#120d38","text":"\uE33E","text_color":"#cad3f5","text_color01":"black","radius":0,"border_side":0,"text_font":28,"toggle":"false"}
{"page":5,"id":26,"obj":"btn","x":725,"y":375,"w":75,"h":50,"bg_color":"#120d38","text":"\uF020","text_color":"#cad3f5","text_color01":"black","radius":0,"border_side":0,"text_font":28,"toggle":"true"}

// ======================================================================= ALARM PAGE 06
{"page":6,"id":1,"obj":"img","x":0,"y":0,"src":"L:/uss_nirlnaeth_p06.png"}

{"page":6,"id":10,"obj":"btnmatrix","bg_color40":"#5b19e2","radius":10,"bg_color":"#120d38","x":80,"y":20,"w":440,"h":440,"toggle":"true","one_check":"true","options":["8","3","9","\n","1","4","7","\n","2","6","5","\n","#FF0000 C#","0","#00FF00 V#"]}

{"page":6,"id":20,"obj":"roller","x":525,"y":95,"w":240,"h":235,"bg_color":"#120d38","options":"Absents\nPresence\nNuit\nInactive","mode":0,"rows":4}
{"page":6,"id":21,"obj":"label","x":525,"y":58,"w":225,"h":30,"comment":"alarm mode","text":"Choix mode + saisie code","mode":"loop","align":"center","text_font":26,"text_color":"#ff6c00"}

// ------------------------------------------------------------ misc information
{"page":6,"id":91,"obj":"label","x":555,"y":12,"h":30,"w":200,"text":"Mercremanche 66 Octobrier","text_font":22,"align":"left","text_color":"#cad3f5"}
{"page":6,"id":92,"obj":"label","x":725,"y":8,"h":30,"w":200,"text":"33:33","text_font":24,"align":"left","text_color":"#cad3f5"}
{"page":6,"id":93,"obj":"btn","x":180,"y":0,"w":25,"h":15,"comment":"alarme state","bg_color":"#8ecfdb","radius":0,"border_side":0}
{"page":6,"id":94,"obj":"btn","x":135,"y":465,"w":340,"h":15,"comment":"alarme state","bg_color":"#120d38","radius":0,"border_side":0}

// ============================================================================= PAGE 00
// ---------------------------------------------------------------- main buttons
{"page":0,"id":11,"obj":"btn","x":0,"y":65,"w":75,"h":50,"comment":"music","bg_color":"#120d38","text":"\uE75A","text_color":"#cad3f5","radius":0,"border_side":0,"text_font":28}
{"page":0,"id":12,"obj":"btn","x":0,"y":120,"w":75,"h":50,"comment":"home","bg_color":"#120d38","text":"","text_color":"#cad3f5","radius":0,"border_side":0,"text_font":28}
{"page":0,"id":13,"obj":"btn","x":0,"y":175,"w":75,"h":50,"comment":"home","bg_color":"#120d38","text":"","text_color":"#cad3f5","radius":0,"border_side":0,"text_font":28}
{"page":0,"id":14,"obj":"btn","x":0,"y":230,"w":75,"h":50,"comment":"home","bg_color":"#120d38","text":"","text_color":"#cad3f5","radius":0,"border_side":0,"text_font":28}
{"page":0,"id":15,"obj":"btn","x":0,"y":285,"w":75,"h":50,"comment":"cctv","bg_color":"#120d38","text":"\uE7AE","text_color":"#cad3f5","radius":0,"border_side":0,"text_font":28}
{"page":0,"id":16,"obj":"btn","x":0,"y":340,"w":75,"h":60,"comment":"alarm","text":"Alarm","bg_color":"#120d38","mode":"break","text_color":"#cad3f5","align": "center","radius":0,"border_side":0,"text_font":20}
{"page":0,"id":17,"obj":"btn","x":0,"y":405,"w":75,"h":60,"comment":"standby","bg_opa":"0","border_side":0,"text":"\uE425","text_color":"black","text_font":28}
openhasp.yaml
crowpanel:
  objects:
    # ==================================================================================
    # ==================================================================================
    # ========================================================================== PAGE 00

    # ------------------------------------------------------------- main buttons

    # ____________________________________________________________ media
    - obj: "p0b11"
      properties:
        "bg_color": "{{ '#ff6c00' if states('number.crowpanel_page_number') == '1' else '#120d38' }}"
        "text_color": "{{ 'black' if states('number.crowpanel_page_number') == '1' else '#cad3f5' }}"
      event:
        "down":
          - service: number.set_value
            data:
              value: "1"
            target:
              entity_id: number.crowpanel_page_number
        "long":
          - service: script.turn_on
            target:
              entity_id: script.media_garage_avr_spotcast

    # ____________________________________________________________ media
    - obj: "p0b12"
      properties:
        "bg_color": "{{ '#ff6c00' if states('number.crowpanel_page_number') == '2' else '#120d38' }}"
        "text_color": "{{ 'black' if states('number.crowpanel_page_number') == '2' else '#cad3f5' }}"
      # event:
      #   "down":
      #     - service: number.set_value
      #       data:
      #         value: "2"
      #       target:
      #         entity_id: number.crowpanel_page_number

    # ____________________________________________________________ media
    - obj: "p0b13"
      properties:
        "bg_color": "{{ '#ff6c00' if states('number.crowpanel_page_number') == '3' else '#120d38' }}"
        "text_color": "{{ 'black' if states('number.crowpanel_page_number') == '3' else '#cad3f5' }}"
      # event:
      #   "down":
      #     - service: number.set_value
      #       data:
      #         value: "3"
      #       target:
      #         entity_id: number.crowpanel_page_number

    # ____________________________________________________________ media
    - obj: "p0b14"
      properties:
        "bg_color": "{{ '#ff6c00' if states('number.crowpanel_page_number') == '4' else '#120d38' }}"
        "text_color": "{{ 'black' if states('number.crowpanel_page_number') == '4' else '#cad3f5' }}"
      # event:
      #   "down":
      #     - service: number.set_value
      #       data:
      #         value: "4"
      #       target:
      #         entity_id: number.crowpanel_page_number

    # _____________________________________________________________ cctv
    - obj: "p0b15"
      properties:
        "bg_color": "{{ '#ff6c00' if states('number.crowpanel_page_number') == '5' else '#120d38' }}"
        "text_color": "{{ 'black' if states('number.crowpanel_page_number') == '5' else '#cad3f5' }}"
      event:
        "down":
          - service: number.set_value
            data:
              value: "5"
            target:
              entity_id: number.crowpanel_page_number

    # ____________________________________________________________ alarm
    - obj: "p0b16"
      properties:
        "text": "{{ states('sensor.tplt_alarmo') }}"
        <<: &alarm_color
          "bg_color": >
              {% if states('alarm_control_panel.alarme_maison') == "armed_home"  -%}
                #120d38
              {% elif states('alarm_control_panel.alarme_maison') == "armed_night" -%}
                lime
              {% elif states('alarm_control_panel.alarme_maison') == "armed_away" -%}
                violet
              {% elif states('alarm_control_panel.alarme_maison') == "triggered" -%}
                red
              {% elif states('alarm_control_panel.alarme_maison') == "disarmed" -%}
                gray
              {% else -%}
                yellow
              {% endif -%}
          "text_color": >
              {% if states('alarm_control_panel.alarme_maison') == "armed_home"  -%}
                #cad3f5
              {% else -%}
                black
              {% endif -%}
      event:
        "down":
          - service: number.set_value
            data:
              value: "6"
            target:
              entity_id: number.crowpanel_page_number
        "long":
          - service: alarm_control_panel.alarm_arm_night
            target:
              entity_id:
                - alarm_control_panel.alarme_maison
            data:
              code: "5299"

    # __________________________________________________________ standby
    - obj: "p0b17"
      event:
        "down":
          - service: light.turn_off
            target:
              entity_id: light.crowpanel_backlight

    # ==================================================================================
    # ==================================================================================
    # ============================================================= MEDIA PLAYER PAGE 01

    - obj: "p1b11" # artist label
      properties:
        "text": "{{ state_attr('media_player.nest_mini_office','media_artist') if state_attr('media_player.nest_mini_office','media_artist') else '-' }}"
        <<: &mp_playing
          "hidden": "{{ 'false' if (states('media_player.nest_mini_office') not in ['unavailable','off']) else 'true' }}"

    - obj: "p1b12" # title label
      properties:
        "text": "{{ state_attr('media_player.nest_mini_office','media_title') if state_attr('media_player.nest_mini_office','media_title') else '-' }}"
        <<: *mp_playing

    - obj: "p1b20" # volume slider
      properties:
        "val": >
          {% if (state_attr('media_player.nest_mini_office','volume_level') != none and states('media_player.nest_mini_office') not in ['unavailable', 'unknown']) %}
          {{ state_attr('media_player.nest_mini_office','volume_level') * 100 | int(default=80) }}
          {% endif %}
        "click": "{{ 'false' if states('media_player.nest_mini_office') in ['unavailable', 'unknown'] else 'true' }}"
        <<: *mp_playing
      event:
        "changed":
          - service: media_player.volume_set
            data:
              entity_id: media_player.nest_mini_office
              volume_level: "{{ val | int / 100 }}"
        "up":
          - service: media_player.volume_set
            data:
              entity_id: media_player.nest_mini_office
              volume_level: "{{ val | int / 100 }}"

    - obj: "p1b21" # prev
      properties:
        "text_opa": "{{ '80' if states('media_player.nest_mini_office') in ['unavailable', 'unknown'] else '255' }}"
      event:
        "down":
          - service: media_player.media_previous_track
            target:
              entity_id: media_player.nest_mini_office

    - obj: "p1b22" # play/pause
      properties:
        "text": >
          {% if is_state('media_player.nest_mini_office', 'playing') %}
          {{ "\uE3E4" | e }}
          {% else %}
          {{ "\uE40A" | e }}
          {% endif %}
        "radius": >
          {% if is_state('media_player.nest_mini_office', 'playing') %}
            10
          {% else %}
            255
          {% endif %}
        "text_opa": "{{ '80' if states('media_player.nest_mini_office') in ['unavailable', 'unknown'] else '255' }}"
      event:
        "down":
          - service: media_player.media_play_pause
            target:
              entity_id: media_player.nest_mini_office
        "long":
          - service: media_player.media_stop
            target:
              entity_id: media_player.nest_mini_office

    - obj: "p1b23" # next
      properties:
        "text_opa": "{{ '80' if states('media_player.nest_mini_office') in ['unavailable', 'unknown'] else '255' }}"
      event:
        "down":
          - service: media_player.media_next_track
            target:
              entity_id: media_player.nest_mini_office

    - obj: "p1b24" # mute
      properties:
        "text_color": >
          {% if state_attr('media_player.nest_mini_office', 'is_volume_muted') %}
            red
          {% else %}
            #cad3f5
          {% endif %}
        "text_opa": "{{ '80' if states('media_player.nest_mini_office') in ['unavailable', 'unknown'] else '255' }}"
      event:
        "down":
          - service: media_player.volume_mute
            data:
              entity_id: media_player.nest_mini_office
              is_volume_muted:  >
                {% if state_attr('media_player.nest_mini_office', 'is_volume_muted') %}
                  false
                {% else %}
                  true
                {% endif %}

    - obj: "p1b25" # power
      properties:
        "text_color": "{{ '#B00000' if states('media_player.nest_mini_office') == 'off' else '#FFFFFF' }}"
        "text_opa": "{{ '80' if states('media_player.nest_mini_office') in ['unavailable', 'unknown'] else '255' }}"
      event:
        "down":
          - service: media_player.toggle
            data:
              entity_id: media_player.nest_mini_office

    - obj: "p1b41" # spotcast logo
      properties:
        "text": "{{ state_attr('media_player.nest_mini_office','media_artist') if state_attr('media_player.nest_mini_office','media_artist') else '-' }}"
        <<: &mp_not_playing
          "hidden": "{{ 'false' if (states('media_player.nest_mini_office') not in ['playing','paused','idle','buffering']) else 'true' }}"
      event:
        "down":
          - service: script.turn_on
            data:
              entity_id: script.spotcast_office

    # ==================================================================================
    # ==================================================================================
    # ========================================================================== PAGE 05

    # --------------------------------------------------------- snapshot buttons

    # ________________________________________________________ camchemin
    - obj: "p5b21"
      event:
        "up":
          - service: openhasp.push_image
            data:
              obj: p5b11
              image: # your_camera_stream
              width: 480
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b22.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b23.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b24.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel

    # ________________________________________________________ camjardin
    - obj: "p5b22"
      event:
        "down":
          - service: openhasp.push_image
            data:
              obj: p5b11
              image: # your_camera_stream
              width: 480
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b21.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b23.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b24.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel

    # _______________________________________________________ camparking
    - obj: "p5b23"
      event:
        "down":
          - service: openhasp.push_image
            data:
              obj: p5b11
              image: # your_camera_stream
              width: 480
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b21.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b22.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b24.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel

    # ___________________________________________________________ camrue
    - obj: "p5b24"
      event:
        "down":
          - service: openhasp.push_image
            data:
              obj: p5b11
              image: # your_camera_stream
              width: 480
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b21.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b22.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel
          - service: openhasp.command
            data:
              keyword: p5b23.val
              parameters: "0"
            target:
              entity_id: openhasp.crowpanel

    # ________________________________________________________ portillon
    - obj: "p5b25"
      properties:
        "bg_color": "{{ '#ff6c00' if states('binary_sensor.io_frient_garage_09c6_input_4') == 'on' else '#120d38' }}"
        "text": "{{ '\uEFC6' if states('binary_sensor.io_frient_garage_09c6_input_4') == 'on' else '\uE33E' }}"
        "text_color": "{{ 'black' if states('binary_sensor.io_frient_garage_09c6_input_4') == 'on' else '#cad3f5' }}"
      event:
        "down":
          - service: lock.unlock
            target:
              entity_id: lock.gate

    # __________________________________________________________ lumiere
    - obj: "p5b26"
      properties:
        "val": >
          {% if is_state('light.ip091_shelly_one_cour','on') %}
            1
          {% else %}
            0
          {% endif %}
      event:
        "down":
          - service: light.toggle
            target:
              entity_id: light.ip091_shelly_one_cour

    # ==================================================================================
    # ==================================================================================
    # ========================================================================== PAGE 06

    - obj: "p6b20"
      properties:
        "val": >
          {% if is_state('input_select.alarm_mode_openhasp', 'arm_away') %}
            0
          {% elif is_state('input_select.alarm_mode_openhasp', 'arm_home') %}
            1
          {% elif is_state('input_select.alarm_mode_openhasp', 'arm_night') %}
            2
          {% elif is_state('input_select.alarm_mode_openhasp', 'disarm') %}
            3
          {% endif %}
      event:
        "changed":
          - service: input_select.select_option
            data:
              option: >
                {% if val == 0 %}
                  arm_away
                {% elif val == 1 %}
                  arm_home
                {% elif val == 2 %}
                  arm_night
                {% elif val == 3 %}
                  disarm
                {% endif %}
            target:
              entity_id: input_select.alarm_mode_openhasp

    # ==================================================================================
    # ==================================================================================
    # ==================================================================================

    # --------------------------------------------------------- misc information

    - obj: "p1b91"
      <<: &date
        properties:
          "text": "{{ state_attr('sensor.tplt_date_fr_full','date_fr_weekday') }} {{ state_attr('sensor.tplt_date_fr_full','date_fr_day') }}/{{ state_attr('sensor.tplt_date_fr_full','date_fr_month_number') }}"
    - obj: "p1b92"
      <<: &hour
        properties:
          "text": "{{ as_timestamp(now()) | timestamp_custom('%H:%M') }}"
    - obj: "p1b93"
      properties:
        <<: *alarm_color

    - obj: "p6b91"
      <<: *date
    - obj: "p6b92"
      <<: *hour
    - obj: "p6b93"
      properties:
        <<: *alarm_color
2 « J'aime »