import serial

import matplotlib.pyplot as plt
import numpy as np

from matplotlib.animation import FuncAnimation

width = 10.0  # sec
period = 0.02  # sec
nbPoints = int(width / period)
paramIdx = [2, 3, 4, 8, 19]
paramLabels = ['Temp', 'SpO2', 'HR', 'InstCO2', 'Press']
paramLims = [(35,38), (80,100), (250,650), (0,5), (0,30)]

x = np.linspace(0.0, width, num=nbPoints)
y = np.zeros((nbPoints,))

fig, axs = plt.subplots(len(paramIdx), 1)
fig.tight_layout(pad=0.1)
for ax,lab,lim in zip(axs,paramLabels, paramLims):
    ax.set_ylabel(lab)
    ax.set_ylim(lim)
    ax.xaxis.set_visible(False)
    ax.yaxis.tick_right()
ax.xaxis.set_visible(True)
ls = []

physioSer = serial.Serial('/dev/PhysioSuite', 115200)
somnoSer = serial.Serial('/dev/SomnoSuite', 115200)


def initPlot():
    for ax in axs:
        l, = ax.plot(x, y, 'r-', lw=2)
        ls.append(l)
    return ls


def updatePlot(i):
    arr = readSer()
    arr = arr[paramIdx]
    _, nP = arr.shape
    for l, a, ax in zip(ls, arr, axs):
        y = l.get_ydata()
        # print ax.get_ylabel()
        # print y
        # print a
        # print nP
        y = np.roll(y, -1 * nP)
        y[-1 * nP:] = a
        l.set_ydata(y)
        #ax.set_ylim(y.min(), y.max())
    return ls


def readSer():
    bufferSize = [800, 905]
    nbParams = 21
    a = physioSer.readlines(bufferSize[0])
    b = somnoSer.readlines(bufferSize[1])
    comb = [c + d for c, d in zip(a, b)]  # combine both arrays
    comb = [c.replace('*', 'NaN').split() for c in comb]  # replace + and split into individual values
    comb = [c for c in comb if len(c) == nbParams]  # drop lines with inccorrect number of values
    c = np.array(comb, dtype=np.float64)
    return c.T


anim = FuncAnimation(fig, updatePlot, init_func=initPlot, blit=True)
plt.show()