Intégration pour Cave à Vin

Bonjour à tous,

J’espère poster au bon endroit.
Je voulais partager mon projet de suivi de cave à vin : Millesime.

Comme beaucoup d’entre vous, je cherchais un moyen de gérer ma cave à vin. Les applications dédiées sont souvent payantes. Alors j’ai décidé de créer ma propre intégration sur mesure — et j’en ai profité pour tester les limites de l’IA générative dans un vrai projet de développement.

Pour info, je n’ai pas encore le niveau de faire ce développement seul.

L’intégralité du projet a été développée et testée via Claude (Anthropic), sans écrire une seule ligne de code moi-même. De l’architecture backend Python à la carte Lovelace JavaScript, en passant par l’intégration Gemini AI, la gestion des erreurs Safari/iPhone, la publication HACS et la rédaction du README — tout a été généré, corrigé et itéré par l’IA.
J’ai même laissé l’IA proposer le nom de l’application.

Les fonctions de l’intégration Millésime (écrit par le développeur Claude lui-même) :
:bottle_with_popping_cork: Visualisation de la cave style Vinotag — cercles colorés sur clayettes bois
:camera: Scan d’étiquette par photo — Gemini AI identifie le vin et remplit la fiche automatiquement
:money_bag: Estimation du prix en un clic via Gemini
• ⎘ Duplication de bouteilles — pratique pour les caisses
:chart_increasing: Suivi de la valeur de la cave dans le temps avec graphique
:magnifying_glass_tilted_left: Recherche texte avec suggestions temps réel
:control_knobs: Filtres par type de vin et par événement (Grande occasion, À garder, Ne pas toucher…)
:mobile_phone: Interface pensée mobile-first / iPhone
:globe_with_meridians: Fallback Open Food Facts (150 000+ vins, sans clé)

Il aura fallut 1semaine de travail pour avoir ce résultat : ça fonctionne et les données sont cohérentes. C’est éprouvé sur la cave perso.

Le projet a été soumis au store HACS officiel et est déjà installable en dépôt custom.

Disponible sur GitHub via mon dépôt custom :
:backhand_index_pointing_right: GitHub - Redsklns/ha-millesime: Suivi de la cave à vin · GitHub

N’hésitez pas si vous avez des questions, des retours ou des idées d’amélioration !
Santé :clinking_glasses:

bonjour,

On pourrait avoir des captures d’écran pour avoir une idée du rendu? Merci!

Merci pour cette intégration

Bonjour et merci pour cette integration
chez moi, je bloque à l’étape 4 .. j’ai bien mis Ajouter une ressource URL : /local/millesime/millesime-card.js

mais il ne voit pas la carte lovelace ! que je cherche ou meme si je tape le type directement :

edit : c’est bon, j’ai trouvé. il ne m’avait pas créé le répertoire www/millesime :roll_eyes:

Bonjour,
Merci pour cette intégration.
La disposition dans ma cave est un peu différente pour le tête bêche.
Je ne sais pas si tu as possibilité de rajouter une option pour cette disposition:

En améliorations possibles je verrai bien:

  • la possibilité de pouvoir déplacer une bouteille sans avoir à la supprimer et la recréer au bon emplacement.
  • pouvoir déplacer un étage complet dans la cave.
  • quand on copie une bouteille pouvoir définir plusieurs emplacement et éviter d’avoir à faire plusieurs fois la fonction copie pour chaque bouteille identique.

Je n’ai pas compris la fonction de quantité quand on ajoute une bouteille puisque que l’on ne peut choisir qu’un seul emplacement.
Pour scanner l’étiquette cela m’ouvre l’appli photo et non pas l’appareil photo (sur Android).

:slightly_smiling_face:

Salut,

Testé rapidement et c’est un bon début ! :clap:

Quelques confirmations rapides :

  • la carte ne s’installe pas seule, même en passant par hacs. il faut faire la manip à la main
  • reconnaissance avec photo mais pas en live avec l’appareil (android)

Autre points constatés:

  • quand la reconnaissance photo ne donne rien, ça quitte le création d’un nouveau vin sans laisser la possibilité de compléter manuellement
  • j’ai 3 bouteilles qui sont listées, mais pas dans des positions de casiers, j’ai pas trouver comment leur attribuer une place, ni comment les virer.

Quelques idées d’améliorations

  • prise en compte du theme de l’utilisateur (noir/blanc et couleur primaire/secondaire)
  • chercher les bouteilles par nom etc
  • ajouter les accords avec les repas
  • alerte quand on arrive dans la fin de la période à boire
  • Coté carte, je verrai bien un truc plus modulaire, perso j’ai des casiers de taille/position différents, des niches, des blocs de mousse etc… Pouvoir faire un patchwork pour identifier la bonne place sans tro p chercher, je suis preneur

Hello @Redsklns

J’ai ‹ claudé › 2 ou 3 trucs : GitHub - Pulpyyyy/ha-millesime: Suivi de la cave à vin · GitHub


📦 Gestion des emplacements

Quantité → N emplacements physiques

Ajouter un vin avec qté = 3 crée désormais 3 entrées séparées sur 3 slots libres consécutifs, au lieu d’un seul enregistrement avec quantity: 3. Chaque bouteille occupe son propre emplacement physique dans le casier.

Auto-détection du premier slot libre

Le bouton + Vin de l’en-tête pré-sélectionne automatiquement le premier emplacement disponible — plus de bouteilles qui s’empilent toutes sur le slot 0.

Slot picker visuel

Le champ numérique est remplacé par une mini-grille cliquable représentant l’étage réel. Les slots occupés affichent la couleur du vin, les libres sont cliquables directement.

Étage modifiable à l’édition

Le sélecteur d’étage est maintenant accessible y compris lors de la modification d’une bouteille existante, et pas uniquement à l’ajout.

Validation des collisions

Vérification côté frontend (avertissement immédiat) et côté backend (HomeAssistantError) pour add_bottle, update_bottle et duplicate_bottle.

↕️ Déplacement et échange de bouteilles

Comment déplacer une bouteille :

  1. Cliquez sur une bouteille pour ouvrir sa fiche

  2. Cliquez :up_down_arrow: Déplacer

  3. Un bandeau apparaît en haut de la cave

  4. Cliquez sur l’emplacement cible

  • Slot vide → la bouteille est déplacée

  • Slot occupé → les deux bouteilles s’échangent automatiquement

  • Fermer un modal ou cliquer Annuler quitte le mode déplacement

🍷 Fiche détail enrichie

Nouvelles informations affichées :

| Champ | Description |

|—|—|

| :round_pushpin: Emplacement | Nom de l’étage + numéro de slot |

| :one_o_clock: Fenêtre de dégustation | Badge :white_check_mark: À boire / :hourglass_not_done: Trop tôt (avec compte à rebours) / :red_circle: Passé l’apogée |

| :fork_and_knife_with_plate: Accords mets-vins | Affichés en chips individuels |

| Appellation / Région / Pays | Séparés dans la grille |

Le millésime est maintenant visible directement dans le titre du header de la fiche.

🎨 Thème Home Assistant (clair / sombre)

La carte s’adapte automatiquement au thème HA configuré. Les variables CSS de HA (--card-background-color, --primary-text-color, --secondary-background-color, --divider-color…) sont injectées dans le shadow DOM et dans les modals.

Le graphique d’historique de valeur adapte également ses couleurs (fond, axes, courbe) au thème actif, y compris lors d’un changement de thème en temps réel.

⚙️ Backend / développeurs
  • update_bottle accepte maintenant floor_id et slot pour les déplacements

  • Nouvelle fonction interne _slot_taken() mutualisée

  • services.yaml mis à jour en conséquence

🛠️ Configuration YAML de la carte

La carte ne requiert aucun paramètre obligatoire. Options disponibles :


type: custom:millesime-card

bottle_style: bottle # "bottle" (défaut) | "dot"

bottle_label: none # "none" (défaut) | "vintage" | "name" | "name_vintage" | "vintage_name"


bottle_style — forme des emplacements dans le casier

| Valeur | Rendu |

|—|—|

| bottle | Silhouette de bouteille SVG colorée (défaut) |

| dot | Cercle coloré compact |


bottle_label — texte affiché sous chaque bouteille

| Valeur | Affichage |

|—|—|

| none | Aucun label (défaut) |

| vintage | Millésime seul (ex. 2019) |

| name | Nom court, tronqué à 15 caractères |

| name_vintage | Nom sur la 1ʳᵉ ligne, millésime sur la 2ᵉ |

| vintage_name | Millésime sur la 1ʳᵉ ligne, nom sur la 2ᵉ |


Disposition des étagères — configurable par étage depuis l’interface

Les 4 types de disposition sont accessibles via le bouton :gear: de chaque étage :

| Valeur | Nom affiché | Description |

|—|—|—|

| side_by_side | Côte à côte | Grille rectangulaire standard, toutes les bouteilles alignées (défaut) |

| alternating | Tête-bêche | Rangées alternées décalées verticalement — imite les casiers en bois |

| alternating_2d | Tête-bêche alterné | Décalage en échiquier case par case |

| quinconce | Quinconce | Rangées impaires décalées d’une demi-bouteille — disposition optimale en tonneau |

Ces valeurs sont stockées dans les données de la cave (non dans le YAML de la carte) et se modifient depuis l’UI.


Exemple complet :


type: custom:millesime-card

bottle_style: dot

bottle_label: vintage

Si tu es interessé, je peux te faire un PR

Bonjour, je vais regarder pour intégrer toutes les modifications. Je te dis quand tout sera en ligne.

Merci pour tes retours

Salut,

Je vais regarder pour prendre en compte tous les retours et améliorer l’intégration.

Je vous dis quand la v6 sera opérationnelle, car je n’ai pas d’Android et je ne peux pas tester.

Merci pour tes retours

Bonjour,

J'ai intégré tous vos retours et même un peu plus dans les dernières versions :

  • correction android (a tester svp)
  • bouteille qte 1 à l'ajout
  • bouton de recherche pour trouver un vin avec son nom
  • journal de dégustation, pour garder une trace de tous les vins bus
  • ajout d'une vue 3D des bouteilles
  • etc...

J'attends vos retours et idées

Excellente cette vue 3D

Salut,

J'ai regardé un peu les nouvelles fonctions et j'ai 2 / 3 remarques et propositions à faire. Il reste notamment un bug sur le positionnement des bouteilles qui peuvent se superposer

Dans ton cas, l'usage est-il bien le suivant : 1 seule cave/casier, usage sur mobile quasi à 100% ?

J'ai poussé le design 3D un peu plus loin, il y a quelques artifacts à corriger encore

J'ai poussé vraiment plus loin le concept 3D je suis fan

vins

Bravo !
J’adore, je vais suivre ce sujet de prêt :blush:

le design de la vue est :100: fois mieux que sur vinotag :joy:

une Request :

pouvoir importer une cave de « vinotag » avec un fichier xlsx ou csv

Ci-dessous, l'export csv :grin:

bottle_quantity,millesime_year,wine_type,wine_country,wine_region,wine_name,wine_domain,bottle_size,wine_apogee_start,wine_apogee_end,last_bottle_added,bottle_real_price,bottle_buying_price,bottle_comment,wine_comment,rating,favorite
1,2021,wine_red,fr,,Narassa,Domaine Lafage,75cl,,Tue Jan 12 2021,Fri Jan 12 2024,,,,,,false
1,2017,wine_white_sweet,fr,sud_ouest,Monbazillac,Marquis de Chamterac,75cl,,Thu Jan 12 2017,Fri Jan 12 2024,,,,,,false
2,2021,wine_red,fr,provence,Bandol Rouge,Domaine et Château Pey Neuf,75cl,,Wed Jan 27 2021,Sat Jan 27 2024,,,,,,false
1,2021,wine_red,fr,,Vieilles Vignes Chautagne Gamay,Cave de Chautagne,150cl,,Tue Jan 12 2021,Fri Jan 12 2024,,,,"1,5l -cadeau Didier",,false
1,2022,wine_white,fr,,La Grande Pièce Pouilly-Fumé,Jean Dumont,75cl,,Thu Jan 20 2022,Sat Jan 20 2024,,,,,,false
1,2019,wine_red,fr,vallee_du_rhone,Croix de Chabot Saint-Joseph,Y/M - Yannick Alléno & Michel Chapoutier,75cl,,Sat Jan 12 2019,Fri Jan 12 2024,,,,,,false
5,2021,wine_red,fr,,Reméage Syrah,Les Vins de Vienne - Cuilleron-Gaillard-Villard,75cl,,Tue Jan 12 2021,Fri Jan 12 2024,,,,,,false
3,2021,wine_red,fr,provence,Moulin des Costes Charriage Bandol,Domaines Bunan,75cl,Fri Mar 03 2023,Mon Mar 03 2031,Sun Mar 03 2024,,,,,,false
2,2022,wine_rose,fr,provence,Château La Rouvière Rosé,Domaines Bunan,75cl,,Thu Mar 03 2022,Sun Mar 03 2024,,,,,,false
1,2017,wine_red,fr,,Saint-Émilion Grand Cru,Château Godeau,75cl,,Thu Jan 12 2017,Fri Jan 12 2024,,,,,,false

ça doit pouvoir se faire pour l'import

J'ai ajouté des noms sur les étagères

Par contre la capsule du champagne est pas tiptop, il faut corriger la couleur du rouge

import ok, on perds juste une info sur les prix (achat/revente)

mais on a gagné les formats de bouteilles 50/75/150

Millésime fork v5.5.0 — ce qu'il fait en plus du fork d'origine (Redsklns v5.4.0)

:file_cabinet: Structure de données

  • Modèle wines[] + slots[] : 1 vin = N emplacements physiques individuels, migration automatique — l'upstream reste en bottles[] + quantity (1 fiche = 1 quantité)
  • Hiérarchie racks[] / shelves (cave → casiers → étagères → emplacements), migration auto, alias floor_id/rows toujours acceptés
  • Champs par bouteille : format (size : 75 cl, 150 cl…) et commentaire, surchargeables indépendamment du vin
  • Champs par vin : coup de cœur :star: (favorite), format par défaut, date d'ajout surchargeable
  • Journal de dégustation enrichi : format, commentaire de la bouteille bue et favori archivés

:wine_glass: Fonctions utilisateur

  • Slot picker visuel (mini-grille cliquable) + multi-sélection (qté 3 = 3 emplacements) — au lieu d'un champ numérique
  • Mode déplacement 2D : clic vide = déplace, clic occupé = échange
  • Drag & drop 3D avec permutation, dépose optimiste, aucun état intermédiaire visible
  • 6 profils de bouteilles réalistes partagés 2D/3D (bordelaise, bordelaise col allongé, bourguignonne, champenoise, flûte, ligérienne) — l'upstream a une silhouette unique
  • Verre teinté + robe visible par type, muselet et plaque blasonnée sur l'effervescent
  • Rendu à l'échelle des formats : magnums et demis changent de taille sans casser la grille
  • Identité visuelle par casier : 5 essences de bois texturées, liserés d'accent, cadres dont fer forgé
  • Plaque nominative par étagère ; emplacements vides en silhouette de bouteille orientée
  • Import Vinotag :inbox_tray: : CSV, automatique au démarrage, auto-placement
  • Rafraîchissement global :recycling_symbol: : fusion des doublons + complétion Gemini des champs vides (jamais d'écrasement)
  • Adaptation au thème HA clair/sombre — l'upstream est en sombre fixe
  • Libellé d'emplacement humain 1-based « casier · ét. X · n°Y » partout (fiche, recherche, infobulles, erreurs)

:gear: Actions (services)

L'upstream expose 11 services ; le fork en ajoute 9 :
add_wine · update_wine · remove_wine · add_slot · update_slot · move_slot · remove_slot · import_vinotag · refresh_wines

Les anciens add_floor / update_floor / remove_floor restent en alias dépréciés : les automatisations existantes continuent de fonctionner.

:bug: Bugs et failles corrigés

  • Faille XSS : l'upstream injecte les données brutes dans innerHTML (ex. value="${b.tasting_notes}") → esc() systématique + safeUrl() sur les liens
  • Capsule 3D côté culot de la bouteille (bug upstream) → capsule côté bouchon, habillage complet
  • Aucune validation de collision d'emplacement → validation frontend (avertissement) et backend (HomeAssistantError)
  • window.confirm natif → modale de confirmation intégrée au thème
  • Carte non rafraîchie si un événement arrive modale ouverte → rendu différé + refetch immédiat après chaque action
  • Numérotation 0-based visible de l'utilisateur → 1-based partout (libellés, toasts, erreurs)
  • disconnectedCallback dupliqué → supprimé

:inbox_tray: Import Vinotag — comment ça marche

Principe : exportez votre cave depuis Vinotag en CSV, déposez le fichier
millesime_import_vinotag.csv dans le dossier de configuration de Home Assistant
(/homeassistant/), et l'import se fait automatiquement au démarrage de l'intégration.
Déclenchable aussi à chaud via le service import_vinotag ou le bouton :inbox_tray: de la carte
(avec confirmation).

Ce qui est repris du CSV :

  • Type de vin : wine_red → rouge, etc. (rouge, blanc, rosé, effervescent, liquoreux)
  • Pays et régions : codes et slugs convertis en libellés français accentués
  • Fenêtre de dégustation : seules les années sont extraites des dates d'apogée
  • Prix : la valeur actuelle est retenue (repli sur le prix d'achat si absente)
  • Note /5, date d'ajout convertie, format par défaut 75 cl
  • Quantité : N exemplaires = N emplacements physiques distincts

Placement automatique : les bouteilles remplissent les premiers emplacements libres
des casiers existants ; si la capacité manque, un casier « Import » est créé à la volée.

Sécurité : le fichier n'est effacé qu'après un import réussi — en cas d'erreur il
reste en place et un avertissement apparaît dans les logs. Le nommage
millesime_import_<source>.csv est prêt pour d'autres formats d'import à venir.

wouah… le taf !! :clap::clap:

je vais tester et merci pour l’import vinotag :wink:

j’ai même pas encore testé que j’ai déjà une question voire une request :innocent:

est ce que tu as prévu pour les caves à vin multi zone ? c’est mon cas :wink:

  • 2 clayettes froid (blanc champagne) et
  • 4 clayettes tempérées ( rouge )

idéalement il faudrait quil favorise le rangement les blancs et les champagnes dans les clayettes froid et le reste en « tempéré »