From 0db98991f12b8e98c9aac1e9a943d283415cc138 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Tue, 31 Oct 2017 16:49:12 -0500 Subject: [PATCH] MAXH2O-44, Adds monthly totals, reset database capabilities, public IP --- HTML/Device.html | 57 ++++++++++++++++++++++++++++ HTML/Reports.html | 1 + config.txt | 6 +-- flow-monitor.py | 96 ++++++++++++++++++++++++++++++++++++++++------- utilities.py | 11 ++++++ 5 files changed, 154 insertions(+), 17 deletions(-) create mode 100644 HTML/Device.html create mode 100644 HTML/Reports.html create mode 100644 utilities.py diff --git a/HTML/Device.html b/HTML/Device.html new file mode 100644 index 0000000..1af65a1 --- /dev/null +++ b/HTML/Device.html @@ -0,0 +1,57 @@ +
+
+

Public IP Address

+

<%= channels["flowmonitor.public_ip_address"].value %>

+

+ + +
+ + \ No newline at end of file diff --git a/HTML/Reports.html b/HTML/Reports.html new file mode 100644 index 0000000..1c42950 --- /dev/null +++ b/HTML/Reports.html @@ -0,0 +1 @@ +DynamicTable \ No newline at end of file diff --git a/config.txt b/config.txt index d3bd190..a894fe3 100644 --- a/config.txt +++ b/config.txt @@ -3,8 +3,8 @@ "driverFileName":"flow-monitor.py", "deviceName":"flowmonitor", "driverId":"0140", -"releaseVersion":"6", +"releaseVersion":"7", "files": { - "file1":"flow-monitor.py"} - + "file1":"flow-monitor.py", + "file2":"utilities.py"} } diff --git a/flow-monitor.py b/flow-monitor.py index 8607f36..920bc69 100644 --- a/flow-monitor.py +++ b/flow-monitor.py @@ -4,11 +4,14 @@ import time from datetime import datetime import sqlite3 from device_base import deviceBase +from utilities import get_public_ip_address CREATE_FLOWDATA_TABLE = """CREATE TABLE flow_data ( id integer PRIMARY KEY, gal_totalizer_value float, bbl_totalizer_value float, + gal_monthly_totalizer float, + bbl_monthly_totalizer float, last_measured_timestamp integer );""" @@ -16,14 +19,25 @@ INSERT_BLANK_FLOWDATA = """INSERT INTO flow_data ( id, gal_totalizer_value, bbl_totalizer_value, + gal_monthly_totalizer, + bbl_monthly_totalizer, last_measured_timestamp) - VALUES (1, 0.0, 0.0, 0);""" + VALUES (1, 0.0, 0.0, 0.0, 0.0, 0);""" CLEAR_FLOWDATA = """UPDATE flow_data SET gal_totalizer_value=0.0, bbl_totalizer_value=0.0, + gal_monthly_totalizer=0.0, + bbl_monthly_totalizer=0.0, last_measured_timestamp=0 WHERE id=1;""" +UPDATE_FLOWDATA = """UPDATE flow_data SET + gal_totalizer_value=?, + bbl_totalizer_value=?, + gal_monthly_totalizer=?, + bbl_monthly_totalizer=?, + last_measured_timestamp=? WHERE id=1""" + CREATE_SCALINGDATA_TABLE = """CREATE TABLE scaling_data ( id integer PRIMARY KEY, raw_min float, @@ -91,6 +105,13 @@ def is_today(tstamp): midnight_ts = (midnight_today - datetime(1970, 1, 1)).total_seconds() return tstamp >= midnight_ts +def is_thismonth(tstamp): + """Check if a given timestamp belongs to the current month.""" + today = datetime.today() + tstamp_date = datetime.fromtimestamp(tstamp) + return today.month == tstamp_date.month + + class start(threading.Thread, deviceBase): """Start class required for driver.""" @@ -109,7 +130,7 @@ class start(threading.Thread, deviceBase): self.GPM_MAX = 100.0 self.daemon = True - self.version = "6" + self.version = "7" self.finished = threading.Event() threading.Thread.start(self) @@ -127,6 +148,7 @@ class start(threading.Thread, deviceBase): flow_time_store_delta = 600 # seconds startup_wait_seconds = 30 + gpm_val = 0.0 @@ -135,15 +157,32 @@ class start(threading.Thread, deviceBase): galtotal_ch = Channel('gal_total', 100.0, total_time_store_delta) bbltotal_ch = Channel('bbl_total', galtotal_ch.senddelta_value/gal_per_bbl, total_time_store_delta) + galtotalthismonth_ch = Channel('gal_total_thismonth', galtotal_ch.senddelta_value, total_time_store_delta) + bbltotalthismonth_ch = Channel('bbl_total_thismonth', galtotalthismonth_ch.senddelta_value/gal_per_bbl, total_time_store_delta) + gpmflow_ch = Channel('gpm_flow', 10.0, flow_time_store_delta) bpdflow_ch = Channel('bpd_flow', gpmflow_ch.senddelta_value * 34.2857, flow_time_store_delta) runstatus_ch = Channel('run_status', 0.5, 600) date_reset = False + month_reset = False gal_totalizer_value = 0.0 bbl_totalizer_value = 0.0 + gal_monthly_totalizer = 0.0 + bbl_monthly_totalizer = 0.0 + + wait_loops = 0 + while wait_loops < startup_wait_seconds: + print("Waiting to start driver in {} seconds".format(startup_wait_seconds - wait_loops)) + wait_loops += 1 + time.sleep(1) + + public_ip_address = get_public_ip_address() + self.sendtodb('public_ip_address', public_ip_address, 0) + ip_checked_time = time.time() + ip_check_after = 3600 # send after an hour last_measured_timestamp = time.time() conn = sqlite3.connect('/root/python_firmware/drivers/flow-monitor.db') @@ -153,7 +192,9 @@ class start(threading.Thread, deviceBase): stored_data = cursor.fetchone() gal_totalizer_value = stored_data[1] bbl_totalizer_value = stored_data[2] - last_measured_timestamp = stored_data[3] + gal_monthly_totalizer = stored_data[3] + bbl_monthly_totalizer = stored_data[4] + last_measured_timestamp = stored_data[5] except sqlite3.OperationalError: print("No table flow_data in the database. I'll create it now.") cursor.execute(CREATE_FLOWDATA_TABLE) @@ -186,11 +227,7 @@ class start(threading.Thread, deviceBase): bbl_totalizer_value = 0.0 last_measured_timestamp = time.time() - wait_loops = 0 - while wait_loops < startup_wait_seconds: - print("Waiting to start driver in {} seconds".format(startup_wait_seconds - wait_loops)) - wait_loops += 1 - time.sleep(1) + while True: try: @@ -204,7 +241,7 @@ class start(threading.Thread, deviceBase): if gpm_val < 0: gpm_val = 0 else: - gpm_val = 0.0 + gpm_val = 4.0 bpd_val = (gpm_val / gal_per_bbl) * 60.0 * 24.0 @@ -216,13 +253,17 @@ class start(threading.Thread, deviceBase): gal_totalizer_value += gal_flow_delta bbl_totalizer_value += bbl_flow_delta + gal_monthly_totalizer += gal_flow_delta + bbl_monthly_totalizer += bbl_flow_delta + last_measured_timestamp = now - cursor.execute('UPDATE flow_data SET gal_totalizer_value=?, bbl_totalizer_value=?, last_measured_timestamp=?', - (gal_totalizer_value, bbl_totalizer_value, last_measured_timestamp)) + cursor.execute(UPDATE_FLOWDATA, (gal_totalizer_value, bbl_totalizer_value, gal_monthly_totalizer, bbl_monthly_totalizer, last_measured_timestamp)) + conn.commit() - print('gpm: {}, bpd: {}, gal: {}, bbl:{}'.format(gpm_val, bpd_val, gal_totalizer_value, bbl_totalizer_value)) + print('gpm: {}, bpd: {}, gal: {}, bbl:{}, month_gal:{}, month_bbl:{}'.format( + gpm_val, bpd_val, gal_totalizer_value, bbl_totalizer_value, gal_monthly_totalizer, bbl_monthly_totalizer)) if galtotal_ch.check_if_send_needed(gal_totalizer_value, now): self.sendtodb(galtotal_ch.meshify_name, gal_totalizer_value, 0) @@ -232,6 +273,14 @@ class start(threading.Thread, deviceBase): self.sendtodb(bbltotal_ch.meshify_name, bbl_totalizer_value, 0) bbltotal_ch.update(bbl_totalizer_value, now) + if galtotalthismonth_ch.check_if_send_needed(gal_monthly_totalizer, now): + self.sendtodb(galtotalthismonth_ch.meshify_name, gal_monthly_totalizer, 0) + galtotalthismonth_ch.update(gal_monthly_totalizer, now) + + if bbltotalthismonth_ch.check_if_send_needed(bbl_monthly_totalizer, now): + self.sendtodb(bbltotalthismonth_ch.meshify_name, bbl_monthly_totalizer, 0) + bbltotalthismonth_ch.update(bbl_monthly_totalizer, now) + if gpmflow_ch.check_if_send_needed(gpm_val, now): self.sendtodb(gpmflow_ch.meshify_name, gpm_val, 0) gpmflow_ch.update(gpm_val, now) @@ -249,14 +298,32 @@ class start(threading.Thread, deviceBase): self.sendtodb('bbl_total_yesterday', bbl_totalizer_value, 0) gal_totalizer_value = 0.0 bbl_totalizer_value = 0.0 - cursor.execute('UPDATE flow_data SET gal_totalizer_value=?, bbl_totalizer_value=?, last_measured_timestamp=?', - (gal_totalizer_value, bbl_totalizer_value, last_measured_timestamp)) + cursor.execute(UPDATE_FLOWDATA, (gal_totalizer_value, bbl_totalizer_value, gal_monthly_totalizer, bbl_monthly_totalizer, last_measured_timestamp)) conn.commit() date_reset = True if time.localtime(now)[3] != 0 and date_reset: date_reset = False + if time.localtime(now)[2] == 1 and not month_reset: + self.sendtodb('gal_total_lastmonth', gal_monthly_totalizer, 0) + self.sendtodb('bbl_total_lastmonth', bbl_monthly_totalizer, 0) + gal_monthly_totalizer = 0.0 + bbl_monthly_totalizer = 0.0 + cursor.execute(UPDATE_FLOWDATA, (gal_totalizer_value, bbl_totalizer_value, gal_monthly_totalizer, bbl_monthly_totalizer, last_measured_timestamp)) + conn.commit() + month_reset = True + + if time.localtime(now)[2] != 1 and month_reset: + month_reset = False + + if (now - ip_checked_time) > ip_check_after: + test_public_ip = get_public_ip_address() + if not test_public_ip == public_ip_address: + self.sendtodb('public_ip_address', test_public_ip, 0) + public_ip_address = test_public_ip + ip_checked_time = now + except Exception as e: print("problem in the driver: {}".format(e)) time.sleep(5) @@ -268,6 +335,7 @@ class start(threading.Thread, deviceBase): cursor.execute('SELECT * FROM flow_data WHERE id = 1') cursor.execute(CLEAR_FLOWDATA) conn.commit() + print("DATABASE HAS BEEN RESET!") except sqlite3.OperationalError: print("No table flow_data in the database. I'll create it now.") cursor.execute(CREATE_FLOWDATA_TABLE) diff --git a/utilities.py b/utilities.py new file mode 100644 index 0000000..ee2a297 --- /dev/null +++ b/utilities.py @@ -0,0 +1,11 @@ +"""Utility functions for the driver.""" +import socket + + +def get_public_ip_address(): + """Find the public IP Address of the host device.""" + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.connect(("8.8.8.8", 80)) + public_ip = sock.getsockname()[0] + sock.close() + return public_ip