Hello.
Ma femme s’est mis en tête de jouer au loto.



Je me suis dis cool, mais vérifier au bon moment quels numéros sont sorties etc… dur dans le temps.
Du coup en bon geek, je me suis demandé comment intégrer ça à home assistant; dommage aucune intégration.
Heureusement, je suis à fond dans le scrape en ce moment pour apprendre comment ça fonctionne; comme disent les américains : « Et voila! » solution toute trouvée…
Le scrape est très intéressant pour récupérer des infos depuis le net. Mais malheureusement il faut quelques connaissances, et surtout il n’existe pas trop d’info propre à HA…
Ici, je vais donc vous faire une petite lecture du dimanche pour documenter, apporter quelques idées sur le scrape, l’automatisation, et l’interface. J’espère que ca pourra aussi créer quelques réponses pertinentes pour inventer d’autre petit tricks, notamment pour de la prédiction, ou alors la détermination et la récupération des lots hors gros lots (4 boules gagnantes etc)…
1. Scrape
- On commence par les résultats du loto :
Le loto c’est 5 boules aléatoires de 1 à 49 et 1 boule chance de 1 à 10.
Tirage le lundi, mercredi, et samedi à 20h20.
Il faut donc miser avant 20h15.
Le résultat se met à jour sur : Résultat LOTO® : Tirage | FDJ®
L’idée c’est donc de récupérer le résultat, quand c’est nécessaire. Je vais pas jouer tous les tirages non plus… (quoique). De le comparer à une grille unique pour le moment (je considère que j’ai plus de chance en jouant tout le temps les mêmes numéros). Et d’avoir une alerte.
- On continue avec l’intégration:
Pour récupérer le résultat, je regarde un peu la page que je vous ai fourni au dessus. En cliquant droit avec mon navigateur, je peux inspecter le code.

Je me rend compte qu’il y a une section de 5 lignes :

Ce qu’il faut ici c’est récupérer le chiffre de chaque ligne pour chaque boule. Avec l’inspecteur c’est assez simple, on clique droit pour chaque chiffre, puis on fait copier le selector (Vous pouvez aussi faire le selector vous même).
Ce selector permet de cibler le code HTML et servira pour créer chaque capteur par boule.
Ce que fait l’intégration Scrape, c’est se connecter à une page « ressource » puis lire le code HTML et remonter une info que l’on cible avec les selecteur.
Ok donc vous connaissez la manip. On recherche l’intégration scrape via l’UI, puis on l’ajoute.
En ressource, on colle l’url du résultat de la FDJ. Cela nous permettra d’aller cibler des infos (le resultat de chaque boule) et le remonter dans un sensor.
https://www.fdj.fr/jeux-de-tirage/loto/resultats
Méthode GET, pas besoin de payload, authentification ou autre. Une fois que vous aurez fait suivant, vous pourrez créer les capteurs. Dans mon cas, je crée un capteur par boule, en copiant chaque selector directement pour éviter les complications.
J’ajoute donc un capteur, avec un nom genre « boule 1 » et en selector (‹ sélectionner* ›) je colle le selector copié via l’inspecteur sur la première boule via le site :
#loto-results > div > section.result-full__tab-item.is-selected > div.result-full__drawing-content > div.result-full__drawing-infos > ul:nth-child(2) > li:nth-child(1) > span
Le secret de la compréhension du scrape se trouve ici. Je ne peux que vous conseiller de vous documenter sur les sélecteur html via internet.
Le premier # permet de cibler un « ID » unique dans le code HTML. Un chevrons indique que l’on va rechercher une balise directement en dessous du sélecteur précédent. Puis ensuite, on indique les type de balise (div, section, ul…). On cible un peut plus avec le point qui permet d’indiquer une classe.
Pour pouvoir descendre jusqu’à la boule 1 j’ai simplifié en ce sens chez moi :
#loto-results ul.result-full__list li.result-full__list-item:nth-child(1) > span.game-ball
- L’ID unique loto-results est en tête,
- puis je recherche dans sa descendance une « ul » (liste non ordonnée) que je précise être celle qui à une classe « result-full__list ».
- Ensuite, comme il y a plusieurs ligne dans ma liste, je m’assure que celle ciblé sera la première ligne avec la classe « result-full__list-item ». Premier enfant « :nth-child(1) » de mon selecteur précédent.
- Enfin, je regarde dans son descendant direct la balise « span » où est le résultat de ma boule avec la classe « game-ball »

Je vous laisse évidemment bosser sur les autres. J’ai créer pour ma part les 5 premières boules, la boule chance, et un autre capteur pour récupérer la date de tirage :
#loto-results div.fdj.Heading > h1.fdj.Title
Je me retrouve donc avec 7 entités (5 boules, 1 chances, 1 tirage)
2. L’automatisation
Comme je ne vais pas jouer à tous les coups, je crée un input booléen que j’activerai seulement lorsque ma grille sera en jeu.
Mon automatisation devra donc vérifier à chaque changement de mon capteur « Tirage » (celui qui me donne la date du dernier résultat) et à condition que mon capteur booléen soit activé, que le résultat correspond à ma grille pour recevoir une notification critique, ou bien que juste m’envoyer une notification normal pour que je puisse vérifier si j’ai pas une ou deux boules de bonne.
Je vous colle le code brut :
Résumé
alias: "Loto"
description: ""
trigger:
- platform: state
entity_id:
- sensor.tirage
condition:
- condition: state
entity_id: input_boolean.grille
state: "on"
action:
- if:
- condition: template
value_template: >-
{{((states('sensor.boule_1') + ' - ' + states('sensor.boule_2') + '
- ' + states('sensor.boule_3') + ' - ' + states('sensor.boule_4')
+ ' - ' + states('sensor.boule_5') + ' * ' +
states('sensor.chance'))==('6 - 11 - 18 - 28 - 41 * 10'))}}
then:
- service: notify.mobile_app_tous
data:
message: >-
Vérifier {{states('sensor.tirage')}}
{{(states('sensor.boule_1') + ' - ' + states('sensor.boule_2') + ' -
' + states('sensor.boule_3') + ' - ' + states('sensor.boule_4') + '
- ' + states('sensor.boule_5') + ' * ' + states('sensor.chance'))}}
title: Loto
data:
push:
sound:
name: default
critical: 1
volume: 1
else:
- service: notify.mobile_app_tous
data:
message: >-
Vérifier {{states('sensor.tirage')}}
{{(states('sensor.boule_1') + ' - ' + states('sensor.boule_2') + ' -
' + states('sensor.boule_3') + ' - ' + states('sensor.boule_4') + '
- ' + states('sensor.boule_5') + ' * ' + states('sensor.chance'))}}
- service: input_boolean.toggle
target:
entity_id: input_boolean.grille
data: {}
mode: single
Pour l’explication :
- Le trigger est simplement le changement d’état du sensor « Tirage ».
- La condition, l’état actif du booléen « grille ».
Puis ensuite, j’ai fais un pré formatage pour que le tirage ressorte moins brute dans mes notifications. Au lieu de « 61118284110 » qui correspond à toutes mes boules alignées, j’afficherai « 6 - 11 - 18 - 28 - 41 * 10 » - J’ai donc un choix via un template. Si le résultat du template :
((states('sensor.boule_1') + ' - ' + states('sensor.boule_2') + ' - ' + states('sensor.boule_3') + ' - ' + states('sensor.boule_4') + ' - ' + states('sensor.boule_5') + ' * ' + states('sensor.chance'))
Correspond au retour de ma grille, alors j’enverrai une notification critique. Sinon une notification simple afin que je vérifie si je n’ai pas quelques boules ok.
Ensuite je désactive mon booléen.
2. L’interface
Pour l’interface, je n’ai pas eu de grosse idée. J’ai simplement fait un petit affichage qui mériterait surement d’être amélioré. Par exemple avec des couleurs si les numéros sont correspondants :

C’est là que je compte sur vous. Si vous avez des idées pour améliorer tout ça je suis preneur. Et j’espère que ceux qui cherche des infos sur le scrape trouverons ici une premier piste. Le scrape peut vraiment être utile quand on veut des mise à jour directement sur notre serveur (comme par exemple, récupérer le prix de l’électricité pour être constamment au bon prix).
Si vous êtes arrivé jusqu’ici, merci. Et comme l’aurait dit Valéry Giscard d’Estaing :
