Skip to content

Commit

Permalink
update of README.md; added option to analyze firewood mass consumptio…
Browse files Browse the repository at this point in the history
…n of a stove
  • Loading branch information
FUEL4EP committed Dec 15, 2022
1 parent bed02dc commit dd03526
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 46 deletions.
69 changes: 55 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# consumption_analysis [![License: CC BY-NC-SA 4.0](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-sa/4.0/) [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FFUEL4EP%2Fconsumption_analysis&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) <a href='https://ko-fi.com/FUEL4EP' target='_blank'><img height='20' style='border:0px;height:20px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=2' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>

Python statistic software for consumption analysis of electrical power, fresh water, oil, gas, pellets, and heat pump energy
Python statistic software for consumption analysis of electrical power, fresh water, oil, gas, pellets, heat pump energy, and firewood

# Installation for [(K)ubuntu] LINUX / Raspian OS:

Expand All @@ -26,9 +26,11 @@ Optional: Put example data bases into the working directory
* gas_energy_consumption.caf
* pellets_energy_consumption.caf
* heat_pump_energy_consumption.caf
* firewood_mass_consumption.caf

**Required python version**
- 3.x
- python2 is **NOT** supported anymore

**Required python modules:**

Expand Down Expand Up @@ -63,6 +65,14 @@ Optional: Put example data bases into the working directory
* moving averages over one year will be calculated after at least one year of data collection
* therefore **for the first year** of data entries, no moving averages will be calculated nor displayed

# Hints for consumption inputs

- The readings of a consumption meter should be inputted into the 'consal' software immediately after reading. The concerning time stamp of the data base is taken based on the system time of your computer at the time of the input.
- The readings can be done at any time. They can be non-equidistant in time.
- The time span between two readings can vary arbitrarily, e.g. after 1 hour, then after 3.2 days, then after 1.34 weeks, then after 5.6 hours, ..
- For creating the graphical views, the data base vectors <time of reading, readout value> are resampled equidistantly in time, in the current software version every 3 hours.
- In case of a newly created data base, the next data base input should be done after the resampling time at the earliest, i.e. after 3 hours.


# Usage:

Expand Down Expand Up @@ -115,7 +125,22 @@ Options:
--hp analyze heat pump consumption
--whp=FILE file storing data base for heat pump consumption analysis

-f analyze firewood mass consumption of a stove (note: mass
of each oven charge needs to be inputted)
--ff=FILE file storing data base for firewood mass consumption
analysis

# Input modes

1. Input of meter readings
- For water, electricity, gas, oil, heat pump energy, pellets energy
- The inputted consumption values are already summed-up by the meter
2. Input of non-meter readings, e.g. firewood charge of a stove
- For firewood charge of a stove
- The inputted consumption values are not summed-up by a meter, but **each** furnance charge is weigthed by a scale. The summing-up is done by the 'consal' software instead.
- **IMPORTANT**: For summing-up the firewood mass consumption correctly, **each furnance charge needs to be weigthed and the firewood weight needs to be inputted with 'consal -f -i', see also below.**

# Examples on usage:

Expand Down Expand Up @@ -153,60 +178,74 @@ Options:


consal --hp

7. Run analysis on provided data base for firewood mass consumption:


consal -f

7. Add a new consumption value to an existing data base and then run an analysis of electrical power consumption:
8. Add a new consumption value to an existing data base and then run an analysis of electrical power consumption:

consal -i -e

8. Add a new consumption value to an existing data base and then run an analysis of water consumption:
9. Add a new consumption value to an existing data base and then run an analysis of water consumption:

consal -i -w


9. Add a new consumption value to an existing data base and then run an analysis of heating oil consumption:
10. Add a new consumption value to an existing data base and then run an analysis of heating oil consumption:


consal -i -o

10. Add a new consumption value to an existing data base and then run an analysis of gas consumption:
11. Add a new consumption value to an existing data base and then run an analysis of gas consumption:


consal -i -g

11. Add a new consumption value to an existing data base and then run an analysis of pellets consumption:
12. Add a new consumption value to an existing data base and then run an analysis of pellets consumption:


consal -i -p

12. Add a new consumption value to an existing data base and then run an analysis of heat pump energy consumption:
13. Add a new consumption value to an existing data base and then run an analysis of heat pump energy consumption:


consal -i \--hp

14. Add the weight of a new furnance charge to an existing data base and then run an analysis of firewood mass consumption:


consal -i -f

13. Create a new data base for electrical power consumption:
15. Create a new data base for electrical power consumption:

consal -i -n -e


14. Create a new data base for water consumption:
16. Create a new data base for water consumption:

consal -i -n -w

15. Create a new data base for heating oil consumption:
17. Create a new data base for heating oil consumption:

consal -i -n -o

16. Create a new data base for gas consumption:
18. Create a new data base for gas consumption:

consal -i -n -g

17. Create a new data base for pellets consumption:
19. Create a new data base for pellets consumption:

consal -i -n -p

18. Create a new data base for heat pump energy consumption:
20. Create a new data base for heat pump energy consumption:

consal -i -n \--hp

21. Create a new data base for firewood mass consumption:

consal -i -n -f



Expand All @@ -218,6 +257,8 @@ Options:
- 13th June 2021: Migration to python3
- 28th October 2022: Fixes due to library updates, update of images
- 21st November 2022: Added analysis options for gas, pellets, and heat pump energy
- 15th December 2022: Added analysis option for firewood mass consumption
Decreased resampling time to 3 hours



Expand Down
Binary file removed __pycache__/graphics.cpython-38.pyc
Binary file not shown.
Binary file removed __pycache__/io_module.cpython-38.pyc
Binary file not shown.
Binary file removed __pycache__/messaging.cpython-38.pyc
Binary file not shown.
130 changes: 98 additions & 32 deletions consal.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

desc="""consal.py is doing a statistical analysis of electrical power, water, oil, gas, pellets, and heat pump consumptions"""
desc="""consal.py is doing a statistical analysis of electrical power, water, oil, gas, pellets, heat pump, and firewood consumptions"""

# $Rev: 79 $:
# $Rev: 81 $:
# $Author: ewald $:
# $Date: 2022-12-03 09:45:53 +0100 (Sa, 03. Dez 2022) $:
# $Id: consal.py 79 2022-12-03 08:45:53Z ewald $
# $Date: 2022-12-15 13:06:52 +0100 (Do, 15. Dez 2022) $:
# $Id: consal.py 81 2022-12-15 12:06:52Z ewald $

__my_version__ = "$Revision: 79 $"
__my_version__ = "$Revision: 81 $"

ELECTRICAL_POWER_CONSUMPTION_FILE="electrical_power_consumption.caf"
WATER_CONSUMPTION_FILE="water_consumption.caf"
OIL_CONSUMPTION_FILE ="oil_consumption.caf"
GAS_CONSUMPTION_FILE ="gas_energy_consumption.caf"
PELLETS_CONSUMPTION_FILE ="pellets_energy_consumption.caf"
HEAT_PUMP_CONSUMPTION_FILE ="heat_pump_energy_consumption.caf"
FIREWOOD_CONSUMPTION_FILE ="firewood_mass_consumption.caf"
TIME_COL=0
VALUE_COL= 1
STRICTLY_INCREASING=1
NOT_STRICTLY_INCREASING=0
MOVING_AVERAGE_DAYS=365
RESAMPLE_TIME_STEP=0.25
RESAMPLE_TIME_STEP=0.125 # resample every 3 hours
EPSILON=1e-6
ALPHA=1e-2
MAX_MEASUREMENT_VARIATION=4
MAX_FIREWOOD_CHARGE=15.0 # adapt this parameter to the maximum allowed charge of your stove

import sys
import optparse
Expand Down Expand Up @@ -62,6 +64,7 @@ def __init__(self):
self.write_table_name=''
self.table=[]
self.np=0
self.increment_flag=False
#list
self.tl=[]
self.cl=[]
Expand All @@ -86,6 +89,14 @@ def __init__(self):
#status flag
self.status=True

def set_increment_flag(self, name):
# set the increment_flag for firewood mass consumption, i.e. each charge of an oven shall be weighted
if ( name == "firewood mass consumption" ):
self.increment_flag = True
#print ("firewood increment_flag is set")
else:
self.increment_flag = False

def set_name(self, name):
self.name = name

Expand Down Expand Up @@ -165,29 +176,59 @@ def check_strictly_increasing_new_row(self, vec):

def check_measurement_input(self, vec):
if self.status != False:
last_row=self.table.last_row()
first_row=self.table.first_row()
#bisheriger Durchschnittsverbrauch pro Tag
slope=(last_row[1]-first_row[1])/(last_row[0]-first_row[0])
for j, el in enumerate(vec):
#print j, el
if isinstance(el, float) and isinstance(last_row[j], float) and self.table.strictly_increasing_check_mask[j]:
if last_row[j] >= el:
if j == 0:
print ("\nWrong input: Actual timestamp \'%.3f\' is smaller than latest table entry \'%.3f\'\n" % (el, last_row[j]))
if j == 1:
print ("\nWrong input: Actual measurement \'%.3f\' is smaller than latest table entry \'%.3f\'\n" % (el, last_row[j]))
return False
else:
if j==1:
actual_slope=(el-last_row[j])/(vec[0]-last_row[0])
print ("\nActual \'%s\' per day: \'%.3f\'\n" % (self.name, actual_slope))
if actual_slope > MAX_MEASUREMENT_VARIATION*slope:
print ("\nWrong input: Actual measurement slope \'%.3f\' is more than \'x%s\' bigger than average slope \'%.3f\'\n" % (actual_slope, MAX_MEASUREMENT_VARIATION, slope))
if self.increment_flag == False:
# check input from a meter
last_row=self.table.last_row()
first_row=self.table.first_row()
#bisheriger Durchschnittsverbrauch pro Tag
slope=(last_row[1]-first_row[1])/(last_row[0]-first_row[0])
for j, el in enumerate(vec):
#print ( j, el )
if isinstance(el, float) and isinstance(last_row[j], float) and self.table.strictly_increasing_check_mask[j]:
if last_row[j] >= el:
if j == 0:
print ("\nWrong input: Actual timestamp \'%.3f\' is smaller than latest table entry \'%.3f\'\n" % (el, last_row[j]))
if j == 1:
print ("\nWrong input: Actual measurement \'%.3f\' is smaller than latest table entry \'%.3f\'\n" % (el, last_row[j]))
return False
else:
if j==1:
actual_slope=(el-last_row[j])/(vec[0]-last_row[0])
print ("\nActual \'%s\' per day: \'%.3f\'\n" % (self.name, actual_slope))
if actual_slope > MAX_MEASUREMENT_VARIATION*slope:
print ("\nWrong input: Actual measurement slope \'%.3f\' is more than \'x%s\' bigger than average slope \'%.3f\'\n" % (actual_slope, MAX_MEASUREMENT_VARIATION, slope))
return False
else:
# check firewood charge input
last_row=self.table.last_row()
for j, el in enumerate(vec):
#print ( j, el )
if isinstance(el, float) and isinstance(last_row[j], float):
if last_row[j] >= el:
if j == 0:
print ("\nWrong input: Actual timestamp \'%.3f\' is smaller than latest table entry \'%.3f\'\n" % (el, last_row[j]))
return False
if el <= 0:
if j == 1:
print ("\nWrong input: Actual charge \'%.3f\' must be positive" % el)
return False
else:
if j==1:
if (el > MAX_FIREWOOD_CHARGE ):
print ("\nWrong input: Actual charge \'%.3f\' is exceeding the maximum charge of \'%.1f\' of the stove (see define MAX_FIREWOOD_CHARGE)" % (el, MAX_FIREWOOD_CHARGE) )
return False
return True
else:
return False

def accumulate_charge_in_increment_mode(self, input_value):
if self.status != False:
if self.increment_flag == True:
if not self.newDB_flag:
last_row=self.table.last_row()
#print ( last_row )
input_value = input_value + last_row[1]
return input_value

def add_row(self, row):
if self.status != False:
Expand Down Expand Up @@ -311,20 +352,24 @@ def input_measurement(self, consistency_check_on):
self.status=False
if self.status != False:
# determine local time for the local timezone
t1 = datetime.datetime(1970, 1, 1, 0, 0, 0) # 1970-01-01 00:0:0
t1 = datetime.datetime(1970, 1, 1, 0, 0, 0) # 1970-01-01 00:0:0
tl = datetime.datetime.now()
tnow=(time.mktime(tl.timetuple())-time.mktime(t1.timetuple()))/24/3600
done = False
while not done:
fp=input_float('Please input actual measurement of \'%s\'\n\n' % self.name)
if self.newDB_flag:
done = True
done = True
else:
done = self.check_measurement_input([tnow, fp])
# accumulate firewood charge of stove to last firewood consumption value, i.e. increment_flag == True
#print ( fp )
fp = self.accumulate_charge_in_increment_mode(fp)
#print (fp )
if self.newDB_flag:
tlminus1 = tl - datetime.timedelta(seconds=1)
tnowminus1=(time.mktime(tlminus1.timetuple())-time.mktime(t1.timetuple()))/24/3600
self.add_row( [tnowminus1, fp-ALPHA])
tlminus60 = tl - datetime.timedelta(seconds=60) #add an artificial table entry for the first entry, timesamp is 60 seconds earlier
tnowminus60=(time.mktime(tlminus60.timetuple())-time.mktime(t1.timetuple()))/24/3600
self.add_row( [tnowminus60, fp-ALPHA])
self.add_row( [tnow, fp])
else:
self.add_row( [tnow, fp])
Expand All @@ -334,6 +379,7 @@ def input_measurement(self, consistency_check_on):
def consumption_analysis(self, name, working_dir, input_file, ylabel,
consistency_check_on, input_flag, newDB_flag):
self.set_name(name)
self.set_increment_flag(name)
self.set_working_dir(working_dir)
self.set_table_name(input_file)
self.set_newDB_flag(newDB_flag)
Expand Down Expand Up @@ -597,6 +643,13 @@ def main():
parser.add_option("--whp", type="string",
help="file storing data base for heat pump energy consumption analysis",
metavar="FILE",dest="file_heat_pump")

parser.add_option("-f", help="analyze firewood mass consumption of a stove (note: mass of each oven charge needs to be inputted)", dest="firewood",
action='store_true')

parser.add_option("--ff", type="string",
help="file storing data base for firewood mass consumption analysis",
metavar="FILE",dest="file_firewood")

parser.set_defaults(verbose=0, no_consistency_check=False, no_greater_than_check=False, newDB=False,
wdir=WORKING_DIR, epower=False,
Expand All @@ -605,7 +658,8 @@ def main():
file_water=WATER_CONSUMPTION_FILE, gas=False,
file_gas=GAS_CONSUMPTION_FILE, pellets=False,
file_pellets=PELLETS_CONSUMPTION_FILE, heat_pump=False,
file_heat_pump=HEAT_PUMP_CONSUMPTION_FILE, version=False, input_flag=False)
file_heat_pump=HEAT_PUMP_CONSUMPTION_FILE, firewood=False,
file_firewood=FIREWOOD_CONSUMPTION_FILE, version=False, input_flag=False)

(options, args) = parser.parse_args()

Expand Down Expand Up @@ -679,7 +733,7 @@ def main():
options.wdir, options.file_pellets, 'pellets energy [kWh]',
not(options.no_consistency_check), options.input_flag, options.newDB)

#analyze heat pump energy consumption
#analyze heat pump energy consumption
if options.heat_pump:
stdMsg("\n\nStarting analysis of heat pump energy consumption ..\n")
#check if data base file is existing and readable
Expand All @@ -690,6 +744,18 @@ def main():
heat_pump.consumption_analysis('heat pump energy consumption',
options.wdir, options.file_heat_pump, 'heat pump energy [kWh]',
not(options.no_consistency_check), options.input_flag, options.newDB)

#analyze firewood mass consumption
if options.firewood:
stdMsg("\n\nStarting analysis of firewood mass consumption of a stove (note: mass of each oven charge needs to be inputted) ..\n")
#check if data base file is existing and readable
check_database_file(options.wdir, options.file_firewood, options.newDB)
#initialize data analysis
firewood=consumption()
#run analysis
firewood.consumption_analysis('firewood mass consumption',
options.wdir, options.file_firewood, 'firewood mass [kg]',
not(options.no_consistency_check), options.input_flag, options.newDB)


if not options.epower and not options.oil and not options.water and not options.gas and not options.pellets and not options.heat_pump:
Expand Down
4 changes: 4 additions & 0 deletions electrical_power_consumption.caf
Original file line number Diff line number Diff line change
Expand Up @@ -600,3 +600,7 @@
19264.809525462966 109450.3
19282.4340625 109679.2
19291.40403935185 109790.4
19310.339016203703 110026.3
19323.384386574075 110198.0
19326.363078703704 110230.7
19340.520914351855 110397.0
2 changes: 2 additions & 0 deletions firewood_mass_consumption.caf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
19341.415324074074 13.59
19341.41601851852 13.6
Loading

0 comments on commit dd03526

Please sign in to comment.