# pip install pyserial matplotlib pandas

import serial
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.widgets import Button
from datetime import datetime

max_points = 20  # Number of points to display on the graph
data = {
    'Timestamp': [],
    **{f'Temp{i+1}': [] for i in range(16)},
    **{f'Hum{i+1}': [] for i in range(16)}
}

# Initialize plots
plt.ion()
fig, (ax_temp, ax_hum) = plt.subplots(2, 1, figsize=(15, 10))

# Set plot titles and labels
ax_temp.set_title('Temperature')
ax_temp.set_xlabel('Time')
ax_temp.set_ylabel('Temperature (°C)')

ax_hum.set_title('Humidity')
ax_hum.set_xlabel('Time')
ax_hum.set_ylabel('Humidity (%)')

# Global flag to control the data collection
collecting_data = False
exit_flag = False

# Button callback functions
def start_button_callback(event):
    global collecting_data
    collecting_data = True

def exit_button_callback(event):
    global exit_flag
    exit_flag = True

# Create the buttons
ax_start_button = plt.axes([0.7, 0.05, 0.1, 0.075])
ax_exit_button = plt.axes([0.81, 0.05, 0.1, 0.075])

start_button = Button(ax_start_button, 'Start')
start_button.on_clicked(start_button_callback)

exit_button = Button(ax_exit_button, 'Exit')
exit_button.on_clicked(exit_button_callback)

# Display the plot window
plt.show(block=False)

# Wait here until 'Start' button is pressed
while not collecting_data:
    plt.pause(0.1)  # Use a short pause to handle UI events
    if exit_flag:
        plt.close(fig)
        raise SystemExit

# Main loop
try:
    # Set up the serial connection (adjust the COM port as needed)
    ser = serial.Serial('/dev/cu.usbmodem14101', 9600, timeout=1)
    while not exit_flag:
        line = ser.readline().decode('utf-8').strip()
        if line:
            try:
                # Split the line into groups and then into temperature and humidity values
                groups = line.split(';')
                if len(groups) == 16:
                    timestamp = datetime.now().strftime('%H:%M:%S')
                    data['Timestamp'].append(timestamp)
                    temps = []
                    hums = []
                    for i, group in enumerate(groups):
                        temp, hum = map(float, group.split(','))
                        temps.append(temp)
                        hums.append(hum)
                        data[f'Temp{i+1}'].append(temp)
                        data[f'Hum{i+1}'].append(hum)

                    # Update temperature graph with latest 20 points
                    ax_temp.clear()
                    ax_temp.set_title('Temperature')
                    ax_temp.set_xlabel('Time')
                    ax_temp.set_ylabel('Temperature (°C)')
                    for i in range(16):
                        ax_temp.plot(data['Timestamp'][-max_points:], data[f'Temp{i+1}'][-max_points:], label=f'Temp{i+1}')
                    
                    # Update humidity graph with latest 20 points
                    ax_hum.clear()
                    ax_hum.set_title('Humidity')
                    ax_hum.set_xlabel('Time')
                    ax_hum.set_ylabel('Humidity (%)')
                    for i in range(16):
                        ax_hum.plot(data['Timestamp'][-max_points:], data[f'Hum{i+1}'][-max_points:], label=f'Hum{i+1}')

                    plt.pause(0.5)
            except ValueError as e:
                print(f"Could not convert data to float: {line}, error: {e}")
except KeyboardInterrupt:
    plt.ioff()
finally:
    # Save the data to a CSV file
    df = pd.DataFrame(data)
    csv_filename = 'arduino_data.csv'
    df.to_csv(csv_filename, index=False)
    print(f"Data saved to '{csv_filename}'")
    ser.close()