import time
import serial as s
import serial.tools.list_ports as stl
import pandas as pd
import matplotlib.pyplot as plt


## Pandas data frame
c = ['time','OD_A','OD_B','OD_C','OD_D']
df = pd.DataFrame(columns=c, dtype=float)

## Serial connection
ser = s.Serial()
ser.port = next(stl.grep('COM*')).name  # Try to automatically find the port - replace with eg 'COM15' if it doesn't work
ser.baudrate = 115200
ser.timeout = 0.1

try:
    ser.open()
except:
    print('error, couldn\'t open port')
    exit()

if ser.isOpen():
    print('Serial connection established\n')
    while True:
        if ser.in_waiting:
            # Leave time for all data to be sent:
            time.sleep(0.02)

            # Data looks like
            # "time,OD_A,OD_B,OD_C,OD_D\r\n"
            # Split the string by comma, strip carriage return and newline characters, and turn into floats:
            try:
                data = [[float(s.strip('\r\n')) for s in ser.read(64).decode('utf-8').split(',')]]
                #print(data)

                # Append to dataframe:
                temp = pd.DataFrame(data, columns=c)
                df = pd.concat([df, temp], ignore_index=True)
                #print(df)

                # Plot data
                plt.cla()
                plt.plot(df['time'], df['OD_A'], 'x-')
                plt.plot(df['time'], df['OD_B'], 'x-')
                plt.plot(df['time'], df['OD_C'], 'x-')
                plt.plot(df['time'], df['OD_D'], 'x-')

                plt.xlabel('Time (hrs)')
                plt.ylabel('OD')

                plt.legend(['A','B','C','D'])

            except:
                # Couldn't parse data - probably from some unrelated serial print.
                # Nothing to do in this case, don't worry.
                pass


        plt.pause(1)    # Need this to keep plot interactive while still looking for new data

