Skip to content
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
Cannot retrieve contributors at this time
executable file 87 lines (76 sloc) 2.68 KB
#!/usr/bin/env python
# Script to detect leakages in water consumption by reading the timestamps
# and counter values from a database.
# The script assumes that during a period of some hours of a day should
# be absolute no water consumption.
# The script detects the longest pause of water consumption. If its duration
# is below a given threshold, then a warning message is printed.
import os
import csv
import rrdtool as rrd
from datetime import datetime
import time
from math import *
# Path to RRD with counter values
count_rrd = "{0}/water.rrd".format(os.path.dirname(os.path.abspath(__file__)))
# Alternative: Path to output of rrdtool fetch
count_fetch = "{0}/water.fetch.txt".format(os.path.dirname(os.path.abspath(__file__)))
# Length of the minimum duration without water consumption in seconds
min_pause = 3 * 60 * 60 # 3 hours
# Verbose output
verbose = False
# Read the rrd specified in count_rrd.
# Returns array of (timestamp, counter).
def read_rrd():
result = []
((start, stop, step), head, data) = rrd.fetch(count_rrd, 'LAST', '-s', 'now - 1 day', '-e', 'now')
t = start
for row in data:
if row[0]:
result.append((t, row[0]))
t += step
return result
# Read the text file specified in count_fetch.
# The text file is the output of command 'rrdtool fetch'.
# Returns array of (timestamp, counter).
def read_fetch_output():
result = []
with open(count_fetch, 'r') as f:
reader = csv.reader(f, delimiter=' ')
for row in reader:
if len(row) == 3:
value = int(row[0][:-1]), float(row[1])
if not isnan(value[1]):
return result
# Detect all pauses which last longer than min_pause.
# Param data: array of (timestamp, counter)
# Returns array of dictionaries {start, duration}.
def detect_pauses(data):
result = []
(start_time, start_counter) = data[0]
(end_time, end_counter) = data[-1]
data.append((time.time(), end_counter + 1)) # ensure that counter increments
for (ts, counter) in data:
if counter > start_counter:
duration = ts - start_time
if duration >= min_pause:
result.append({'start' : start_time, 'duration' : duration})
start_time = ts
start_counter = counter
return result
def main():
#counter = read_fetch_output()
counter = read_rrd()
if len(counter) > 0:
pauses = detect_pauses(counter)
if verbose:
for p in pauses:
print("Pause starting at {0:%Y-%m-%d %H:%M:%S}: {1:.1f} hours"
.format(datetime.fromtimestamp(p['start']), p['duration']/3600.0))
if len(pauses) == 0:
print("Possible leak detected! There is no break of at least {0} hours."
if __name__ == '__main__':