From e2a893a03894ae876d3730cc813a84e6b3352480 Mon Sep 17 00:00:00 2001 From: Raymond Bourges Date: Tue, 30 Dec 2025 15:42:38 +0100 Subject: [PATCH] FEAT : Classe Relais et Cloud --- main.py | 200 +++++++++++++++++++++++++------------------------------- 1 file changed, 89 insertions(+), 111 deletions(-) diff --git a/main.py b/main.py index c9b8088..db6a3a9 100644 --- a/main.py +++ b/main.py @@ -8,9 +8,12 @@ import urequests import localtime_fr # TODO : Lire info HP.. HC.. sur HA > sensor.compteur_linky_ptec import webrepl +Broche = [0, 1, 2, 21, 22, 23, 16, 17, 19, 20, 18] + class Bouton: - - def __init__(self, nom, pin, todo = None, pin_led = None): + DEBOUNCE_MS = 500 + + def __init__(self, nom, pin, todo = None, pin_led = None, led_on = False): self.dernier_appui = 0 self.nom = nom self.pin = Pin(pin, Pin.IN, Pin.PULL_UP) @@ -21,6 +24,7 @@ class Bouton: else: self.avec_led = True self.pin_led = Pin(pin_led, Pin.OUT) + self.led_on() if led_on else self.led_off() def led_on(self): if self.avec_led: @@ -32,35 +36,88 @@ class Bouton: def bouton_presse(self, pin): self.maintenant = time.ticks_ms() - if time.ticks_diff(self.maintenant, self.dernier_appui) > DEBOUNCE_MS: + if time.ticks_diff(self.maintenant, self.dernier_appui) > self.DEBOUNCE_MS: self.dernier_appui = self.maintenant print("Bouton " + self.nom + " pressé !") if self.todo is not None: self.todo() +class Relais: + i2c = I2C(scl=Pin(Broche[5]), sda=Pin(Broche[4]), freq=20000) + I2C_ADDR = 0x11 + + def __init__(self) -> None: + self.solaire() + + def off(self): + self.i2c.writeto_mem(self.I2C_ADDR, 0x10, bytes([0b0000])) + + def solaire(self): + self.i2c.writeto_mem(self.I2C_ADDR, 0x10, bytes([0b0011])) + + def reseau(self): + self.i2c.writeto_mem(self.I2C_ADDR, 0x10, bytes([0b1100])) + +class Cloud: + token_ha = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkNGY4MDdmYWYzNDQ0NTc0ODY4MmFmNzA4NDdmMTE0MyIsImlhdCI6MTc2NDQ1Mzk0NSwiZXhwIjoyMDc5ODEzOTQ1fQ.DJgSqeTKPHWbKEFH3HuFih4QKt3CSqLqot34_vhCOQU" + headers = {"Authorization": f"Bearer {token_ha}", "Content-Type": "application/json"} + wifi = network.WLAN(network.STA_IF) + wifi.active(True) + wifi.connect("Livebox-BDC6", "KFQSn7PDCMSgPpM2Ws") + + def zoe(self) -> int: + try: + response = urequests.get("https://ha-demo.arbi.fr/api/states/sensor.zoe_batterie", headers=self.headers) + data = response.json() + response.close() + return int(data["state"]) + except Exception as e: + print("Erreur :", e) + return -1 + # Capter exception pour éviter les sorties intempestives (comme timeout sur ntp) # Regarder https://docs.micropython.org/en/latest/esp32/quickref.html#timers # led_jaune = Pin(0, Pin.OUT) # D0 # button_jaune = Pin(1, Pin.IN, Pin.PULL_UP) # D1 +relais = Relais() + +cloud = Cloud() + def action_jaune(): bouton_jaune.led_on() - led_bleue.off() - led_rouge.off() - set_relays(0b0011) + bouton_bleu.led_off() + bouton_rouge.led_off() + relais.solaire() -bouton_jaune = Bouton("jaune", 1, action_jaune, 0) +bouton_jaune = Bouton("jaune", Broche[1], action_jaune, Broche[0], True) -led_bleue = Pin(2, Pin.OUT) # D2 -button_bleu = Pin(21, Pin.IN, Pin.PULL_UP) # D3 +def action_bleu(): + bouton_jaune.led_off() + bouton_bleu.led_on() + bouton_rouge.led_off() + relais.reseau() -led_rouge = Pin(20, Pin.OUT) # D9 -button_rouge = Pin(18, Pin.IN, Pin.PULL_UP) # D10 +bouton_bleu = Bouton("bleu", Broche[3], action_bleu, Broche[2]) + +def action_rouge(): + bouton_jaune.led_off() + bouton_bleu.led_off() + bouton_rouge.led_on() + relais.reseau() + +bouton_rouge = Bouton("bleu", Broche[10], action_rouge, Broche[9]) button_moins = Pin(16, Pin.IN, Pin.PULL_UP) # D6 (et masse) button_plus = Pin(17, Pin.IN, Pin.PULL_UP) # D7 (et masse) +bouton_moins = Bouton("moins", Broche[7]) + +bouton_plus = Bouton("plus", Broche[6]) + +#######################################################"" + brightness = 0.01 # 1 % def set_pixel(i, r, g, b): @@ -77,115 +134,36 @@ set_pixel(7, 0, 255, 0) np.write() # np.brightness(50) -i2c = I2C(scl=Pin(23), sda=Pin(22), freq=20000) # D5, D4 -I2C_ADDR = 0x11 - -ntp_ok = False -ntp_ttl = 3600 -ntp_attente = ntp_ttl -rtc = RTC() - pas_temps = 10 -DEBOUNCE_MS = 500 -dernier_appui = 0 -token_ha = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkNGY4MDdmYWYzNDQ0NTc0ODY4MmFmNzA4NDdmMTE0MyIsImlhdCI6MTc2NDQ1Mzk0NSwiZXhwIjoyMDc5ODEzOTQ1fQ.DJgSqeTKPHWbKEFH3HuFih4QKt3CSqLqot34_vhCOQU" -def button_bleu_presse(pin): - global dernier_appui - maintenant = time.ticks_ms() - if time.ticks_diff(maintenant, dernier_appui) > DEBOUNCE_MS: - dernier_appui = maintenant - print("Bouton bleu !") - bouton_jaune.led_off() - led_bleue.on() - led_rouge.off() - set_relays(0b1100) +# def HC(date_heure) -> bool: +# heure, minute = date_heure[4], date_heure[5] +# nb_minutes = heure * 60 + minute +# _21h30 = 21 * 60 + 30 # TODO : Ne pas faire le calcul à chaque appel +# _23h30 = 23 * 60 + 30 +# if (nb_minutes > _21h30 and nb_minutes < _23h30): +# return True +# return False -button_bleu.irq(trigger=Pin.IRQ_FALLING, handler=button_bleu_presse) +# def ntp(): +# global ntp_ok, ntp_ttl, ntp_attente +# if (wifi.isconnected() and (not ntp_ok or ntp_attente < 0)): +# print("WIFI OK, call NTP") +# ntptime.settime() +# ntp_ok = True +# ntp_attente = ntp_ttl +# webrepl.start() +# if (ntp_ok): +# date_heure = localtime_fr.localtime() +# print(f"Date et heure : {date_heure[3]}:{date_heure[4]}:{date_heure[5]} ({ntp_attente}, {HC(date_heure)})") +# ntp_attente = ntp_attente - pas_temps -def button_rouge_presse(pin): - global dernier_appui - maintenant = time.ticks_ms() - if time.ticks_diff(maintenant, dernier_appui) > DEBOUNCE_MS: - dernier_appui = maintenant - print("Bouton rouge pressé !") - bouton_jaune.led_off() - led_bleue.off() - led_rouge.on() - set_relays(0b1100) - -button_rouge.irq(trigger=Pin.IRQ_FALLING, handler=button_rouge_presse) - -def button_moins_presse(pin): - global dernier_appui - maintenant = time.ticks_ms() - if time.ticks_diff(maintenant, dernier_appui) > DEBOUNCE_MS: - dernier_appui = maintenant - print("Bouton moins pressé !") - -button_moins.irq(trigger=Pin.IRQ_FALLING, handler=button_moins_presse) - -def button_plus_presse(pin): - global dernier_appui - maintenant = time.ticks_ms() - if time.ticks_diff(maintenant, dernier_appui) > DEBOUNCE_MS: - dernier_appui = maintenant - print("Bouton plus pressé !") - -button_plus.irq(trigger=Pin.IRQ_FALLING, handler=button_plus_presse) - -def set_relays(mask): - """mask = bits 0..3 (1=ON, 0=OFF)""" - i2c.writeto_mem(I2C_ADDR, 0x10, bytes([mask])) - -def HC(date_heure) -> bool: - heure, minute = date_heure[4], date_heure[5] - nb_minutes = heure * 60 + minute - _21h30 = 21 * 60 + 30 # TODO : Ne pas faire le calcul à chaque appel - _23h30 = 23 * 60 + 30 - if (nb_minutes > _21h30 and nb_minutes < _23h30): - return True - return False - -def ntp(): - global ntp_ok, ntp_ttl, ntp_attente - if (wifi.isconnected() and (not ntp_ok or ntp_attente < 0)): - print("WIFI OK, call NTP") - ntptime.settime() - ntp_ok = True - ntp_attente = ntp_ttl - webrepl.start() - if (ntp_ok): - date_heure = localtime_fr.localtime() - print(f"Date et heure : {date_heure[3]}:{date_heure[4]}:{date_heure[5]} ({ntp_attente}, {HC(date_heure)})") - ntp_attente = ntp_attente - pas_temps - -def charge() -> int: - try: - headers = {"Authorization": f"Bearer {token_ha}", "Content-Type": "application/json"} - response = urequests.get("https://ha-demo.arbi.fr/api/states/sensor.zoe_batterie", headers=headers) - data = response.json() - response.close() - return int(data["state"]) - except Exception as e: - print("Erreur :", e) - return -1 - -# Init -set_relays(0b0000) -bouton_jaune.led_off() -led_bleue.off() -led_rouge.off() -wifi = network.WLAN(network.STA_IF) -wifi.active(True) -wifi.connect("Livebox-BDC6", "KFQSn7PDCMSgPpM2Ws") while True: # now = datetime.now() # print("Date et heure :", now) - ntp() - print(f"Charge : {charge()}") + print(f"Charge : {cloud.zoe()}") time.sleep(pas_temps) # set_pixel(0, 0, 0, 0) # OFF # np.write() \ No newline at end of file