From fb024ded084171d1cedaf74908a6d1767481e6b4 Mon Sep 17 00:00:00 2001 From: Jan Pecinovsky Date: Sun, 29 Apr 2018 18:38:20 +0200 Subject: [PATCH] modulation level detection --- notebooks/Modulation Detection.ipynb | 150 +++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 notebooks/Modulation Detection.ipynb diff --git a/notebooks/Modulation Detection.ipynb b/notebooks/Modulation Detection.ipynb new file mode 100644 index 0000000..e9b602e --- /dev/null +++ b/notebooks/Modulation Detection.ipynb @@ -0,0 +1,150 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Intro\n", + "\n", + "Some condensing gas boilers have the ability to *modulate*, this means that they can adjust the power of the burn. In short: while heating a building, the boiler will start of at maximum power and will gradually lower the power as the temperature of the water in the pipes rises. This allows the boiler to burn longer, at a higher efficiency. (gas boilers are more efficient at lower power)\n", + "\n", + "If you know a boiler has the capability of modulation, you can increase the efficiency ever further by adjusting the settings so it only starts its burn at a lower power. However it takes longer to get the building up to temperature. You can set your thermostat so it starts the heating cycle earlier, or a smart thermostat will automatically do this for you.\n", + "\n", + "The aim of this analysis is to use detailed gas consumption data to detect the power level at which a certain gas boiler modulates." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import opengrid as og\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt = og.plot_style()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Test Dataset\n", + "\n", + "We have a large (1 month) dataset of gas consumption in 30 second resolution. If you take a closer look, you can see that a gas cycle consists of a peak, after which the boiler immediately lowers its power. We want to determine this level." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ts = og.datasets.get('gas_012017_30s')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ts_zoom = ts.truncate(before=pd.Timestamp('20170101'), after=pd.Timestamp('201701010700'))\n", + "_ = ts_zoom.plot()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Find modulation levels" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ml = og.analysis.modulation_detection(ts)\n", + "print(ml)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You get two values, the median modulation level, and the minimum modulation level.\n", + "\n", + "The median is most useful for further analysis. The minimum can be useful to cut of a curve, where the remainder would be \"all the gas that is used by the boiler\"." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ts_zoom.plot()\n", + "pd.Series(index=ts_zoom.index, data=[ml.median], name='median').plot()\n", + "pd.Series(index=ts_zoom.index, data=[ml.minimum], name='minimum').plot()\n", + "_ = plt.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To interpret the result even further it is useful to look at the load duration curve. Notice that the median sits right on the \"plateau\", while the minimum sits just below the knee." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ld = og.analysis.load_duration(ts)\n", + "ld.plot()\n", + "pd.Series(index=ld.index, data=[ml.median], name='median').plot()\n", + "pd.Series(index=ld.index, data=[ml.minimum], name='min').plot()\n", + "_ = plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}