Voici mon code python qui donne la température en remonté d’info et je travaille sur la récupération de l’état de la lampe
"""
Indygo Light Controller – GUI simplifiée sans login à l'écran
--------------------------------------------------------------
• Connexion automatique avec identifiants intégrés
• Affichage température piscine et lumière (scraping)
• Actualisation automatique toutes les 60 secondes
Dépendances : requests, beautifulsoup4, customtkinter
"""
import threading, requests, re, time, customtkinter as ctk
from bs4 import BeautifulSoup
# ──────────────────────────────────────────────────────────────
# 1) Contrôleur HTTP Indygo
# ──────────────────────────────────────────────────────────────
class IndygoController:
BASE_URL = "https://myindygo.com"
LOGIN_URL = f"{BASE_URL}/login"
POOL_URL = f"{BASE_URL}/pools/VOTRE ID MYINDYGO"
# ⚠️ ID à adapter si besoin : ici on teste "Station 1"
LIGHT_ID = "l'id de la light"
def __init__(self):
# ⚠️ Identifiants à remplacer si besoin
self.email = "votre login"
self.pwd = "votre mot de passe"
self.session = None
self.csrf = None
self.logged = False
def _new_session(self):
self.session = requests.Session()
self.session.headers.update({
"User-Agent": "Mozilla/5.0",
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "fr-FR,fr;q=0.9"
})
def _extract_tokens(self, html: str):
soup = BeautifulSoup(html, "html.parser")
meta = soup.find("meta", attrs={"name": re.compile("csrf|_token", re.I)})
if meta:
self.csrf = meta.get("content")
def login(self) -> bool:
self._new_session()
try:
r = self.session.get(self.LOGIN_URL, timeout=10)
r.raise_for_status()
self._extract_tokens(r.text)
data = {"email": self.email, "password": self.pwd, "_token": self.csrf}
r2 = self.session.post(self.LOGIN_URL, data=data, timeout=10, allow_redirects=True)
self.logged = (r2.url != self.LOGIN_URL)
except Exception as e:
print("Erreur login:", e)
self.logged = False
return self.logged
def fetch_temperature(self) -> str | None:
if not self.logged:
return None
try:
html = self.session.get(self.POOL_URL, timeout=10).text
soup = BeautifulSoup(html, "html.parser")
t = soup.find("div", class_="water_temperature_value")
if t and t.span:
return t.span.text.strip()
except Exception as e:
print("Erreur température:", e)
return None
def fetch_light_status(self) -> str | None:
if not self.logged:
return None
try:
html = self.session.get(self.POOL_URL, timeout=10).text
soup = BeautifulSoup(html, "html.parser")
# Identifier la section "Éclairage"
light_section = soup.find("div", class_="title", string=re.compile("Éclairage", re.I))
if not light_section:
return "NON TROUVÉ"
parent_div = light_section.find_parent("div", class_=re.compile("smallbox"))
if not parent_div:
return "NON TROUVÉ"
# Chercher l’input radio actif
input_active = parent_div.find("input", class_=re.compile("active"))
if input_active:
value = input_active.get("value", "INCONNU")
return value.upper()
else:
return "NON TROUVÉ"
except Exception as e:
print(f"⚠️ Erreur fetch_light_status : {e}")
return None
# ──────────────────────────────────────────────────────────────
# 2) Interface CustomTkinter simplifiée
# ──────────────────────────────────────────────────────────────
class IndygoApp(ctk.CTk):
def __init__(self):
super().__init__()
ctk.set_appearance_mode("light")
self.title("Indygo – Température Piscine")
self.geometry("400x220")
self.resizable(False, False)
self.ctrl = IndygoController()
self.temp_lbl = ctk.CTkLabel(self, text="Température : -- °C", font=("Segoe UI", 24, "bold"))
self.temp_lbl.pack(pady=30)
self.light_lbl = ctk.CTkLabel(self, text="Lumière : --", font=("Segoe UI", 18))
self.light_lbl.pack(pady=10)
self.status_lbl = ctk.CTkLabel(self, text="Connexion en cours…")
self.status_lbl.pack(pady=10)
self.after_id = None
threading.Thread(target=self._init_task, daemon=True).start()
def _init_task(self):
if self.ctrl.login():
self.status_lbl.configure(text="✅ Connecté")
self._refresh_loop()
else:
self.status_lbl.configure(text="❌ Connexion échouée")
def _refresh_loop(self):
threading.Thread(target=self._refresh_task, daemon=True).start()
def _refresh_task(self):
temp = self.ctrl.fetch_temperature()
light = self.ctrl.fetch_light_status()
self.temp_lbl.configure(text=f"Température : {temp} °C" if temp else "Température : Erreur")
self.light_lbl.configure(text=f"Lumière : {light}" if light else "Lumière : Erreur")
self.after_id = self.after(60000, self._refresh_loop)
def on_closing(self):
if self.after_id:
self.after_cancel(self.after_id)
self.destroy()
# ──────────────────────────────────────────────────────────────
# 3) Lancement
# ──────────────────────────────────────────────────────────────
if __name__ == "__main__":
print("Lancement OK")
app = IndygoApp()
app.protocol("WM_DELETE_WINDOW", app.on_closing)
app.mainloop()