Projet station météo

Salut,

Attendons d’avoir des retours de @Jeffodilo et de @brocopike . Ce n’est que peut-être qu’un soucis de calibration ou alors un capteur défectueux, attends d’autres retours.

Toutefois n’hésitez pas à éditer vos messages plutôt que d’en faire 3/4 à la suite, ça sera plus fluide et simple à lire et suivre.

De mon côté, je vais attendre avant de foncer pour l’achat d’un autre capteur ou abri Stevenson… le budget du projet est assez élevé et je vais tenter de faire avec ce que j’ai. :slight_smile:

Salut,
Je n’ai plus trop à dire de plus sur le sujet.
Sans soleil direct, mes 2 sondes ont les mêmes valeurs, exemple la nuit ou jour sans soleil, c’est nickel. Avec un soleil d’hiver pas trop fort, les différences sont déjà notables.
J’ai regardé les sites météo, la tendance est sonde sous abri Stevenson à l’ombre ou très ventilé. Je ne vais pas rajouter un abri ventilé même si je pense que je pourrais le fabriquer ( je suis en 220v, j’ai une imprimante 3D). La sonde est aussi peut-être trop emprisonnée dans la boîte dans l’abri Stevenson mais à l’abri de l’humidité aussi. J’ai déjà fait l’expérience de l’oxydation des sondes sur PCB.
Dans mon cas à moi, je peux déplacer mon abri à l’ombre assez facilement. C’est ce que je ferais quand il fera meilleur.

1 « J'aime »

Bonjour

2 idées DIY pour l’abri 1er ici le 2eme ici

C’est ce que j’ai fabriqué comme type d’abri positionne 100% du temps à l’ombre. Initialement pour une sonde bme180 qui s’est oxydée et remplacée depuis par une sonde ds18b20. Ca fait 3,5 ans que j’ai mis cela en place.
C’est avec cette sonde que je fais des comparatifs

2 « J'aime »

Bonjour. Tu utilises quoi comme carte home assistant pour afficher les infos Vitesse vent, rafale 10mn, luminosité, pression, etc… ? Merci

Bonjour,
Celle indiquée dans mon post un peu plus haut

https://github.com/aukedejong/lovelace-windrose-card

Oui j’ai toujours les deux mais je n’affiche que la valeur du BH1750 car le TSL2561 sature très vite

Salut @brocopike

De ton côté, tu n’as pas de problème avec les valeurs de ton capteur de température par rapport à celle données par la météo local ?

Je te conseille le OPT3001 pour remplacer celui qui sature, il a une amplitude beaucoup plus large !
Si tu veux ajouter le capteur UV, le montage de @Jeffodilo est très bien également (c.f. son github) :wink:

Bonjour,

J’ai profité d’un peu de temps pour mettre à disposition mes configurations de carte et ma configuration de mon code esphome de ma station sur mon https://github.com/Jeffodilo/Weather-station-ESPHOME
Je les poste ici dans l’état actuel sachant que je n’y touche plus beaucoup, ca me convient pour le moment :

Code card windrose
type: custom:windrose-card
data_period:
  period_selector:
    location: bottom
    active_color: black
    active_bg_color: gold
    buttons:
      - hours: 1
        title: 1 heure
        active: true
      - hours: 8
        title: 8 heures
      - hours: 24
        title: 1 jour
      - hours: 240
        title: 10 jours
windspeed_bar_full: true
wind_direction_entity:
  entity: sensor.station_meteo_direction_cardinale_du_vent
windspeed_entities:
  - entity: sensor.station_meteo_vitesse_du_vent
    name: Vitesse
    output_speed_unit: kph
    speed_range_beaufort: false
    speed_ranges:
      - from_value: 0
        color: hsl(195, 95%, 55%)
      - from_value: 10
        color: hsl(200, 95%, 52%)
      - from_value: 20
        color: hsl(185, 95%, 48%)
      - from_value: 30
        color: hsl(165, 95%, 45%)
      - from_value: 40
        color: hsl(135, 95%, 45%)
      - from_value: 50
        color: hsl(90, 95%, 48%)
      - from_value: 60
        color: hsl(65, 95%, 50%)
      - from_value: 70
        color: hsl(45, 95%, 50%)
      - from_value: 80
        color: hsl(30, 95%, 50%)
      - from_value: 90
        color: hsl(15, 95%, 50%)
      - from_value: 100
        color: hsl(0, 95%, 50%)
  - entity: sensor.station_meteo_rafale_10m
    name: Rafale 10m
    output_speed_unit: kph
    speed_range_beaufort: false
    speed_ranges:
      - from_value: 0
        color: hsl(195, 90%, 55%)
      - from_value: 10
        color: hsl(210, 90%, 50%)
      - from_value: 20
        color: hsl(165, 90%, 45%)
      - from_value: 30
        color: hsl(120, 90%, 45%)
      - from_value: 50
        color: hsl(60, 95%, 50%)
      - from_value: 70
        color: hsl(35, 95%, 50%)
      - from_value: 90
        color: hsl(0, 95%, 50%)
current_direction:
  show_arrow: true
  arrow_size: 80
  center_circle_size: 30
  hide_direction_below_speed: 3
corner_info:
  top_left:
    label: Vent
    entity: sensor.station_meteo_vitesse_du_vent
    unit: " Km/h"
    color: rgb(127,255,212)
    label_text_size: 50
    value_text_size: 60
    precision: 0
  top_right:
    label: Rafale
    entity: sensor.station_meteo_rafale_max_jour
    color: rgb(127,255,212)
    unit: " Km/h"
    label_text_size: 50
    value_text_size: 60
  bottom_left:
    label: Pression
    entity: sensor.bain_de_bretagne_pressure
    color: rgb(154,205,50)
    unit: " hPa"
    label_text_size: 50
    value_text_size: 60
    precision: 0
  bottom_right:
    label: Pluie
    entity: sensor.station_meteo_precipitation_journaliere
    color: rgb(154,205,50)
    unit: " mm"
    label_text_size: 50
    value_text_size: 60
    precision: 1
actions:
  top_left:
    tap_action:
      entity: sensor.station_meteo_vitesse_du_vent
      action: more-info
  top_right:
    tap_action:
      entity: sensor.station_meteo_rafale_max_jour
      action: more-info
  windrose:
    tap_action:
      action: navigate
      navigation_path: /config/devices/device/bf03c49d803e88cbef4e231601c36f8c
  bottom_left:
    tap_action:
      entity: sensor.bain_de_bretagne_pressure
      action: more-info
  bottom_right:
    tap_action:
      entity: sensor.station_meteo_precipitation_journaliere
      action: more-info
  speed_bar_1:
    tap_action:
      entity: sensor.station_meteo_vitesse_du_vent
      action: more-info
  speed_bar_2:
    tap_action:
      entity: sensor.station_meteo_rafale_10m
      action: more-info
direction_labels:
  cardinal_direction_letters: NESO
  show_cardinal_directions: true
  show_intercardinal_directions: true
  show_secondary_intercardinal_directions: false
  cardinal_directions_text_size: 60
  intercardinal_directions_text_size: 45
  secondary_intercardinal_directions_text_size: 30
show_intercardinal_directions: true
show_secondary_intercardinal_directions: true
matching_strategy: full-time
center_calm_percentage: false
colors:
  rose_lines: white
  rose_cardinal_direction_labels: gold
  rose_intercardinal_direction_labels: white
  rose_secondary_intercardinal_direction_labels: yellow
  rose_center_percentage: red
  rose_percentages: gold
  rose_current_direction_arrow: purple
  bar_border: hsl(200, 100%, 60%)
  bar_unit_name: white
  bar_name: white
  bar_unit_values: white
  bar_percentages: auto

Code carte capteurs temp, pluie, lux et UV
type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - type: custom:mini-graph-card
        color_thresholds:
          - color: "#0000ff"
            value: 0
          - color: "#0020ff"
            value: 2
          - color: "#0040ff"
            value: 4
          - color: "#0060ff"
            value: 6
          - color: "#0080ff"
            value: 8
          - color: "#00a0ff"
            value: 10
          - color: "#00c0ff"
            value: 12
          - color: "#00e0ff"
            value: 14
          - color: "#00ffff"
            value: 15
          - color: "#00ff80"
            value: 16
          - color: "#40ff40"
            value: 17
          - color: "#80ff00"
            value: 18
          - color: "#80ff00"
            value: 19
          - color: "#ffff00"
            value: 20
          - color: "#ffe000"
            value: 21
          - color: "#ffc000"
            value: 22
          - color: "#ffd000"
            value: 23
          - color: "#ffa500"
            value: 24
          - color: "#ff9400"
            value: 25
          - color: "#ff8800"
            value: 26
          - color: "#ff8000"
            value: 27
          - color: "#ff8000"
            value: 28
          - color: "#ff0000"
            value: 30
          - color: "#e00000"
            value: 32
          - color: "#c00000"
            value: 34
          - color: "#b00000"
            value: 36
        color_thresholds_transition: smooth
        entities:
          - entity: sensor.station_meteo_temperature
            name: Temperature
        decimals: 1
        group: false
        hour24: true
        line_width: 2
        points_per_hour: 4
        show:
          extrema: true
          fill: fade
          icon: true
          labels: false
          name: true
          state: true
      - type: custom:mini-graph-card
        color_thresholds:
          - color: "#fe2712"
            value: 40
          - color: "#fefe33"
            value: 60
          - color: "#66b032"
            value: 80
          - color: "#0000cd"
            value: 90
        color_thresholds_transition: smooth
        entities:
          - entity: sensor.station_meteo_humidite
            name: Humidité
        decimals: 0
        group: false
        hour24: true
        line_width: 2
        points_per_hour: 4
        show:
          extrema: true
          fill: fade
          icon: true
          labels: false
          name: true
          state: true
  - type: horizontal-stack
    cards:
      - type: custom:mini-graph-card
        color_thresholds:
          - color: "#0000cd"
            value: 10
          - color: "#00BFFF"
            value: 0
        color_thresholds_transition: smooth
        entities:
          - entity: sensor.station_meteo_precipitation_journaliere
            name: Pluie jour
        decimals: 1
        group: false
        hour24: false
        hours_to_show: 24
        show:
          graph: bar
          extrema: true
          fill: fade
          icon: true
          labels: false
          name: true
          state: true
      - type: custom:mini-graph-card
        color_thresholds:
          - color: "#0000cd"
            value: 10
          - color: "#00BFFF"
            value: 0
        color_thresholds_transition: smooth
        entities:
          - entity: sensor.station_meteo_precipitation_par_heure
            name: Pluie ratio
        group: false
        hour24: false
        hours_to_show: 24
        show:
          graph: bar
          extrema: true
          fill: fade
          icon: true
          labels: false
          name: true
          state: true
  - type: horizontal-stack
    cards:
      - type: custom:mini-graph-card
        entities:
          - entity: sensor.station_meteo_luminosite
            name: Luminosité
            format: precision 1
        color_thresholds:
          - color: "#ff3b30"
            value: 25000
          - color: "#ff8a65"
            value: 15000
          - color: "#ffcc80"
            value: 10000
          - color: "#fff9c4"
            value: 5000
          - color: "#dcedc8"
            value: 2500
          - color: "#a5d6a7"
            value: 1000
          - color: "#81c784"
            value: 0
        color_thresholds_transition: smooth
        decimals: 0
        group: false
        hour24: true
        line_width: 2
        points_per_hour: 4
        show:
          extrema: true
          fill: fade
          icon: true
          labels: false
          name: true
          state: true
      - type: custom:mini-graph-card
        entities:
          - entity: sensor.station_meteo_uv_index
            name: UV Index
        color_thresholds:
          - color: "#e1011b"
            value: 11
          - color: "#e94153"
            value: 8
          - color: "#ffa304"
            value: 6
          - color: "#ffb636"
            value: 3
          - color: "#72c900"
            value: 0
        color_thresholds_transition: hard
        decimals: 1
        group: false
        hour24: true
        line_width: 2
        points_per_hour: 4
        show:
          extrema: true
          fill: fade
          icon: true
          labels: false
          name: true
          state: true
  - type: horizontal-stack
    cards:
      - type: custom:mini-graph-card
        entities:
          - entity: sensor.bain_de_bretagne_pressure
            name: Pression
        color_thresholds:
          - color: "#ffcc33"
            value: 1025
          - color: "#00B7eb"
            value: 975
        color_thresholds_transition: smooth
        decimals: 0
        group: false
        hour24: true
        line_width: 2
        points_per_hour: 4
        show:
          extrema: true
          fill: fade
          icon: true
          labels: false
          name: true
          state: true

Code carte capteurs vent
type: horizontal-stack
cards:
  - type: custom:mini-graph-card
    entities:
      - entity: sensor.station_meteo_vitesse_du_vent
        name: Vitesse vent
    color_thresholds:
      - color: "#fa00ff"
        value: 80
      - color: "#fdb5aa"
        value: 70
      - color: "#fdb5aa"
        value: 50
      - color: "#ffffbb"
        value: 30
      - color: "#82c93f"
        value: 0
    color_thresholds_transition: hard
    decimals: 0
    group: false
    hour24: true
    line_width: 2
    points_per_hour: 4
    show:
      extrema: true
      fill: fade
      icon: true
      labels: false
      name: true
      state: true
  - type: custom:mini-graph-card
    entities:
      - entity: sensor.station_meteo_rafale_10m
        name: Rafale 10 min
    color_thresholds:
      - color: "#fa00ff"
        value: 80
      - color: "#fdb5aa"
        value: 60
      - color: "#fdb5aa"
        value: 40
      - color: "#ffffbb"
        value: 20
      - color: "#82c93f"
        value: 0
    color_thresholds_transition: hard
    decimals: 0
    group: false
    hour24: true
    line_width: 2
    points_per_hour: 4
    show:
      extrema: true
      fill: fade
      icon: true
      labels: false
      name: true
      state: true

Merci beaucoup pour ce boulot et surtout le partage sans limite que tu en fais. :slight_smile:

Petite question.
En me renseignant sur le capteur VEML7700 il y a un paramètre intégré « glass_attenuation_factor » qui permet la prise en compte de l’atténuation de la luminosité quand le capteur est placé derrière une vitre. Je ne vois pas où tu gères ça dans ton YAML.

Je ne le gère pas :laughing:, j’utilise un bh1750.
Pour l’instant je n’exploite pas ce capteur, pour mes scnérios de volets et lumière selon la luminosité, j’utilise depuis 5 ans un capteur aqara de luminosité posé sur une fenêtre à l’ombre et à la lumière de tout.

Merci pour la précision. :smiley:

Et pour les branchements des capteurs I2C, tu passes par des câbles comme ça ( Câble Adafruit 4397 Câble QT/Qwiic JST SH 4 broches avec prises femelles de qualité supérieure 150 mm - Rouge, Noir, Bleu, Jaune - Cuivre, PVC coloré : Amazon.fr: Commerce, Industrie et Science), tu soudes sans passer par des connecteurs ?
Merci ! :slight_smile:

Pour ma part, j’ai soudé des fils dupont directement sur les capteurs. Ca reste modifiable en cas de besoin et j’ai ponté plusieurs capteurs par la même occasion.

J’ai soudé des fils sur chaque capteur que je ponte ensemble sur des wago dans la boîte des capteurs. Je peux donc retirer et rajouter des capteurs facilement.

Merci à vous, j’avais en tête que e pontage était particulier niveau branchements, mais il suffit en fait de ramener les différentes pattes des composants dans les Wago et zou. :slight_smile:

EDIT> Je suis tombé par hasard sur le capteur AS3935, détecteur de foudre. Il y en a qui ont déjà testé ça ?
C’est apparemment compatible ESPHome. :slight_smile:

1 « J'aime »

Bonjour,
Après avoir fait une page spéciale pour la station, je cherchais des petites cartes simplifiées pour intégrer à mon dashboard principale pour ma tablette. Avec l’aide, il faut l’avouer de chatgpt, j’ai fait ceci avec l’incroyable custom: button-card qui permet tout. Cela change en fonction des états du jour et de la nuit et les infos de rafale de vent… Elles s’éclairsissent en fonction du moment la journée et de la luminosité. Je souhaitais la partager avec vous !

Code

`type: horizontal-stack
cards:

  • type: custom:mod-card
    card:
    type: custom:button-card
    entity: sensor.station_meteo_temperature
    show_name: false
    show_state: true
    icon: |
    [[[
    const t = Number(entity.state);

      if (t < 0) return "mdi:snowflake";
      if (t < 10) return "mdi:thermometer-low";
      if (t < 25) return "mdi:thermometer";
      if (t < 32) return "mdi:thermometer-high";
      return "mdi:fire";
    ]]]
    

    styles:
    card:
    - width: 80px
    - height: 80px
    - border-radius: 50%
    - padding: 10px
    - font-family: sans-serif
    - overflow: hidden
    icon:
    - position: absolute
    - top: 6%
    - width: 26px
    - height: 26px
    - color: var(–icon-color)
    - filter: drop-shadow(0 0 6px rgba(0,0,0,0.4))
    - animation: var(–icon-animation)
    state:
    - position: absolute
    - top: 58%
    - font-size: 13px
    - font-weight: 700
    - color: var(–text-color)
    - text-shadow: 0 0 1px rgba(0,0,0,0.2)
    card_mod:
    style: |
    ha-card {

        {% set lux = states('sensor.luxmetre_illuminance') | float(0) %}
        {% set sun = states('sun.sun') %}
        {% set night = lux < 10 or sun.state == 'below_horizon' %}
    
        {% if night %}
          /* 🌙 Mode nuit léger */
          filter: brightness(0.9);  /* juste un léger assombrissement */
          background: linear-gradient(180deg, #1a2a3a, #2c3e50); /* bleu doux */
          --text-color: #d0d8e0;  /* texte adouci */
          --icon-color: #9bb0c4;  /* icône légèrement plus froide */
        {% endif %}
    
        {% set t = states('sensor.station_meteo_temperature') | float(0) %}
    
        {% if t < -5 %}
          /* 🧊 Froid extrême */
          background: linear-gradient(180deg, #0f2027, #203a43);
          --text-color: #e0f7fa;
          --icon-color: #81ecec;
          --icon-animation: frost 3s infinite ease-in-out;
    
        {% elif t < 0 %}
          /* ❄️ Gel */
          background: linear-gradient(180deg, #1e3c72, #2a5298);
          --text-color: #ecf0f1;
          --icon-color: #74b9ff;
          --icon-animation: frost 4s infinite ease-in-out;
    
        {% elif t < 5 %}
          /* 🥶 Très froid (bleu froid clair) */
          background: linear-gradient(180deg, #6fa3d8, #b6d7f2);
          --text-color: #123047;
          --icon-color: #2d6cdf;
          --icon-animation: none;
    
        {% elif t < 10 %}
          /* 🧥 Froid */
          background: linear-gradient(180deg, #a1c4fd, #c2e9fb);
          --text-color: #2c3e50;
          --icon-color: #0984e3;
          --icon-animation: none;
    
        {% elif t < 18 %}
          /* 🌤 Frais */
          background: linear-gradient(180deg, #d4fc79, #96e6a1);
          --text-color: #1e272e;
          --icon-color: #2ecc71;
          --icon-animation: none;
    
        {% elif t < 25 %}
          /* 🙂 Tempéré */
          background: linear-gradient(180deg, #fdfbfb, #ebedee);
          --text-color: #2c3e50;
          --icon-color: #f1c40f;
          --icon-animation: none;
    
        {% elif t < 32 %}
          /* 🌞 Chaud */
          background: linear-gradient(180deg, #fceabb, #f8b500);
          --text-color: #2c3e50;
          --icon-color: #f39c12;
          --icon-animation: heat 2.5s infinite ease-in-out;
    
        {% else %}
          /* 🔥 Canicule */
          background: linear-gradient(180deg, #ff512f, #dd2476);
          --text-color: #ffffff;
          --icon-color: #ffdd59;
          --icon-animation: heat 1.8s infinite ease-in-out;
    
        {% endif %}
      }
    
      /* 🌡 Animations */
      @keyframes frost {
        0% { filter: brightness(1); }
        50% { filter: brightness(1.2); }
        100% { filter: brightness(1); }
      }
    
      @keyframes heat {
        0% { transform: scale(1); }
        50% { transform: scale(1.08); }
        100% { transform: scale(1); }
      }
    

    style: |
    ha-card {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    width: 100%;
    }

  • type: custom:mod-card
    card:
    type: custom:button-card
    entity: sensor.station_meteo_vitesse_du_vent
    show_name: false
    show_state: true
    icon: |
    [[[
    const wind = Number(entity.state);
    const gust = Number(states[‹ sensor.station_meteo_rafale_10m ›]?.state || 0);

      if (gust >= 50) return "mdi:weather-windy-variant";
      if (gust >= 30) return "mdi:weather-windy";
      if (wind >= 15) return "mdi:weather-windy";
      return "mdi:weather-cloudy";
    ]]]
    

    styles:
    card:
    - width: 80px
    - height: 80px
    - border-radius: 50%
    - padding: 10px
    - font-family: sans-serif
    - overflow: hidden
    icon:
    - position: absolute
    - top: 8%
    - width: 26px
    - height: 26px
    - color: var(–icon-color)
    - filter: drop-shadow(0 0 6px rgba(0,0,0,0.4))
    - animation: var(–icon-animation)
    state:
    - position: absolute
    - top: 50%
    - font-size: 13px
    - font-weight: 700
    - color: var(–text-color)
    - text-shadow: 0 0 1px rgba(0,0,0,0.2)
    custom_fields:
    rafale:
    - position: absolute
    - top: 70%
    - left: 50%
    - transform: translateX(-50%)
    - font-size: 12px
    - font-weight: 600
    - color: |
    [[[
    const g = Number(states[‹ sensor.station_meteo_rafale_max_jour ›]?.state || 0);
    if (g < 20) return ‹ #95a5a6 ›; // gris doux
    if (g < 40) return ‹ #6c8f7d ›; // vert-gris naturel (beaucoup plus discret)
    if (g < 60) return ‹ #d68910 ›; // orange plus sourd
    return ‹ #c0392b ›; // rouge profond
    ]]]
    - text-shadow: 0 0 1px rgba(0,0,0,0.2)
    - text-align: center
    custom_fields:
    rafale: |
    [[[
    const gustMax = Number(states[‹ sensor.station_meteo_rafale_max_jour ›]?.state || 0);
    return ${Math.round(gustMax)} km/h;
    ]]]
    card_mod:
    style: |
    ha-card {

        {% set lux = states('sensor.luxmetre_illuminance') | float(0) %}
        {% set sun = states('sun.sun') %}
        {% set night = lux < 10 or sun.state == 'below_horizon' %}
    
        {% if night %}
          /* 🌙 Mode nuit léger */
          filter: brightness(0.9);  /* juste un léger assombrissement */
          background: linear-gradient(180deg, #1a2a3a, #2c3e50); /* bleu doux */
          --text-color: #d0d8e0;  /* texte adouci */
          --icon-color: #9bb0c4;  /* icône légèrement plus froide */
        {% endif %}
    
        {% set wind = states('sensor.station_meteo_vitesse_du_vent') | float(0) %}
        {% set gust = states('sensor.station_meteo_rafale_10m') | float(0) %}
    
        {% if wind < 1 %}
          /* 🌫 Calme plat */
          background: linear-gradient(180deg, #e0eafc, #cfdef3);
          --text-color: #2c3e50;
          --icon-color: #b2bec3;
    
        {% elif wind < 5 %}
          /* 🌬 Très faible */
          background: linear-gradient(180deg, #dfe9f3, #ffffff);
          --text-color: #2c3e50;
          --icon-color: #74b9ff;
    
        {% elif wind < 15 %}
          /* 🍃 Brise */
          background: linear-gradient(180deg, #a1c4fd, #c2e9fb);
          --text-color: #2c3e50;
          --icon-color: #0984e3;
    
        {% elif wind < 30 %}
          /* 🌬 Vent modéré */
          background: linear-gradient(180deg, #6fdcbf, #2ecc71);
          --text-color: #0b2e1a;
          --icon-color: #1e8449;
    
        {% elif wind < 50 %}
          /* 💨 Vent fort */
          background: linear-gradient(180deg, #667db6, #485563);
          --text-color: #ecf0f1;
          --icon-color: #81ecec;
    
        {% else %}
          /* 🌪 Tempête */
          background: linear-gradient(180deg, #232526, #414345);
          --text-color: #ffffff;
          --icon-color: #dfe6e9;
    
        {% endif %}
    
        /* 💨 Animation selon rafales */
        {% if gust < 10 %}
          --icon-animation: none;
        
        {% elif gust < 30 %}
          --icon-animation: breeze 4s infinite ease-in-out;
        
        {% elif gust < 50 %}
          --icon-animation: gust 3s infinite ease-in-out;
        
        {% else %}
          --icon-animation: storm 2s infinite ease-in-out;
        
        {% endif %}
    
      }
    
      /* 🌬 Animations adoucies */
      @keyframes breeze {
        0%   { transform: translateX(0); opacity: 0.95; }
        50%  { transform: translateX(2px); opacity: 1; }
        100% { transform: translateX(0); opacity: 0.95; }
      }
    
      @keyframes gust {
        0%   { transform: translateX(0); }
        50%  { transform: translateX(3px); }
        100% { transform: translateX(0); }
      }
    
      @keyframes storm {
        0%   { transform: translateX(-3px); }
        50%  { transform: translateX(3px); }
        100% { transform: translateX(-3px); }
      }
    

    style: |
    ha-card {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    width: 100%;
    }

  • type: custom:mod-card
    card:
    type: custom:button-card
    entity: sensor.station_meteo_precipitation_journaliere
    show_name: false
    show_state: true
    icon: |
    [[[
    const daily = Number(entity.state);
    const rate = Number(states[‹ sensor.station_meteo_precipitation_par_heure ›]?.state || 0);

      if (rate > 0.1) return "mdi:weather-pouring";
      if (rate > 0.02) return "mdi:weather-rainy";
      if (rate > 0) return "mdi:weather-partly-rainy";
      if (daily > 0) return "mdi:weather-cloudy";
      return "mdi:weather-cloudy";
    ]]]
    

    styles:
    card:
    - width: 80px
    - height: 80px
    - border-radius: 50%
    - padding: 10px
    - font-family: sans-serif
    - overflow: hidden
    icon:
    - position: absolute
    - top: 6%
    - width: 26px
    - height: 26px
    - color: var(–icon-color)
    - filter: drop-shadow(0 0 6px rgba(0,0,0,0.4))
    - animation: var(–icon-animation)
    state:
    - position: absolute
    - top: 58%
    - font-size: 13px
    - font-weight: 700
    - color: var(–text-color)
    - text-shadow: 0 0 1px rgba(0,0,0,0.2)
    card_mod:
    style: |
    ha-card {

        {% set lux = states('sensor.luxmetre_illuminance') | float(0) %}
        {% set sun = states('sun.sun') %}
        {% set night = lux < 10 or sun.state == 'below_horizon' %}
    
        {% if night %}
          /* 🌙 Mode nuit léger */
          filter: brightness(0.9);  /* juste un léger assombrissement */
          background: linear-gradient(180deg, #1a2a3a, #2c3e50); /* bleu doux */
          --text-color: #d0d8e0;  /* texte adouci */
          --icon-color: #9bb0c4;  /* icône légèrement plus froide */
        {% endif %}
    
        {% set daily = states('sensor.station_meteo_precipitation_journaliere') | float(0) %}
        {% set rate = states('sensor.station_meteo_precipitation_par_heure') | float(0) %}
    
        {% if daily == 0 %}
          /* ☁️ Sec */
          background: linear-gradient(180deg, #757f9a, #d7dde8);
          --text-color: #2c3e50;
          --icon-color: #636e72;
    
        {% elif daily < 2 %}
          /* 🌫 Journée humide */
          background: linear-gradient(180deg, #667db6, #485563);
          --text-color: #ecf0f1;
          --icon-color: #74b9ff;
    
        {% elif daily < 8 %}
          /* 🌧 Journée pluvieuse */
          background: linear-gradient(180deg, #4b6cb7, #182848);
          --text-color: #ecf0f1;
          --icon-color: #81ecec;
    
        {% elif daily < 20 %}
          /* 🌧🌧 Forte pluie */
          background: linear-gradient(180deg, #283048, #859398);
          --text-color: #ffffff;
          --icon-color: #00cec9;
    
        {% else %}
          /* ⛈ Épisode intense */
          background: linear-gradient(180deg, #141e30, #243b55);
          --text-color: #ffffff;
          --icon-color: #0984e3;
    
        {% endif %}
    
        /* 💧 Animation selon intensité instantanée */
        {% if rate == 0 %}
          --icon-animation: none;
    
        {% elif rate < 0.05 %}
          --icon-animation: drizzle 3s infinite ease-in-out;
    
        {% elif rate < 0.10 %}
          --icon-animation: rain 1.8s infinite linear;
    
        {% else %}
          --icon-animation: rain 0.9s infinite linear;
    
        {% endif %}
      }
    
      /* 💧 Animations */
      @keyframes drizzle {
        0% { transform: translateY(0); opacity: 0.7; }
        50% { transform: translateY(2px); opacity: 1; }
        100% { transform: translateY(0); opacity: 0.7; }
      }
    
      @keyframes rain {
        0% { transform: translateY(0); }
        100% { transform: translateY(7px); }
      }
    

    style: |
    ha-card {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    width: 100%;
    }

  • type: custom:mod-card
    card:
    type: custom:button-card
    entity: sensor.bain_de_bretagne_pressure
    show_name: false
    show_state: true
    icon: |
    [[[
    const p = Number(entity.state);

      if (p < 990) return "mdi:weather-lightning";
      if (p < 1005) return "mdi:weather-windy";
      if (p < 1015) return "mdi:weather-cloudy";
      if (p < 1025) return "mdi:weather-partly-cloudy";
      return "mdi:weather-sunny";
    ]]]
    

    styles:
    card:
    - width: 80px
    - height: 80px
    - border-radius: 50%
    - padding: 10px
    - font-family: sans-serif
    - overflow: hidden
    icon:
    - position: absolute
    - top: 6%
    - width: 26px
    - height: 26px
    - color: var(–icon-color)
    - filter: drop-shadow(0 0 6px rgba(0,0,0,0.4))
    - animation: var(–icon-animation)
    state:
    - position: absolute
    - top: 58%
    - font-size: 13px
    - font-weight: 700
    - color: var(–text-color)
    - text-shadow: 0 0 1px rgba(0,0,0,0.2)
    state_display: |
    [[[
    return Math.floor(Number(entity.state)) + " hPa";
    ]]]
    card_mod:
    style: |
    ha-card {

        {% set lux = states('sensor.luxmetre_illuminance') | float(0) %}
        {% set sun = states('sun.sun') %}
        {% set night = lux < 10 or sun.state == 'below_horizon' %}
    
        {% if night %}
          /* 🌙 Mode nuit léger */
          filter: brightness(0.9);  /* juste un léger assombrissement */
          background: linear-gradient(180deg, #1a2a3a, #2c3e50); /* bleu doux */
          --text-color: #d0d8e0;  /* texte adouci */
          --icon-color: #9bb0c4;  /* icône légèrement plus froide */
        {% endif %}
    
        {% set p = states('sensor.bain_de_bretagne_pressure') | float(0) %}
    
        {% if p < 990 %}
          /* ⛈ Dépression marquée */
          background: linear-gradient(180deg, #141e30, #243b55);
          --text-color: #ffffff;
          --icon-color: #74b9ff;
          --icon-animation: pulse 1.2s infinite ease-in-out;
    
        {% elif p < 1005 %}
          /* 🌧 Dépression */
          background: linear-gradient(180deg, #485563, #29323c);
          --text-color: #ecf0f1;
          --icon-color: #81ecec;
          --icon-animation: drift 3s infinite ease-in-out;
    
        {% elif p < 1015 %}
          /* ☁️ Pression normale */
          background: linear-gradient(180deg, #757f9a, #d7dde8);
          --text-color: #2c3e50;
          --icon-color: #636e72;
          --icon-animation: none;
    
        {% elif p < 1025 %}
          /* 🌤 Haute pression */
          background: linear-gradient(180deg, #a1c4fd, #c2e9fb);
          --text-color: #1e272e;
          --icon-color: #0984e3;
          --icon-animation: none;
    
        {% else %}
          /* ☀️ Anticyclone */
          background: linear-gradient(180deg, #fdfbfb, #ebedee);
          --text-color: #2c3e50;
          --icon-color: #f1c40f;
          --icon-animation: glow 3s infinite ease-in-out;
    
        {% endif %}
      }
    
      /* 🌫 Animations */
      @keyframes pulse {
        0% { transform: scale(1); opacity: 0.9; }
        50% { transform: scale(1.08); opacity: 1; }
        100% { transform: scale(1); opacity: 0.9; }
      }
    
      @keyframes drift {
        0% { transform: translateX(0); }
        50% { transform: translateX(4px); }
        100% { transform: translateX(0); }
      }
    
      @keyframes glow {
        0% { filter: brightness(1); }
        50% { filter: brightness(1.25); }
        100% { filter: brightness(1); }
      }
    

    style: |
    ha-card {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    width: 100%;
    }
    `

Code

`type: horizontal-stack
cards:

  • type: custom:mushroom-entity-card
    entity: sensor.saint_du_jour
    icon: mdi:calendar-star
    name: Saint du jour
    fill_container: true
    icon_color: orange
    card_mod:
    style:
    mushroom-state-info$: |
    .container {
    –card-secondary-font-size: 18px;
    –card-secondary-color: orange;
    }
  • type: horizontal-stack
    cards:
    • type: custom:mod-card
      card:
      type: custom:button-card
      entity: sun.sun
      name: Cycle solaire
      show_name: false
      show_state: false
      icon: |
      [[[
      if (entity.state === ‹ above_horizon ›) return ‹ mdi:weather-sunset-down ›;
      return ‹ mdi:weather-sunset-up ›;
      ]]]
      label: |
      [[[
      const sun = states[‹ sun.sun ›].state;
      const lever = states[‹ sensor.prochain_lever ›].state;
      const coucher = states[‹ sensor.prochain_coucher ›].state;

        if (sun === 'above_horizon') {
          return `${coucher}`;
        } else {
          return `${lever}`;
        }
      ]]]
      

      show_label: true
      styles:
      card:
      - width: 80px
      - height: 80px
      - border-radius: 50%
      - padding: 10px
      - font-family: sans-serif
      icon:
      - position: absolute
      - top: 0%
      - width: 25px
      - height: 25px
      - color: var(–icon-color)
      - filter: |
      drop-shadow(0 0 4px rgba(0,0,0,0.35))
      drop-shadow(0 0 8px rgba(0,0,0,0.25))
      name:
      - font-size: 14px
      - font-weight: bold
      - color: var(–text-color)
      label:
      - position: absolute
      - top: 35%
      - white-space: pre-line
      - font-size: 13px
      - font-weight: 700
      - color: var(–text-color)
      - text-align: center
      - text-shadow: |
      [[[
      const sun = states[‹ sun.sun ›].state;

              if (sun === 'above_horizon') {
                /* Jour : lisible sur fond clair */
                return `
                  0px 0px 2px rgba(255,255,255,0.6),
                  0px 1px 3px rgba(0,0,0,0.35)
                `;
              } else {
                /* Nuit : glow doux */
                return `
                  0px 0px 4px rgba(0,0,0,0.8),
                  0px 0px 8px rgba(0,0,0,0.4)
                `;
              }
            ]]]
      

      card_mod:
      style: |
      ha-card {

          {% set sun = state_attr('sun.sun', 'elevation') | float(-10) %}
          {% set rising = state_attr('sun.sun', 'rising') %}
      
          {% if sun < -6 %}
            /* 🌑 Nuit astronomique */
            background: linear-gradient(180deg, #000814, #001d3d);
            --text-color: #e0e6ff;
            --icon-color: #9aa7ff;
      
          {% elif sun < 0 %}
            /* 🌌 Aube / crépuscule nautique */
            background: linear-gradient(180deg, #1b2a41, #3a4f7a);
            --text-color: #eef2ff;
            --icon-color: #b3c7ff;
      
          {% elif sun < 6 %}
            /* 🌅 Aube / coucher civil */
            background: linear-gradient(180deg, #5f6f94, #c9ada7);
            --text-color: #2d3436;
            --icon-color: #e09f3e;
      
          {% elif sun < 15 %}
            /* 🌄 Soleil bas */
            background: linear-gradient(180deg, #f6d365, #fda085);
            --text-color: #2c3e50;
            --icon-color: #e67e22;
      
          {% else %}
            /* ☀️ Jour plein */
            background: linear-gradient(180deg, #fff1c1, #fef9e7);
            --text-color: #2c3e50;
            --icon-color: #f1c40f;
      
          {% endif %}
        }
      

      style: |
      ha-card {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%;
      width: 100%;
      }

    • type: custom:mod-card
      card:
      type: custom:button-card
      entity: sensor.luxmetre_illuminance
      show_name: false
      show_state: true
      icon: |
      [[[
      const lux = Number(entity.state);
      const sun = states[‹ sun.sun ›];
      const rising = sun?.attributes?.rising;
      const elevation = sun?.attributes?.elevation ?? -10;

        // 🌑 Nuit
        if (elevation < -6) return "mdi:weather-night";
      
        // 🌅 Aube (soleil sous l'horizon mais monte)
        if (elevation < 5 && rising) return "mdi:weather-sunset-up";
      
        // 🌇 Crépuscule (soleil descend)
        if (elevation < 0 && !rising) return "mdi:weather-sunset-down";
      
        // 🌄 Lever du soleil
        if (elevation < 10 && rising) return "mdi:weather-sunrise";
      
        // 🌆 Coucher du soleil
        if (elevation < 10 && !rising) return "mdi:weather-sunset";
      
        // ☀️ Jour
        if (lux < 20000) return "mdi:weather-partly-cloudy";
      
        // 🔆 Soleil haut
        return "mdi:weather-sunny";
      ]]]
      

      styles:
      card:
      - width: 80px
      - height: 80px
      - border-radius: 50%
      - padding: 10px
      - font-family: sans-serif
      icon:
      - position: absolute
      - top: 0%
      - width: 25px
      - height: 25px
      - color: var(–icon-color)
      - filter: drop-shadow(0 0 6px rgba(0,0,0,0.4))
      state:
      - position: absolute
      - top: 55%
      - font-size: 13px
      - font-weight: 700
      - color: var(–text-color)
      - text-align: center
      - white-space: nowrap
      - text-shadow: |
      [[[
      const lux = Number(entity.state);

              if (lux < 100) {
                return `
                  0px 0px 4px rgba(0,0,0,0.8),
                  0px 0px 8px rgba(0,0,0,0.4)
                `;
              } else {
                return `
                  0px 0px 2px rgba(255,255,255,0.6),
                  0px 1px 3px rgba(0,0,0,0.35)
                `;
              }
            ]]]
      

      card_mod:
      style: |
      ha-card {
      {% set lux = states(‹ sensor.luxmetre_illuminance ›) | int(0) %}

          {% if lux < 1 %}
            /* 🌑 Nuit astronomique */
            background: linear-gradient(180deg, #000008, #020024);
            --text-color: #e0e0ff;
            --icon-color: #8e9eff;
      
          {% elif lux < 10 %}
            /* 🌌 Nuit */
            background: linear-gradient(180deg, #020024, #090979);
            --text-color: #eaeaff;
            --icon-color: #a5b4fc;
      
          {% elif lux < 80 %}
            /* 🌊 Aube nautique */
            background: linear-gradient(180deg, #0f3057, #1b4965);
            --text-color: #f1f6ff;
            --icon-color: #6cb2eb;
      
          {% elif lux < 300 %}
            /* 🌅 Aube civile */
            background: linear-gradient(180deg, #355c7d, #6c5b7b);
            --text-color: #fefefe;
            --icon-color: #c7a4ff;
      
          {% elif lux < 1000 %}
            /* 🌄 Lever / coucher du soleil */
            background: linear-gradient(180deg, #f67280, #f8b195);
            --text-color: #2d3436;
            --icon-color: #e17055;
      
          {% elif lux < 5000 %}
            /* 🌤 Soleil bas */
            background: linear-gradient(180deg, #fce38a, #f38181);
            --text-color: #2c3e50;
            --icon-color: #f39c12;
      
          {% elif lux < 20000 %}
            /* ☀️ Plein jour */
            background: linear-gradient(180deg, #fffbd5, #b5eaea);
            --text-color: #1e272e;
            --icon-color: #f1c40f;
      
          {% else %}
            /* 🔆 Soleil au zénith */
            background: linear-gradient(180deg, #ffffff, #e0f7fa);
            --text-color: #1e272e;
            --icon-color: #fbc531;
      
          {% endif %}
        }
      

      style: |
      ha-card {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%;
      width: 100%;
      }
      `

1 « J'aime »

Wouah Propre je trouve

Bonjour. J’ai le même pluviomètre que toi, MISOL WH-SP-RG de chez Aliexpress, pourtant chez moi avec la même config que toi du pulse_counter, un basculement correspond à 0,6mm de pluie, je comprends pas… Peux-tu m’éclairer sur ce problème ? Merci.

Bonjour,
C’est ce qu’on retrouve dans la doc. Je t’avoue ne pas avoir testé et les valeurs sont cohérentes en fin de journée à ce que MF m’annonce, on est loin du double donc pour moi c’est 0.3mm

Bonjour, merci pour ta réponse. En fait, c’est en allant voir ton yaml sur GitHub que je me suis aperçu que ma config était pas la même que toi. La mienne était basé juste sur un pulse_counter, la tienne un peu plus sophistiquée, pulse_meter + pulse_counter. Après le test sur table de ta config, je confirme la tienne est la bonne, j’ai bien 0.3mm pour 1 pulse. Du coup, je vais reprendre la partie pluviomètre et l’adapter à ma config. Et aussi, vraiment top tous tes cartes que tu as créé pour le pluviomètre et merci encore pour le partage.

Salutations.

1 « J'aime »