"""
Programme python sur une pi pico RP2040 (pas besoin d'expliqué comment faire fonctionné le python dessus) pour validé une carte electronique qu'on apellera ordinateurAqua qui: 
	a une fonction enregistre qui envoie grace a l'uart de l'USB vers un PC. et grace a un formalisme tous les evenement qui se passe sur l'ordinateurAqua
	1er type d'evenement des commandes uart (echange sur OrdinateurAqua entre 2 microcontroleur). le pico devra donc grace au deuxieme uart "espionné" cest commande et les envoyer sur le PC
	2ieme type d'evenement 8 pin GPIO en sortie de OrdinateurAqua donc en entrée sur la pico, a chaque changmeent d'etat d'une de c'est pin il faudra envoyer sur le PC (Out1~Out8)
	3ieme type d'evenement 2 pwm qui sorte de l'ordinateurAqua, la pico devra enregistrer toute les 30 min la frequence de ces PWM.
	4ieme type d'evenmennt il faudra enregistrer 6 autres GPIO ,qui sont en entree sur l'ordinateurAqua mais qui seront aussi en entrée sur le pico (espionnage) (In1~In6)
	5ieme type d'evenement Génération d'un signal a 1 pendant une durée de 10 a 30 sec sur un autres GPIO du pico. cette evemenent doit avoir lieux 4 fois par jours mais de maniere aléatoire dans la journée 
	"""
	
from machine import Pin, UART, PWM
import time
import random
import utime

# Configuration UART
uart0 = UART(0, baudrate=9600)
uart1 = UART(1, baudrate=9600)

# Configuration GPIO pour espionner les commandes UART
gpio_out_pins = [Pin(i, Pin.IN) for i in range(2, 10)]  # Out1 ~ Out8
gpio_in_pins = [Pin(i, Pin.IN) for i in range(10, 16)]  # In1 ~ In6
pwm_pins = [PWM(Pin(16)), PWM(Pin(17))]  # PWM pins
signal_pin = Pin(18, Pin.OUT)  # Pin for signal generation

last_states_out = [pin.value() for pin in gpio_out_pins]
last_states_in = [pin.value() for pin in gpio_in_pins]
last_pwm_freqs = [pwm.freq() for pwm in pwm_pins]

def send_event(event_type, details):
    message = f"{event_type}: {details}\n"
    uart0.write(message)

def check_uart():
    if uart1.any():
        command = uart1.read()
        send_event("UART Command", command)

def check_gpio_changes():
    global last_states_out, last_states_in
    for i, pin in enumerate(gpio_out_pins):
        state = pin.value()
        if state != last_states_out[i]:
            send_event(f"Out{i+1}", state)
            last_states_out[i] = state
    for i, pin in enumerate(gpio_in_pins):
        state = pin.value()
        if state != last_states_in[i]:
            send_event(f"In{i+1}", state)
            last_states_in[i] = state

def log_pwm_freqs():
    global last_pwm_freqs
    for i, pwm in enumerate(pwm_pins):
        freq = pwm.freq()
        if freq != last_pwm_freqs[i]:
            send_event(f"PWM{i+1} Frequency", freq)
            last_pwm_freqs[i] = freq

def generate_signal():
    duration = random.randint(10, 30)
    signal_pin.value(1)
    time.sleep(duration)
    signal_pin.value(0)
    send_event("Signal Generation", f"Duration: {duration} seconds")

def random_signal_schedule():
    for _ in range(4):
        delay = random.randint(0, 21600)  # Random delay up to 6 hours
        utime.sleep(delay)
        generate_signal()

# Main loop
last_pwm_log_time = time.time()
while True:
    check_uart()
    check_gpio_changes()
    
    current_time = time.time()
    if current_time - last_pwm_log_time >= 1800:  # Every 30 minutes
        log_pwm_freqs()
        last_pwm_log_time = current_time

    if random.random() < 0.00011574:  # Approximately once every 6 hours (4 times per day)
        generate_signal()
    
    time.sleep(0.1)
