tested running for a month
This commit is contained in:
146
not-tested/dash-power_room.py
Normal file
146
not-tested/dash-power_room.py
Normal file
@@ -0,0 +1,146 @@
|
||||
import dash
|
||||
from dash import dcc, html, Input, Output, State
|
||||
import plotly.express as px
|
||||
import sqlite3
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# Create a Dash app
|
||||
app = dash.Dash(__name__)
|
||||
|
||||
# Function to fetch data from the SQLite database
|
||||
def fetch_data():
|
||||
conn = sqlite3.connect('power_data.db')
|
||||
building_totals = pd.read_sql_query('SELECT * FROM building_totals', conn)
|
||||
room_breakdown = pd.read_sql_query('SELECT * FROM room_breakdown', conn)
|
||||
conn.close()
|
||||
return building_totals, room_breakdown
|
||||
|
||||
# Function to calculate kWh usage
|
||||
def calculate_kwh(data, power_column):
|
||||
data = data.copy() # Create a copy of the DataFrame to avoid SettingWithCopyWarning
|
||||
data.loc[:, 'timestamp'] = pd.to_datetime(data['timestamp'], format='ISO8601')
|
||||
data = data.sort_values('timestamp')
|
||||
data.loc[:, 'time_diff'] = data['timestamp'].diff().dt.total_seconds() / 3600 # Convert to hours
|
||||
data.loc[:, 'kwh'] = data[power_column] * data['time_diff']
|
||||
data.loc[:, 'cumulative_kwh'] = data['kwh'].cumsum()
|
||||
return data
|
||||
|
||||
# Define the layout of the dashboard
|
||||
app.layout = html.Div([
|
||||
html.H1("Power and Current Data Dashboard"),
|
||||
dcc.Dropdown(
|
||||
id='time-range-selector',
|
||||
options=[
|
||||
{'label': 'Last 6 Hours', 'value': 6},
|
||||
{'label': 'Last 12 Hours', 'value': 12},
|
||||
{'label': 'Last 1 Day', 'value': 24},
|
||||
{'label': 'Last 2 Days', 'value': 48},
|
||||
{'label': 'Last 1 Week', 'value': 168},
|
||||
{'label': 'Last 1 Month', 'value': 720},
|
||||
{'label': 'Last 2 Months', 'value': 1440},
|
||||
{'label': 'Last 1 Year', 'value': 8760}
|
||||
],
|
||||
value=6,
|
||||
clearable=False
|
||||
),
|
||||
dcc.Graph(id='building-totals-graph'),
|
||||
dcc.Dropdown(
|
||||
id='room-selector',
|
||||
options=[{'label': room, 'value': room} for room in fetch_data()[1]['room_number'].unique()],
|
||||
value=fetch_data()[1]['room_number'].iloc[0] if not fetch_data()[1].empty else None,
|
||||
placeholder="Select a room"
|
||||
),
|
||||
dcc.Graph(id='room-graph')
|
||||
])
|
||||
|
||||
# Define callbacks to update the graphs
|
||||
@app.callback(
|
||||
Output('building-totals-graph', 'figure'),
|
||||
Input('time-range-selector', 'value'),
|
||||
Input('building-totals-graph', 'relayoutData')
|
||||
)
|
||||
def update_building_totals_graph(time_range, relayoutData):
|
||||
building_totals, _ = fetch_data()
|
||||
building_totals = calculate_kwh(building_totals, 'total_power')
|
||||
|
||||
# Handle time range selection
|
||||
end_time = datetime.now()
|
||||
start_time = end_time - timedelta(hours=time_range)
|
||||
filtered_data = building_totals[(building_totals['timestamp'] >= start_time) & (building_totals['timestamp'] <= end_time)]
|
||||
|
||||
# Handle zoom level
|
||||
if relayoutData and 'xaxis.range[0]' in relayoutData:
|
||||
zoom_start = pd.to_datetime(relayoutData['xaxis.range[0]'])
|
||||
zoom_end = pd.to_datetime(relayoutData['xaxis.range[1]'])
|
||||
filtered_data = filtered_data[(filtered_data['timestamp'] >= zoom_start) & (filtered_data['timestamp'] <= zoom_end)]
|
||||
|
||||
latest_data = filtered_data.iloc[-1] if not filtered_data.empty else None
|
||||
|
||||
fig = px.line(filtered_data, x='timestamp', y=['total_current', 'total_power', 'cumulative_kwh'],
|
||||
title='Building Totals', labels={'value': 'Value', 'variable': 'Metric'})
|
||||
|
||||
if latest_data is not None:
|
||||
fig.update_traces(
|
||||
name=f"Total Current: {latest_data['total_current']} A",
|
||||
selector=dict(name="total_current")
|
||||
)
|
||||
fig.update_traces(
|
||||
name=f"Total Power: {latest_data['total_power']} kW",
|
||||
selector=dict(name="total_power")
|
||||
)
|
||||
fig.update_traces(
|
||||
name=f"Cumulative kWh: {round(latest_data['cumulative_kwh'], 3)} kWh",
|
||||
selector=dict(name="cumulative_kwh")
|
||||
)
|
||||
|
||||
return fig
|
||||
|
||||
@app.callback(
|
||||
Output('room-graph', 'figure'),
|
||||
Input('time-range-selector', 'value'),
|
||||
Input('room-selector', 'value'),
|
||||
Input('room-graph', 'relayoutData')
|
||||
)
|
||||
def update_room_graph(time_range, selected_room, relayoutData):
|
||||
if selected_room:
|
||||
_, room_breakdown = fetch_data()
|
||||
room_data = room_breakdown[room_breakdown['room_number'] == selected_room]
|
||||
room_data = calculate_kwh(room_data, 'power')
|
||||
|
||||
# Handle time range selection
|
||||
end_time = datetime.now()
|
||||
start_time = end_time - timedelta(hours=time_range)
|
||||
filtered_data = room_data[(room_data['timestamp'] >= start_time) & (room_data['timestamp'] <= end_time)]
|
||||
|
||||
# Handle zoom level
|
||||
if relayoutData and 'xaxis.range[0]' in relayoutData:
|
||||
zoom_start = pd.to_datetime(relayoutData['xaxis.range[0]'])
|
||||
zoom_end = pd.to_datetime(relayoutData['xaxis.range[1]'])
|
||||
filtered_data = filtered_data[(filtered_data['timestamp'] >= zoom_start) & (filtered_data['timestamp'] <= zoom_end)]
|
||||
|
||||
latest_data = filtered_data.iloc[-1] if not filtered_data.empty else None
|
||||
|
||||
fig = px.line(filtered_data, x='timestamp', y=['current', 'power', 'cumulative_kwh'],
|
||||
title=f'Room {selected_room}', labels={'value': 'Value', 'variable': 'Metric'})
|
||||
|
||||
if latest_data is not None:
|
||||
fig.update_traces(
|
||||
name=f"Current: {latest_data['current']} A",
|
||||
selector=dict(name="current")
|
||||
)
|
||||
fig.update_traces(
|
||||
name=f"Power: {latest_data['power']} kW",
|
||||
selector=dict(name="power")
|
||||
)
|
||||
fig.update_traces(
|
||||
name=f"Cumulative kWh: {round(latest_data['cumulative_kwh'], 3)} kWh",
|
||||
selector=dict(name="cumulative_kwh")
|
||||
)
|
||||
|
||||
return fig
|
||||
return px.line(title='Select a room to display its graph')
|
||||
|
||||
# Run the app
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=8050, debug=True)
|
||||
Reference in New Issue
Block a user