#!./venv/bin/python3 import pandas as pd import numpy as np import json import matplotlib.pyplot as plt import os from datetime import timedelta ## Read the measurements data file ## DATA_MEAS_DIR = 'data/measurements' # Always plot latest datafile - replace [-1] with another index if you want to plot a specific file. MEAS_LOG_FILE = sorted(os.listdir(DATA_MEAS_DIR))[-1] # Store each dictionary of the measurements json in a list with open(os.path.join(DATA_MEAS_DIR, MEAS_LOG_FILE)) as f: meas_data = [json.loads(line) for line in f] # Use setpoint logger (only necessary for part two of the exercise "collecting fresh data") use_setpoint_log = False ## Read the setpoints data file ## if use_setpoint_log: DATA_SP_DIR = 'data/setpoints' # Always plot latest datafile SP_LOG_FILE = sorted(os.listdir(DATA_SP_DIR))[-1] # Store each dictionary of the setpoints json in a list with open(os.path.join(DATA_SP_DIR, SP_LOG_FILE)) as f: sp_data = [json.loads(line) for line in f] # Merge measurements and setpoints in one list data = meas_data + sp_data else: data = meas_data ################################################################################ ################## Part 2 ###################################################### ################################################################################ def overshoot(df, T1, T2): yT1, yT2 = df[T1], df[T2] over = 1 / (yT1 - yT2) * np.max(yT2 - df) return over SETPOINT_UNIX = 1718013959.6977577 SETPOINT_TS = pd.to_datetime(SETPOINT_UNIX, unit='s') WINDOW = pd.to_datetime(SETPOINT_UNIX+25, unit='s') ## The controller is reasonably fast at reacting to changes; the sum of in and ## out is at zero roughly 5-10 seconds after a change. # Construct a dataframe and pivot it to obtain a dataframe with a column per unit, and a row per timestamp. df = pd.DataFrame.from_records(data) df['time'] = pd.to_datetime(df['time'], unit='s') df_pivot = df.pivot_table(values='value', columns='unit', index='time') df_resampled = df_pivot.resample('0.1s').mean() df_resampled.interpolate(method='linear', inplace=True) df_resampled = pd.DataFrame(df_resampled) # Plot the data. Note, that the data will mostly not be plotted with lines. plt.ion() # Turn interactive mode on plt.figure() ax1, ax2 = plt.subplot(211), plt.subplot(212) df_resampled[[c for c in df_resampled.columns if '_p' in c]].plot(marker='.', ax=ax1, linewidth=3) ax2.plot(df_resampled['pcc_p'][SETPOINT_TS:WINDOW], marker='.', linewidth=3, label='pcc_p') ax2.plot(df_resampled['dumpload_p'][SETPOINT_TS:WINDOW], marker='.', linewidth=3, label='dumpload') plt.legend() # print(overshoot(df_resampled['pcc_p'][SETPOINT_TS:WINDOW], SETPOINT_TS, WINDOW)) plt.show(block=True)