{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "import plotly.express as px\n", "import plotly.graph_objects as go\n", "import pandas as pd\n", "from dash import Dash, html, dcc, Input, Output, callback\n", "import plotly.express as px\n", "import numpy as np\n", "import example_data\n", "import core\n", "\n", "outside_temp = example_data.ExampleDailyOutsideTemperature\n", "energy_price = example_data.ExampleDailyEnergyCost\n", "boiler_temperature = example_data.ExampleBoilerTemperature\n", "\n", "data = pd.DataFrame(columns=['hour', 'energy_consumption', 'comfort', 'policy_readable'])\n", "data = pd.concat([data, pd.DataFrame({'hour': np.arange(0, 24), 'energy_consumption': energy_price.value, 'comfort': np.random.rand(24),\n", " 'policy_readable': np.random.choice(['A', 'B', 'C', 'D', 'E'], 24)\n", " })])\n", "debug = False\n", "\n", "external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']\n", "\n", "app = Dash(__name__, external_stylesheets=external_stylesheets)\n", "\n", "app.layout = html.Div([\n", " dcc.Location(id='url', refresh=False),\n", " html.Div(id='page-content')\n", "])\n", "\n", "server = app.server\n", "\n", "# Solution options\n", "solution_options = [\n", " \"Discrete Optimization\",\n", " \"Continuous Optimization\",\n", " \"Reinforcement Learning\"\n", "]\n", "solution_options_default_value = solution_options[0]\n", "\n", "# Datasets\n", "dataset_options = [\n", " \"16NSJNnjLK4MndjZYaKYGKEV\",\n", " \"7uLwefnSt8CgVlmIGY8emqJK\",\n", " \"8yS04Ddkk3pPL8e9Rku4LJtc\",\n", " \"Cwp33jA19hp9VdoNJUlj6USf\",\n", " \"iBFIAuvh7bCNyOQDo0jkjhRV\",\n", " \"iNVKpGfGW6rU17eOtxpZSFWR\",\n", " \"kaTMmHVh8gXUbHMppzdmdzpv\",\n", " \"KN9Z3gANLftDuUGvgs8O38dI\",\n", " \"LzbMafI31IosheUI7YGhj5at\",\n", " \"PHqaZDuMTRvCZCvA259Z1vJu\",\n", " \"RZngVU6axOdshmfma0yNAajE\",\n", " \"SQUOjMB6zAgYpSJEMy46tKXJ\",\n", " \"UcufQVoJQPbfLzIBnSsUodJP\",\n", " \"VTuh8oxtC6YlOCLeScXfLuY3\",\n", " \"VZTnyVO3TP3ILuYsN5Xw9UR0\",\n", " \"WyPRjcmBXJZoC9DIURMXKxn8\",\n", " \"yPtlbyLlDlzeBZQYrPYaByoB\",\n", "]\n", "dataset_options_default_value = dataset_options[0]\n", "dataset_dfs = {\n", " \"16NSJNnjLK4MndjZYaKYGKEV\": pd.read_csv('data/16NSJNnjLK4MndjZYaKYGKEV.csv')[:100000],\n", " \"7uLwefnSt8CgVlmIGY8emqJK\": pd.read_csv('data/7uLwefnSt8CgVlmIGY8emqJK.csv')[:100000],\n", " \"8yS04Ddkk3pPL8e9Rku4LJtc\": pd.read_csv('data/8yS04Ddkk3pPL8e9Rku4LJtc.csv')[:100000],\n", " \"Cwp33jA19hp9VdoNJUlj6USf\": pd.read_csv('data/Cwp33jA19hp9VdoNJUlj6USf.csv')[:100000],\n", " \"iBFIAuvh7bCNyOQDo0jkjhRV\": pd.read_csv('data/iBFIAuvh7bCNyOQDo0jkjhRV.csv')[:100000],\n", " \"iNVKpGfGW6rU17eOtxpZSFWR\": pd.read_csv('data/iNVKpGfGW6rU17eOtxpZSFWR.csv')[:100000],\n", " \"kaTMmHVh8gXUbHMppzdmdzpv\": pd.read_csv('data/kaTMmHVh8gXUbHMppzdmdzpv.csv')[:100000],\n", " \"KN9Z3gANLftDuUGvgs8O38dI\": pd.read_csv('data/KN9Z3gANLftDuUGvgs8O38dI.csv')[:100000],\n", " \"LzbMafI31IosheUI7YGhj5at\": pd.read_csv('data/LzbMafI31IosheUI7YGhj5at.csv')[:100000],\n", " \"PHqaZDuMTRvCZCvA259Z1vJu\": pd.read_csv('data/PHqaZDuMTRvCZCvA259Z1vJu.csv')[:100000],\n", " \"RZngVU6axOdshmfma0yNAajE\": pd.read_csv('data/RZngVU6axOdshmfma0yNAajE.csv')[:100000],\n", " \"SQUOjMB6zAgYpSJEMy46tKXJ\": pd.read_csv('data/SQUOjMB6zAgYpSJEMy46tKXJ.csv')[:100000],\n", " \"UcufQVoJQPbfLzIBnSsUodJP\": pd.read_csv('data/UcufQVoJQPbfLzIBnSsUodJP.csv')[:100000],\n", " \"VTuh8oxtC6YlOCLeScXfLuY3\": pd.read_csv('data/VTuh8oxtC6YlOCLeScXfLuY3.csv')[:100000],\n", " \"VZTnyVO3TP3ILuYsN5Xw9UR0\": pd.read_csv('data/VZTnyVO3TP3ILuYsN5Xw9UR0.csv')[:100000],\n", " \"WyPRjcmBXJZoC9DIURMXKxn8\": pd.read_csv('data/WyPRjcmBXJZoC9DIURMXKxn8.csv')[:100000],\n", " \"yPtlbyLlDlzeBZQYrPYaByoB\": pd.read_csv('data/yPtlbyLlDlzeBZQYrPYaByoB.csv')[:100000],\n", "}\n", "\n", "# provide a scalar value to enable the slider to select ideal temperature\n", "ideal_temperature = 50\n", "\n", "dashboard_layout = html.Div([\n", " dcc.Link('About this project', href='/wiki'),\n", "\n", " html.H1('System Evaluation'),\n", " #small subtitle that says of solution is possible or not\n", " html.Div(id='solution-status', children='', style={'color': 'lighrgrey'}),\n", " html.Div([\n", " html.Div([\n", " html.H3('Dataset'),\n", " dcc.Dropdown(\n", " id='dataset-dropdown',\n", " options=dataset_options,\n", " value=dataset_options_default_value,\n", " )\n", " ], className='three columns'),\n", " html.Div([\n", " html.H3('Solution'),\n", " dcc.Dropdown(\n", " id='solution-dropdown',\n", " options=solution_options,\n", " value=solution_options_default_value,\n", " )\n", " ], className='three columns'),\n", " html.Div([\n", " html.H3('Ideal Shower Temperature'),\n", " dcc.Slider(\n", " id='ideal-temperature-slider',\n", " min=0,\n", " max=100,\n", " step=1,\n", " value=ideal_temperature,\n", " marks={\n", " 0: '0°C',\n", " 25: '25°C',\n", " 50: '50°C',\n", " 75: '75°C',\n", " 100: '100°C'\n", " },\n", " )\n", " ], className='three columns'),\n", "\n", "\n", " ], className='row'),\n", " html.Div(\n", " [\n", " html.Div(\n", " [\n", " html.H3('Dataset'),\n", " dcc.Graph(id='dataset-graph')\n", " ], className='twelve columns',\n", " )\n", " ], className='row'),\n", " html.Div(\n", " [\n", " html.Div(\n", " [\n", " html.H3('Policy'),\n", " dcc.Graph(id='policy_readable-graph')\n", " ], className='six columns',\n", " ),\n", " html.Div(\n", " [\n", " html.H3('Energy Consumption'),\n", " dcc.Graph(id='energy-consumption-graph')\n", " ], className='six columns'\n", " ),\n", " ]\n", " ),\n", " html.Div(\n", " [\n", " html.Div(\n", " [\n", " html.H3('Comfort'),\n", " dcc.Graph(id='comfort-graph')\n", " ], className='six columns'\n", " )\n", " ], className='row'),\n", "],\n", "#add background image from local file and make it transparent\n", "#, style={'background-image':'url(/assets/background_1.png)'}\n", "style={'background-color': '#333', 'font-family': 'Fantasy', 'color': '#999', 'padding': '10px'}\n", ")\n", "\n", "\n", "wiki_layout = html.Div([\n", " dcc.Link('Dashboard', href='/'),\n", "\n", " html.H1('About this project'),\n", "\n", " html.Div([\n", " html.Div([\n", " \n", " html.H3('What is this project about?'),\n", "\n", " html.P('This project is a simulation of a shower system. The goal is to find the best policy for the boiler to heat the water for the shower. The policy is a function that takes the current hour of the day and the current temperature of the water in the boiler and returns the temperature that the boiler should heat the water to.'),\n", " html.P('The best policy is the one that maximizes the comfort of the shower and minimizes the energy consumption of the boiler.'),\n", "\n", " html.H3('How does it work?'),\n", "\n", " #Insert image of the system\n", "\n", " html.H3('\\'Bout us'),\n", " html.Img(src='/assets/hackatos.png', style={'width': '40%', 'height': 'auto', 'display': 'block', 'margin-left': 'auto', 'margin-right': 'auto'}),\n", " html.P('This project was developed by a team of 3, in the context of the Aveiro Tech City 2023 hackathon.'),\n", " html.P('The team members are:'),\n", " html.H4('Rui Melo'),\n", " html.P('Rui Melo is a ....'),\n", " html.H4('André Catarino'),\n", " html.P('André Catarino is a ....'),\n", " html.H4('Francisco Petronilho'),\n", " html.P('Francisco Petronilho is a ....'),\n", " html.H4('André Tomás'),\n", " html.P('André Tomás is a ....'),\n", " html.H4('Zé Miguel'),\n", " html.P('Zé Miguel is a ....'),\n", "\n", "\n", " html.H3('References'),\n", " html.P('The boiler model was based on the following paper:'),\n", "\n", "\n", " ], className='six columns'),], className='row'),\n", "],\n", "style={'background-color': '#333', 'font-family': 'Fantasy', 'color': '#999', 'padding': '10px'}\n", "\n", ")\n", "\n", "# Update the index\n", "@callback(Output('page-content', 'children'), Input('url', 'pathname'))\n", "def display_page(pathname):\n", " if pathname == '/':\n", " return dashboard_layout\n", " elif pathname == '/wiki':\n", " return wiki_layout\n", " else:\n", " return '404'\n", " # You could also return a 404 \"URL not found\" page here\n", "\n", "\n", "@app.callback(\n", " Output('policy_readable-graph', 'figure'),\n", " Output('energy-consumption-graph', 'figure'),\n", " Output('comfort-graph', 'figure'),\n", " Output('dataset-graph', 'figure'),\n", " Output('solution-status', 'children'),\n", " Input('dataset-dropdown', 'value'),\n", " Input('solution-dropdown', 'value'),\n", " Input('ideal-temperature-slider', 'value')\n", ")\n", "def update_graph(dataset, solution, ideal_temperature):\n", " energy_consumption = data['energy_consumption'].values\n", " comfort_obtained = data['comfort'].values\n", "\n", "\n", " # Dataset Graph\n", " dataset_df = dataset_dfs[dataset]\n", " dataset_df['ChActive'] = dataset_df['ChActive'].map({'Yes': 90, 'No': 5})\n", " dataset_df['HwActive'] = dataset_df['HwActive'].map({'Yes': 100, 'No': 0})\n", "\n", " dataset_graph = px.line()\n", " #Add another line to the plot\n", " dataset_graph.add_scatter(x=dataset_df['ts'], y=dataset_df['ActPow'], mode='lines', name='ActPow')\n", " dataset_graph.add_scatter(x=dataset_df['ts'], y=dataset_df['HwActive'], mode='lines', name='HwActive')\n", " dataset_graph.add_scatter(x=dataset_df['ts'], y=dataset_df['ChActive'], mode='lines', name='ChActive')\n", " dataset_graph.add_scatter(x=dataset_df['ts'], y=dataset_df['HwTSet'], mode='lines', name='HwTSet')\n", " dataset_graph.add_scatter(x=dataset_df['ts'], y=dataset_df['DHW_E21_T3_START_TEMP'], mode='lines', name='START_TEMP')\n", " dataset_graph.add_scatter(x=dataset_df['ts'], y=dataset_df['HwTStor'], mode='lines', name='HwTStor')\n", " dataset_graph.add_scatter(x=dataset_df['ts'], y=dataset_df['HwTAct'], mode='lines', name='HwTAct')\n", " dataset_graph.add_scatter(x=dataset_df['ts'], y=dataset_df['OutTemp'], mode='lines', name='OutTemp')\n", " \n", " start_time = pd.Timestamp(dataset_df['ts'][0])\n", " \n", " dataset_graph.update_xaxes(range=[start_time, start_time+pd.Timedelta(days=2)])\n", "\n", "\n", " # Policy Graph\n", " policy_readable_graph = px.line(data, x='hour', y='policy_readable',\n", " labels={'hour': 'Hour', 'policy_readable': 'Policy'},\n", " color_discrete_sequence=['lightgreen'])\n", " policy_readable_graph.update_layout(\n", " xaxis_title=\"Hour\",\n", " yaxis_title=\"Temperature (°C)\",\n", " legend_title=\"Policy\"\n", " )\n", "\n", "\n", " # Energy Consumption Graph\n", " energy_consumption_graph = px.line(data, x='hour', \n", " y='energy_consumption', \n", " labels={'hour': 'Hour', 'energy_consumption': 'Energy Consumption (kWh)'},\n", " color_discrete_sequence=['lightgreen'])\n", " energy_consumption_graph.update_layout(\n", " xaxis_title=\"Hour\",\n", " yaxis_title=\"Energy Consumption (kWh)\",\n", " legend_title=\"Energy Consumption\",\n", " )\n", " #add accumulated energy consumption\n", " energy_consumption = np.cumsum(energy_consumption)\n", " energy_consumption_graph.add_trace(px.line(data, x='hour', \n", " y=energy_consumption,\n", " labels={'y': 'Acc. Energy Consumption (kWh)'},\n", " color_discrete_sequence=['green']).data[0])\n", "\n", "\n", " # Comfort Graph\n", " comfort_graph = px.line(data, x='hour', y='comfort',\n", " labels={'hour': 'Hour', 'comfort': 'comfort Score'},\n", " color_discrete_sequence=['lightgreen'])\n", "\n", " comfort_graph.update_layout(\n", " xaxis_title=\"Hour\",\n", " yaxis_title=\"comfort Score\",\n", " legend_title=\"comfort\"\n", " )\n", " #add accumulated comfort\n", " comfort_obtained = np.cumsum(comfort_obtained)\n", " comfort_graph.add_trace(px.line(data, x='hour', y=comfort_obtained,\n", " labels={'y': 'Acc. comfort Score'},\n", " color_discrete_sequence=['green']\n", " ).data[0])\n", " result = \"No solution found\"\n", " return policy_readable_graph, energy_consumption_graph, comfort_graph, dataset_graph, result\n", "\n", "\n", "if __name__ == \"__main__\":\n", " app.run_server(host=\"127.0.0.1\", port=\"8050\", debug=debug)\n" ] } ], "metadata": { "kernelspec": { "display_name": "atc-smart-shower-YhjpRjjr-py3.10", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.2" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }