Carte pour ventilateur avec oscillation verticale?

Bonjour à tous,
J'ai acheté un nouveau ventilateur Xiaomi Smart Desktop Air Circulation Fan. j'ai un Mi Smart Standing Fan 2 aussi que j'utilise avec la carte Xiaomi Smartmi Fan Card.

Les deux ventilateurs sont intégrés par l'intégration Xiaomi Mi Smart Pedestal Fan.

Le souci est que la carte Xiaomi Smartmi Fan Card n'est pas a jour pour le Xiaomi Smart Desktop Air Circulation Fan et il me manque des options.
J'ai testé avec les cartes mushroom et tuile, mais je ne suis pas fan du résultat (à la rigueur, avec la mushroom et UIX pour personnaliser les couleurs, car par défaut c'est laid).

mes essais avec la carte tuile :

la carte mushroom :

Connaissez-vous une carte pour les ventilateurs à jour avec un look sympa ?

J'ai repensé au post de @BBE et à sa room-card avec l'utilisation de custom-card-features.

Ça me plaît bien, plus qu'à finaliser la carte.

N'hésitez pas à partager vos cartes de ventilateur. :wink:

Edit :
J'ai pratiquement fini.

ventilateur éteint :

Popup des deux ventilateurs :

j'ai prit la version sur pied et c'est une tuerie, j'ai pas encore regardé pour faire une carte, faute de temps, mais je partagerai ici quand ce sera fait

Comme tu dis, une tuerie ce ventilateur sur pied ou sans pied. Le contrôle de haut en bas, c'est juste royal.

J'ai complété les options du ventilateur, elles y sont toutes maintenant :

  • Direction du ventilateur gauche, droite, haut et bas.
  • Oscillation horizontale (on/off)
  • Oscillation verticale (on/off)
  • Mode Naturel (on/off)
  • Timer (60-120-180-240 min)
  • Vitesse du ventilateur (slider)
  • Choix d'angle horizontal (30-60-90-120 °)
  • Choix d'angle vertical (30-60-90-100 °)

Après si tu veux une carte custom:button-card, n'hésite pas en envoyer un visule de ce que tu voudrais exactement et on devrais pouvoir faire ça :grin:

Merci, mais je vais pas te prendre la tête. La carte que j'ai faite me convient, j'ai accès à toutes les options du ventilateur (un peu chiant, obligé de faire des input_select, script).

Tu n'arrives à tout concentrer dans un input_text ?

Pour le timer , angle vertical et horizontal, on des données différentes.

un script :

sequence:
  - action: input_select.select_next
    target:
      entity_id: input_select.angle_horizontal_ventilateur_petit
    data:
      cycle: true
  - action: xiaomi_miio_fan.fan_set_oscillation_angle
    target:
      entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
    data:
      angle: "{{ states('input_select.angle_horizontal_ventilateur_petit') | int }}"
description: Fait défiler cycliquement les angles d'oscillation du ventilateur Xiaomi.
alias: "Ventilateur petit : Changer d'angle horizontal"
icon: mdi:rotate-3d-variant

et j'utilise le script sur un tap_action, qui boucle. Peu être pas le mieux, mais ca fonctionne et me convient.

Poste le code complet de ta carte et je regarderai ce que je peux faire avec une seule carte (button-card) et sans multiplier entrées et scripts. Je suis en congé et j'ai un peu de temps devant moi :wink:

Comme tu veux, je ne te force pas. :wink:

type: tile
grid_options:
  rows: auto
  columns: full
entity: fan.xiaomi_smart_desktop_air_circulation_fan
color: blue
state_content:
  - state
  - percentage
vertical: false
tap_action:
  action: toggle
icon_tap_action:
  action: more-info
features:
  - type: custom:service-call
    entries:
      - type: button
        icon: mdi:arrow-left
        haptics: false
        tap_action:
          action: perform-action
          perform_action: xiaomi_miio_fan.fan_turn
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data:
            direction: left
        styles: |-
          :host { 
          --icon-color: DodgerBlue; 
          --color: rgba(33,150,243,0.2);
          }
          .label {
            color: white;
          }
          .icon {
            --mdc-icon-size: 30px;
          }
        thumb: md3-fab-primary
        label: Gauche
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        toggle_styles: false
      - type: button
        icon: mdi:arrow-right
        haptics: false
        tap_action:
          action: perform-action
          perform_action: xiaomi_miio_fan.fan_turn
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data:
            direction: right
        styles: |-
          :host { 
          --icon-color: DodgerBlue; 
          --color: rgba(33,150,243,0.2);
          }
          .label {
            color: white;
          }
          .icon {
            --mdc-icon-size: 30px;
          }          
        thumb: md3-fab-primary
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        label: Droite
      - type: button
        icon: mdi:arrow-up
        haptics: false
        tap_action:
          action: perform-action
          perform_action: xiaomi_miio_fan.fan_turn
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data:
            direction: up
        styles: |-
          :host { 
          --icon-color: DodgerBlue; 
          --color: rgba(33,150,243,0.2);
          }
          .label {
            color: white;
          }
          .icon {
            --mdc-icon-size: 30px;
          }          
        thumb: md3-fab-primary
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        label: Haut
      - type: button
        icon: mdi:arrow-down
        haptics: false
        tap_action:
          action: perform-action
          perform_action: xiaomi_miio_fan.fan_turn
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data:
            direction: down
        styles: |-
          :host { 
          --icon-color: DodgerBlue; 
          --color: rgba(33,150,243,0.2);
          }
          .label {
            color: white;
          }
          .icon {
            --mdc-icon-size: 30px;
          }          
        thumb: md3-fab-primary
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        label: Bas
    styles: |-
      :host {
        --feature-button-spacing: 5px;
      }
  - type: custom:service-call
    entries:
      - type: button
        icon: |-
          {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan',
          'oscillate') == true %}
          mdi:arrow-oscillating
          {% else %}
          mdi:arrow-oscillating-off
          {% endif %}               
        tap_action:
          action: perform-action
          perform_action: script.ventilateur_petit_oscille_toggle
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data: {}
        styles: |-
          :host { 
            {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan', 'oscillate') == true %}
            --icon-color: #2196f3;
            --color: rgba(33,150,243,0.2);
            {% else %}
            --icon-color: white;
            --color: rgba(111,111,111,0.15);  
            {% endif %}
          }
          .label {
            color: white;  
          }
          .icon {
            --mdc-icon-size: 30px;
          }          
        label: |-
          {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan',
          'oscillate') == true %}
          On
          {% else %}
          Off
          {% endif %}
        haptics: false
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        value_attribute: oscillate
        thumb: md3-fab-primary
      - type: button
        icon: |-
          {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan',
          'vertical_oscillate') == true %}
          mdi:rotate-right
          {% else %}
          mdi:rotate-left
          {% endif %}        
        autofill_entity_id: true
        haptics: false
        tap_action:
          action: perform-action
          perform_action: script.ventilateur_petit_oscille_verticale_toggle
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data: {}
        styles: |-
          :host { 
            {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan', 'vertical_oscillate') == true %}
            --icon-color: #2196f3;
            --color: rgba(33,150,243,0.2);
            {% else %}
            --icon-color: white;
            --color: rgba(111,111,111,0.15);  
            {% endif %}
          }
          .label {
            color: white;  
          }
          .icon {
            --mdc-icon-size: 30px;
          }          
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        label: |-
          {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan',
          'vertical_oscillate') == true %}
          On
          {% else %}
          Off
          {% endif %}        
        thumb: md3-fab-primary
      - type: button
        icon: mdi:leaf
        autofill_entity_id: true
        haptics: false
        tap_action:
          action: perform-action
          perform_action: script.ventilateur_petit_nature_toggle
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data: {}
        styles: |-
          :host { 
            {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan', 'mode') == 'Natural' %}
            --icon-color: #2196f3;
            --color: rgba(33,150,243,0.2);
            {% else %}
            --icon-color: white;
            --color: rgba(111,111,111,0.15);  
            {% endif %}
          } .label {
            color: white;  
          }
          .icon {
            --mdc-icon-size: 30px;
          }          
        thumb: md3-fab-primary
        label: |
          {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan',
          'mode') == 'Natural' %} Naturel {% else %} Normal {% endif %}
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
      - type: button
        icon: mdi:timer
        autofill_entity_id: true
        haptics: false
        tap_action:
          action: perform-action
          perform_action: script.ventilateur_petit_changer_le_timer
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data: {}
        styles: |-
          :host { 
            {% if state_attr('fan.xiaomi_smart_desktop_air_circulation_fan', 'delay_off_countdown') > 0 %}
            --icon-color: #2196f3;
            --color: rgba(33,150,243,0.2);
            {% else %}
            --icon-color: white;
            --color: rgba(111,111,111,0.15);  
            {% endif %}
          } 
          .label {
            color: white;  
          }
          .icon {
            --mdc-icon-size: 30px;
          }          
        thumb: md3-fab-primary
        label: >-
          {{ state_attr('fan.xiaomi_smart_desktop_air_circulation_fan',
          'delay_off_countdown')}} min          
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
    styles: |-
      :host {
        --feature-button-spacing: 5px;
      }
  - type: custom:service-call
    entries:
      - type: slider
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        tap_action:
          action: perform-action
          perform_action: fan.set_percentage
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data:
            percentage: "{{ value | int }}"
        range:
          - 0
          - 100
        step: 1
        value_attribute: percentage
        label: |-
          Vitesse 
          {{ value | int }}%
        thumb: default
        styles: |-
          .container {      
            {% if is_state("fan.xiaomi_smart_desktop_air_circulation_fan", "off")  %}          
            visibility: hidden; 
            {% endif %}
          }
          .label {
            display: inline-flex;
            font-size: 15px;
          }
          :host {
            flex-basis: 258%;
          }
        ticks: false
        haptics: false
      - type: button
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        value_attribute: angle
        thumb: md3-fab-primary
        styles: |-
          :host { 
          --icon-color: DodgerBlue; 
          --color: rgba(33,150,243,0.2);
          }
          .label {
            color: white;
          }
          .icon {
            --mdc-icon-size: 30px;
          }
        icon: mdi:arrow-expand-horizontal
        label: |-
          Angle
            {{ value }}°
        tap_action:
          action: perform-action
          perform_action: script.ventilateur_petit_changer_d_angle_horizontal
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data: {}
      - type: button
        entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
        thumb: md3-fab-primary
        styles: |-
          :host { 
          --icon-color: DodgerBlue; 
          --color: rgba(33,150,243,0.2);
          }
          .label {
            color: white;
          }
          .icon {
            --mdc-icon-size: 30px;
          }
        value_attribute: vertical_angle
        label: |-
          Angle 
            {{ value |int }}°
        icon: mdi:arrow-expand-vertical
        tap_action:
          action: perform-action
          perform_action: script.ventilateur_petit_changer_d_angle_vertical
          target:
            entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
          data: {}
    styles: |-
      :host {
        --feature-button-spacing: 5px;
      }
features_position: bottom

le résultat :

une image du ventilateur :

la carte que j'utilise pour mon autre ventilateur en action. Il y a des flèches à gauche et à droite de l'image du ventilateur pour le faire bouger et un on/off du ventilateur sur l'image :
popup2
une carte qui soit dans l'identique si possible, après tu adaptes comme tu peux. Pas besoin de l'option child lock, elle peut être remplacée par le changement d'angle vertical.

ChatGPT m'a pondu ça. :heart_eyes:

popup3

button_card_templates :

button_card_templates:
  p70_small:
    show_icon: true
    show_name: true
    show_state: false
    show_label: true
    tap_action:
      haptic: light
    styles:
      card:
        - min-height: 64px
        - padding: 8px 4px
        - border-radius: 14px
        - box-shadow: none
        - border: 1px solid rgba(127, 127, 127, 0.18)
        - background: rgba(127, 127, 127, 0.07)
      grid:
        - grid-template-areas: "\"i\" \"n\" \"l\""
        - grid-template-rows: 26px min-content min-content
      icon:
        - width: 23px
        - color: var(--secondary-text-color)
      name:
        - font-size: 11px
        - font-weight: 600
        - color: var(--primary-text-color)
      label:
        - margin-top: 2px
        - font-size: 9px
        - color: var(--secondary-text-color)
  p70_speed:
    template: p70_small
    variables:
      preset: Level 1
    tap_action:
      action: call-service
      service: fan.set_preset_mode
      target:
        entity_id: "[[[ return entity.entity_id; ]]]"
      data:
        preset_mode: "[[[ return variables.preset; ]]]"
      haptic: light
    state:
      - operator: template
        value: "[[[ return entity.attributes.preset_mode === variables.preset; ]]]"
        styles:
          card:
            - background: rgba(1, 190, 158, 0.15)
            - border: 1px solid '#01be9e'
          icon:
            - color: "#01be9e"
          name:
            - color: "#01be9e"
          label:
            - color: "#01be9e"
  p70_toggle:
    template: p70_small
    variables:
      active: false
      service_on: null
      service_off: null
    tap_action:
      action: call-service
      service: >
        [[[ return variables.active ? variables.service_off :
        variables.service_on; ]]]
      target:
        entity_id: "[[[ return entity.entity_id; ]]]"
      haptic: light
    state:
      - operator: template
        value: "[[[ return Boolean(variables.active); ]]]"
        styles:
          card:
            - background: rgba(1, 190, 158, 0.15)
            - border: 1px solid '#01be9e'
          icon:
            - color: "#01be9e"
          name:
            - color: "#01be9e"
          label:
            - color: "#01be9e"
  p70_move:
    show_icon: true
    show_name: false
    show_state: false
    variables:
      direction: left
    tap_action:
      action: call-service
      service: xiaomi_miio_fan.fan_turn
      target:
        entity_id: "[[[ return entity.entity_id; ]]]"
      data:
        direction: "[[[ return variables.direction; ]]]"
      haptic: light
    hold_action:
      action: call-service
      service: xiaomi_miio_fan.fan_turn
      target:
        entity_id: "[[[ return entity.entity_id; ]]]"
      data:
        direction: "[[[ return variables.direction; ]]]"
      repeat: 350
      haptic: selection
    styles:
      card:
        - min-height: 48px
        - border-radius: 14px
        - box-shadow: none
        - border: 1px solid rgba(127, 127, 127, 0.18)
        - background: rgba(127, 127, 127, 0.07)
      icon:
        - width: 28px
        - color: var(--primary-text-color)

button-card :

type: custom:button-card
entity: fan.xiaomi_smart_desktop_air_circulation_fan
name: Xiaomi Smart Fan P70
show_icon: false
show_state: false
show_label: false
show_ripple: false
tap_action:
  action: none
hold_action:
  action: more-info
extra_styles: |
  @keyframes p70-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }
  @keyframes p70-swing-h {
    0%, 100% { transform: rotate(-9deg); }
    50%      { transform: rotate(9deg); }
  }
  @keyframes p70-swing-v {
    0%, 100% { transform: translateY(-4px); }
    50%      { transform: translateY(5px); }
  }
  .p70-status {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--secondary-text-color);
  }
  .p70-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--disabled-text-color);
  }
  .p70-dot.on {
    background: #01be9e;
    box-shadow: 0 0 9px rgba(1, 190, 158, .9);
  }
  .p70-visual {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 190px;
  }
  .p70-h.active {
    animation: p70-swing-h 4s ease-in-out infinite;
    transform-origin: 50% 100%;
  }
  .p70-v.active {
    animation: p70-swing-v 3.2s ease-in-out infinite;
  }
  .p70-shell {
    width: 154px;
    height: 154px;
    box-sizing: border-box;
    border: 10px solid rgba(127, 127, 127, .22);
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: radial-gradient(circle, rgba(127,127,127,.08) 0 54%, rgba(127,127,127,.18) 55% 58%, transparent 59%);
    box-shadow: inset 0 0 18px rgba(0,0,0,.08), 0 10px 25px rgba(0,0,0,.08);
  }
  .p70-shell.on {
    border-color: rgba(1, 190, 158, .38);
    box-shadow: inset 0 0 25px rgba(1,190,158,.13), 0 10px 28px rgba(0,0,0,.09);
  }
  .p70-blade {
    width: 112px;
    height: 112px;
    color: var(--disabled-text-color);
  }
  .p70-shell.on .p70-blade {
    color: #01be9e;
    filter: drop-shadow(0 0 7px rgba(1,190,158,.35));
  }
  .p70-blade.spinning {
    animation: p70-spin var(--p70-duration) linear infinite;
  }
  .p70-center {
    position: absolute;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--card-background-color);
    border: 2px solid rgba(127,127,127,.28);
    font-size: 9px;
    font-weight: 700;
    color: var(--secondary-text-color);
  }
  .p70-shell.on .p70-center {
    border-color: #01be9e;
    color: #01be9e;
  }
  .p70-meta {
    margin-top: 12px;
    display: flex;
    gap: 7px;
    flex-wrap: wrap;
    justify-content: center;
  }
  .p70-chip {
    padding: 4px 8px;
    border-radius: 999px;
    font-size: 10px;
    color: var(--secondary-text-color);
    background: rgba(127,127,127,.09);
    border: 1px solid rgba(127,127,127,.14);
  }
  .p70-section-title {
    margin-top: 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .12em;
    color: var(--secondary-text-color);
  }
styles:
  card:
    - padding: 18px
    - border-radius: 24px
    - overflow: hidden
  grid:
    - grid-template-areas: >-
        "n power" "status power" "visual visual" "speed_title speed_title"
        "speeds speeds" "mode_title mode_title" "modes modes" "direction_title
        direction_title" "directions directions" "cycle cycle"
    - grid-template-columns: 1fr 48px
    - grid-template-rows: >-
        min-content min-content 205px min-content min-content min-content
        min-content min-content min-content min-content
    - column-gap: 10px
    - row-gap: 10px
  name:
    - justify-self: start
    - align-self: end
    - font-size: 18px
    - font-weight: 700
  custom_fields:
    power:
      - align-self: center
      - justify-self: end
    status:
      - justify-self: start
      - align-self: start
    visual:
      - width: 100%
    speed_title:
      - justify-self: start
      - width: 100%
    mode_title:
      - justify-self: start
      - width: 100%
    direction_title:
      - justify-self: start
      - width: 100%
    speeds:
      - width: 100%
    modes:
      - width: 100%
    directions:
      - width: 100%
    cycle:
      - width: 100%
custom_fields:
  power:
    card:
      type: custom:button-card
      entity: fan.xiaomi_smart_desktop_air_circulation_fan
      icon: mdi:power
      show_name: false
      show_state: false
      tap_action:
        action: toggle
        haptic: medium
      styles:
        card:
          - width: 46px
          - height: 46px
          - border-radius: 50%
          - padding: 0
          - box-shadow: none
          - border: 1px solid rgba(127, 127, 127, 0.2)
          - background: rgba(127, 127, 127, 0.08)
        icon:
          - width: 23px
          - color: var(--secondary-text-color)
      state:
        - value: "on"
          styles:
            card:
              - background: rgba(1, 190, 158, 0.16)
              - border: 1px solid
            icon:
              - color: "#01be9e"
  status: |
    [[[
      const on = entity.state === 'on';
      const pct = Number(entity.attributes.percentage ?? entity.attributes.raw_speed ?? 0);
      const mode = entity.attributes.mode === 'Natural' ? 'Naturel' : 'Direct';
      return `<div class="p70-status">
        <span class="p70-dot ${on ? 'on' : ''}"></span>
        <span>${on ? `Allumé · ${pct}% · ${mode}` : 'Éteint'}</span>
      </div>`;
    ]]]
  visual: |
    [[[
      const on = entity.state === 'on';
      const pct = Number(entity.attributes.percentage ?? entity.attributes.raw_speed ?? 0);
      const horizontal = Boolean(entity.attributes.oscillating ?? entity.attributes.oscillate ?? false);
      const vertical = Boolean(entity.attributes.vertical_oscillate ?? false);
      const angleH = entity.attributes.angle ?? '—';
      const angleV = entity.attributes.vertical_angle ?? '—';
      const preset = entity.attributes.preset_mode ?? '—';
      const duration = Math.max(0.55, 4.6 - pct * 0.037).toFixed(2);
      return `<div class="p70-visual">
        <div class="p70-h ${on && horizontal ? 'active' : ''}">
          <div class="p70-v ${on && vertical ? 'active' : ''}">
            <div class="p70-shell ${on ? 'on' : ''}" style="position:relative">
              <ha-icon class="p70-blade ${on ? 'spinning' : ''}" style="--p70-duration:${duration}s" icon="mdi:fan"></ha-icon>
              <div class="p70-center">${on ? pct : 0}%</div>
            </div>
          </div>
        </div>
        <div class="p70-meta">
          <span class="p70-chip">${preset}</span>
          <span class="p70-chip">H ${angleH}°</span>
          <span class="p70-chip">V ${angleV}°</span>
        </div>
      </div>`;
    ]]]
  speed_title: <div class="p70-section-title">VITESSE</div>
  speeds:
    card:
      type: grid
      columns: 4
      square: false
      cards:
        - type: custom:button-card
          template: p70_speed
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          variables:
            preset: Level 1
          icon: mdi:fan
          name: Niveau 1
          label: Doux
        - type: custom:button-card
          template: p70_speed
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          variables:
            preset: Level 2
          icon: mdi:fan
          name: Niveau 2
          label: Moyen
        - type: custom:button-card
          template: p70_speed
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          variables:
            preset: Level 3
          icon: mdi:fan
          name: Niveau 3
          label: Fort
        - type: custom:button-card
          template: p70_speed
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          variables:
            preset: Level 4
          icon: mdi:fan
          name: Niveau 4
          label: Turbo
  mode_title: <div class="p70-section-title">MODES ET OPTIONS</div>
  modes:
    card:
      type: grid
      columns: 3
      square: false
      cards:
        - type: custom:button-card
          template: p70_toggle
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          variables:
            active: "[[[ return entity.attributes.mode === \"Natural\"; ]]]"
            service_on: xiaomi_miio_fan.fan_set_natural_mode_on
            service_off: xiaomi_miio_fan.fan_set_natural_mode_off
          icon: mdi:leaf
          name: Naturel
          label: >-
            [[[ return entity.attributes.mode === "Natural" ? "Activé" :
            "Désactivé"; ]]]
        - type: custom:button-card
          template: p70_small
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:swap-horizontal-bold
          name: Horizontal
          label: >
            [[[ return Boolean(entity.attributes.oscillating ??
            entity.attributes.oscillate ?? false) ? 'Activée' : 'Arrêtée'; ]]]
          tap_action:
            action: call-service
            service: fan.oscillate
            target:
              entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
            data:
              oscillating: >
                [[[ return !Boolean(entity.attributes.oscillating ??
                entity.attributes.oscillate ?? false); ]]]
            haptic: light
          state:
            - operator: template
              value: >-
                [[[ return Boolean(entity.attributes.oscillating ??
                entity.attributes.oscillate ?? false); ]]]
              styles:
                card:
                  - background: rgba(1, 190, 158, 0.15)
                icon:
                  - color: "#01be9e"
                name:
                  - color: "#01be9e"
                label:
                  - color: "#01be9e"
        - type: custom:button-card
          template: p70_toggle
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          variables:
            active: "[[[ return Boolean(entity.attributes.vertical_oscillate); ]]]"
            service_on: xiaomi_miio_fan.fan_set_vertical_oscillation_on
            service_off: xiaomi_miio_fan.fan_set_vertical_oscillation_off
          icon: mdi:swap-vertical-bold
          name: Vertical
          label: >-
            [[[ return entity.attributes.vertical_oscillate ? "Activée" :
            "Arrêtée"; ]]]
        - type: custom:button-card
          template: p70_small
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:led-on
          name: Voyant
          label: "[[[ return entity.attributes.led ? \"Allumé\" : \"Éteint\"; ]]]"
          tap_action:
            action: call-service
            service: xiaomi_miio_fan.fan_set_led_brightness
            target:
              entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
            data:
              brightness: "[[[ return entity.attributes.led ? 2 : 0; ]]]"
            haptic: light
          state:
            - operator: template
              value: "[[[ return Boolean(entity.attributes.led); ]]]"
              styles:
                card:
                  - background: rgba(1, 190, 158, 0.15)
                icon:
                  - color: "#01be9e"
                name:
                  - color: "#01be9e"
                label:
                  - color: "#01be9e"
        - type: custom:button-card
          template: p70_toggle
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          variables:
            active: "[[[ return Boolean(entity.attributes.buzzer); ]]]"
            service_on: xiaomi_miio_fan.fan_set_buzzer_on
            service_off: xiaomi_miio_fan.fan_set_buzzer_off
          icon: mdi:volume-high
          name: Bip
          label: "[[[ return entity.attributes.buzzer ? \"Activé\" : \"Muet\"; ]]]"
        - type: custom:button-card
          template: p70_toggle
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          variables:
            active: "[[[ return Boolean(entity.attributes.child_lock); ]]]"
            service_on: xiaomi_miio_fan.fan_set_child_lock_on
            service_off: xiaomi_miio_fan.fan_set_child_lock_off
          icon: mdi:lock-outline
          name: Verrou
          label: >-
            [[[ return entity.attributes.child_lock ? "Verrouillé" : "Libre";
            ]]]
  direction_title: <div class="p70-section-title">ORIENTATION — APPUI LONG POUR RÉPÉTER</div>
  directions:
    card:
      type: grid
      columns: 4
      square: false
      cards:
        - type: custom:button-card
          template: p70_move
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:chevron-left
          variables:
            direction: left
        - type: custom:button-card
          template: p70_move
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:chevron-up
          variables:
            direction: up
        - type: custom:button-card
          template: p70_move
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:chevron-down
          variables:
            direction: down
        - type: custom:button-card
          template: p70_move
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:chevron-right
          variables:
            direction: right
  cycle:
    card:
      type: grid
      columns: 3
      square: false
      cards:
        - type: custom:button-card
          template: p70_small
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:angle-acute
          name: Angle H
          label: "[[[ return `${entity.attributes.angle ?? \"—\"}°`; ]]]"
          tap_action:
            action: call-service
            service: xiaomi_miio_fan.fan_set_oscillation_angle
            target:
              entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
            data:
              angle: |
                [[[
                  const values = [30, 60, 90, 120];
                  const current = Number(entity.attributes.angle ?? 0);
                  return values.find(v => v > current) ?? values[0];
                ]]]
            haptic: light
        - type: custom:button-card
          template: p70_small
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:angle-acute
          name: Angle V
          label: "[[[ return `${entity.attributes.vertical_angle ?? \"—\"}°`; ]]]"
          tap_action:
            action: call-service
            service: xiaomi_miio_fan.fan_set_vertical_oscillation_angle
            target:
              entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
            data:
              vertical_angle: |
                [[[
                  const values = [30, 60, 90, 100];
                  const current = Number(entity.attributes.vertical_angle ?? 0);
                  return values.find(v => v > current) ?? values[0];
                ]]]
            haptic: light
        - type: custom:button-card
          template: p70_small
          entity: fan.xiaomi_smart_desktop_air_circulation_fan
          icon: mdi:timer-outline
          name: Minuterie
          label: |
            [[[
              const minutes = Number(entity.attributes.delay_off_countdown ?? 0);
              return minutes > 0 ? `${minutes} min` : 'Arrêtée';
            ]]]
          tap_action:
            action: call-service
            service: xiaomi_miio_fan.fan_set_delay_off
            target:
              entity_id: fan.xiaomi_smart_desktop_air_circulation_fan
            data:
              delay_off_countdown: |
                [[[
                  const values = [0, 60, 120, 240, 480];
                  const current = Number(entity.attributes.delay_off_countdown ?? 0);
                  return values.find(v => v > current) ?? values[0];
                ]]]
            haptic: light

edit:
version plus compacte avec slider pour la vitesse et image du ventilateur .

bonsoir,

j'ai bien avancer sur ma carte qui va s'integrer a mon dash

ventillo wip

j'ai encore un peu de travail, integrer un pad pour diriger manuellement, mais le principal est fonctionnel
du button card, des templates, du css, enfin un jolie bordel :smiley:

J'en ai profité pour faire une carte button-card pour mon Mi Smart Standing Fan 2

les cartes finalisées :

Au passage, j'ai fait une request d'icône pour custom-brand-icons qui vient d'être ajoutée.

image

image

met bouton, qui ouvre un popup avec les cartes du dessus.