Venue 90#
It’s hard to know what insulation venue 90 has. It’s a bit like a big shed clad in corrugated iron. This plots some temperature data against external weather conditions, but the monitor could only connect to the internet intermittently.
Show code cell source
Hide code cell source
# Using plotly.express
plot_height = 800
plot_width = 1000
venue_data_dir = "venue-90"
venue_temp_data_dir = venue_data_dir + "/"
weather_data_dir = "./weather_data/"
temp_filenames = ['venue_90.csv']
location_labels= room_names=["1 - near kitchen"]
weather_location_labels= room_names=["1 - near kitchen"] # used to plot against weather data.
use_diary_filepath = venue_data_dir + "/use_diary.csv"
heating_timings_filepath = venue_data_dir + "heating_timings.csv"
weather_filepath = weather_data_dir + "gcht2024_weather_data.csv"
# had to correct the times - Thermopro default export appears to have exactly the same format for am as pm so can only get from context. Did that in Excel by copying the first
# timestamp to column 4 as it was morning start, and then adding 1/24/4 to it for 15 minute intervals, filling down.
# :TODO: if this is a common problem, need to specify the start timestamp in a constant here and add programmatically - but with some kind of check Thermopro never "skipped".
# import ipywidgets as widgets
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import os as os
list_of_temp_traces = []
list_of_rh_traces = []
list_of_traces_for_weather_comparison = []
dfUseDiary = pd.DataFrame()
dfHeatTimes = pd.DataFrame()
#from IPython.display import display
# now the homebuilt monitor
if os.path.isfile(use_diary_filepath):
dfUseDiary = pd.read_csv(use_diary_filepath)
dfUseDiary = dfUseDiary.fillna('')
dfUseDiary['annotation_position'] = dfUseDiary['annotation_position'].replace(to_replace="", value="top left")
dfUseDiary['start'] = pd.to_datetime(dfUseDiary['startUse'])
dfUseDiary['end'] = pd.to_datetime(dfUseDiary['endUse'])
if os.path.isfile(heating_timings_filepath):
dfHeatTimes = pd.read_csv(heating_timings_filepath)
dfHeatTimes = dfHeatTimes.fillna('')
dfHeatTimes['start'] = pd.to_datetime(dfHeatTimes['startHeat'])
dfHeatTimes['end'] = pd.to_datetime(dfHeatTimes['endHeat'])
for temp_filename,location_label in zip(temp_filenames,location_labels):
df = pd.read_csv(venue_temp_data_dir + temp_filename,encoding='latin-1') #,usecols=[1,2,3], header=1, names=[ 'time','temperature','rh'])
#df["timestamp"] = pd.to_datetime(df['time'])
df = df.fillna('')
#range_min = df['timestamp'].min()
#range_max = df['timestamp'].max()
#print(range_min, " to ", range_max) # this just uses the range of the last file, not ideal
trace = go.Scatter(customdata=df,
y=df['temperature'],
x = df['timestamp'],
mode='lines',
hoverinfo='all',
name=location_label,
)
list_of_temp_traces.append(trace)
# aim for representative one per space where there are questions about the relation to weather, just to make it easier to work with the plot.
if (location_label in weather_location_labels):
list_of_traces_for_weather_comparison.append(trace)
trace = go.Scatter(customdata=df,
y=df['rh'],
x = df['timestamp'],
mode='lines',
hoverinfo='all',
name=location_label,
)
list_of_rh_traces.append(trace)
# create a trace for the weather data
df = pd.read_csv(weather_filepath,encoding='latin-1',usecols=[0,1], header=1, names=[ 'time','temperature'])
df["timestamp"] = pd.to_datetime(df['time'])
df = df.fillna('')
trace = go.Scatter(customdata=df,
y=df['temperature'],
x = df['timestamp'],
mode='lines',
hoverinfo='all',
name="outside",
)
list_of_traces_for_weather_comparison.append(trace)
temp_g = go.FigureWidget(data=list_of_temp_traces,
layout = go.Layout(
yaxis=dict(range=[9,25])
))
rh_g = go.FigureWidget(data=list_of_rh_traces,
layout = go.Layout(
yaxis=dict(range=[0,100])
))
weather_g = go.FigureWidget(data=list_of_traces_for_weather_comparison,
layout = go.Layout(
yaxis=dict(range=[-6,25])
))
# example syntax for two plots on same x-axis - I'd like to show the boiler temperature in
# parallel - but havne't had time to sort the syntax.
#fig = make_subplots(rows=2, cols=1, shared_xaxes=True)
# for i, col in enumerate(cols, start=1):
# fig.add_trace(go.Scatter(x=df[col].index, y=df[col].values), row=i, col=1)
temp_fig = go.Figure(temp_g)
temp_fig.update_layout(showlegend=True,
autosize = True,
title= "Temperature (deg C))",
width=plot_width,
height=plot_height,
)
rh_fig = go.Figure(rh_g)
rh_fig.update_layout(showlegend=True,
autosize = True,
title= "Relative Humidity (%RH)",
width=plot_width,
height=plot_height,
)
weather_fig = go.Figure(weather_g)
weather_fig.update_layout(showlegend=True,
autosize = True,
title= "Indoor vs outdoor temperature from weather station (deg C))",
width=plot_width,
height=plot_height,
)
temp_fig.update_layout(
hovermode='x unified',
# range=[range_min, range_max],
hoverlabel=dict(
bgcolor="white",
# font_size=16,
font_family="Rockwell"
)
)
#Add range slider
temp_fig.update_layout(
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(
label="All",
step="all"
),
dict(count=1,
label="Hour",
step="hour",
stepmode="todate"),
dict(count=1,
label="Day",
step="day",
stepmode="backward"),
dict(count=7,
label="Week",
step="day",
stepmode="backward"),
dict(count=1,
label="Year",
step="year",
stepmode="backward")
])
),
rangeslider=dict(
visible=True,
),
type="date"
)
)
for ind in dfUseDiary.index:
temp_fig.add_vrect(x0=dfUseDiary['start'][ind], x1=dfUseDiary['end'][ind],
annotation_text=dfUseDiary['label'][ind],
annotation_position=dfUseDiary['annotation_position'][ind],
annotation=dict(font_size=14,
font_family="Times New Roman"),
fillcolor="green",
opacity=0.25,
line_width=0)
for ind in dfHeatTimes.index:
temp_fig.add_vrect(x0=dfHeatTimes['start'][ind], x1=dfHeatTimes['end'][ind])
#fig.add_hline(y=16, annotation_text='16C - usual minimum for children', annotation_font_color="blue", line_color='red', layer='above', line_dash='dash')
# fig.update_yaxes(range = [-5, dfCollatedDataSet['temperature'].max()+5])
temp_fig.show()
rh_fig.update_layout(
hovermode='x unified',
# range=[range_min, range_max],
hoverlabel=dict(
bgcolor="white",
# font_size=16,
font_family="Rockwell"
)
)
#Add range slider
rh_fig.update_layout(
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(
label="All",
step="all"
),
dict(count=1,
label="Hour",
step="hour",
stepmode="todate"),
dict(count=1,
label="Day",
step="day",
stepmode="backward"),
dict(count=7,
label="Week",
step="day",
stepmode="backward"),
dict(count=1,
label="Year",
step="year",
stepmode="backward")
])
),
rangeslider=dict(
visible=True,
),
type="date"
)
)
#fig.add_hline(y=16, annotation_text='16C - usual minimum for children', annotation_font_color="blue", line_color='red', layer='above', line_dash='dash')
# fig.update_yaxes(range = [-5, dfCollatedDataSet['temperature'].max()+5])
rh_fig.show()
weather_fig.update_layout(
hovermode='x unified',
# range=[range_min, range_max],
hoverlabel=dict(
bgcolor="white",
# font_size=16,
font_family="Rockwell"
)
)
#Add range slider
weather_fig.update_layout(
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(
label="All",
step="all"
),
dict(count=1,
label="Hour",
step="hour",
stepmode="todate"),
dict(count=1,
label="Day",
step="day",
stepmode="backward"),
dict(count=7,
label="Week",
step="day",
stepmode="backward"),
dict(count=1,
label="Year",
step="year",
stepmode="backward")
])
),
rangeslider=dict(
visible=True,
),
type="date"
)
)
for ind in dfHeatTimes.index:
weather_fig.add_vrect(x0=dfHeatTimes['start'][ind], x1=dfHeatTimes['end'][ind])
# just for this one, because no heating diary, add the use diary to the weather figure.
for ind in dfUseDiary.index:
weather_fig.add_vrect(x0=dfUseDiary['start'][ind], x1=dfUseDiary['end'][ind],
annotation_text=dfUseDiary['label'][ind],
annotation_position=dfUseDiary['annotation_position'][ind],
annotation=dict(font_size=14,
font_family="Times New Roman"),
fillcolor="green",
opacity=0.25,
line_width=0)
#fig.add_hline(y=16, annotation_text='16C - usual minimum for children', annotation_font_color="blue", line_color='red', layer='above', line_dash='dash')
# fig.update_yaxes(range = [-5, dfCollatedDataSet['temperature'].max()+5])
weather_fig.show()