Hopefully this will make sense!
#!/usr/bin/env python
#Program to read data from WattsUp power meter through USB port.
#Written by Steve Roof, September 2016
#This version sets Watts Up meter to external logging then does a continuous loop writing data to file
#and sends data to emoncms web site
import sys
import string
import serial
import time
import requests
from datetime import datetime, date
#Define the serial port the WattsUp is connected to
WattsUp = serial.Serial('/dev/ttyUSB0', baudrate=115200)
#define output file
data_file_name = '/home/pi/wattsup/GreyWaterSumpPump1.txt'
#initialize some variables
current_day = date.today()
firstpass = True
daily_total_kWh = prev_kWh_tot = kWh_tot = prev_meter_kWh_tot = elapsed_hours = elapsed_minutes = 0.0
#kWh_tot is running total since wattsup program started, not total value report by meter
#Set Watts Up meter to external logging mode. Triple quotes are needed to escape the # char
#last digit before semi-colon in trigger sets logging interval in seconds
trigger1 = '''#L,W,3,E,2,60;'''
WattsUp.write(trigger1)
time.sleep(4)
#Create output file (append to it if it already exists)
with open(data_file_name, 'a') as file:
file.write('\n')
file.write(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + ', +++++++ Program Started +++++++'))
file.write('\n')
file.write(trigger1) #record trigger in file
file.write('\n')
file.write('Date Time,d,-,18,W,V,A,WH,Cost,WH/Mo,Cost/Mo,Wmax,Vmax,Amax,Wmin,Vmin,Amin,PF,DC,PC,Hz,VA')
file.write('\n')
#Read output line from the WattsUp and discard - 1st line is often incomplete
WattsUp_data = WattsUp.readline()
start_time = time.time()
while True:
try:
#Read output from the WattsUp
WattsUp_data = WattsUp.readline()
#write raw results to output file
with open(data_file_name, 'a') as file:
if firstpass:
file.write('Line below is first pass - it was not processed: ')
file.write('\n')
file.write(str((datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))
file.write(', ')
file.write(WattsUp_data)
#Clean up data stream and extract relevant values using split
WattsUp_data = WattsUp_data.strip() #strips any non-printing characters including line feeds '\n'
if WattsUp_data[1:7] <> 'd,-,18': #tests to determine if input is proper data string (proper strings start with #d,-,18
with open(data_file_name, 'a') as file:
file.write(str((datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))
file.write(', +++++ Malformed Input Line Above Skipped +++++')
file.write('\n')
firstpass = False #needed if data line from 1st pass is malformed, since reset of firstpass below will be skipped
continue #"continue" causes program to skip code lines below and immediately return to beginning of While loop
else:
Watts = (float(WattsUp_data.split(',')[3])/10) #Splits out watt value, converts to float, then divides by 10
meter_kWh_tot = (float(WattsUp_data.split(',')[6])/10000) #Splits out watt-hour value, converts to float, then divides by 10000
#This prevents the daily_total values from accumulating bad data on first pass through While loop
if not firstpass:
#calculate change in kWh_tot in interval
interval_kWh_tot = meter_kWh_tot - prev_meter_kWh_tot
if interval_kWh_tot < 0: # Occurs when WH rolls over at approx 260,000
interval_kWh_tot = 0 # Replace any negative interval value with zero
daily_total_kWh = daily_total_kWh + interval_kWh_tot
#kWh_tot is running total since wattsup program started, not total value report by meter
kWh_tot = kWh_tot + interval_kWh_tot
elapsed_seconds = time.time() - start_time
m, s = divmod(elapsed_seconds, 60) #see http://stackoverflow.com/questions/775049/python-time-seconds-to-hms
h, m = divmod(m, 60)
elapsed_hours = str(int(h))
elapsed_minutes = str(int(m))
#Format data to send to emoncms.org.
datapack = "GreyWaterSumpPump1_Watts:" + str(round(Watts,6)) + \
",GreyWaterSumpPump1_kWh_tot:" + str(round(kWh_tot,6)) + \
",GreyWaterSumpPump1_daily_total_kWh:" + str(round(daily_total_kWh,6)) + \
",GreyWaterSumpPump1_elapsed_hours:" + str(elapsed_hours) + \
",GreyWaterSumpPump1_elapsed_minutes:" + str(elapsed_minutes)
# print 'datapack = ' + datapack
#determine epochtime
epochtime = str(int((datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()))
#insert the api key at the beginning and append the data:
#This version sends to node 4 at emons!
oem_payload = "time=" + epochtime + "&node=4&apikey=XXXXXXXXXXXXXXXXXXXX&json=" + datapack
#print 'oem_payload = ' + oem_payload
#combine the url with the payload into "fullurl":
fullurl = 'http://emoncms.org/input/post.json?' + oem_payload
#print 'fullurl: ' + fullurl
#Now send the message to emomcms.org if it's not the first pass
if not firstpass:
r = requests.post(fullurl)
#Test if current time has passed midnight and if true, reset "daily_total_" values and "today" value
if date.today() > current_day:
daily_total_kWh = 0.0
current_day = date.today()
#Set all current values to prev_ values for next pass
firstpass = False
prev_meter_kWh_tot = meter_kWh_tot
except:
error_msg = sys.exc_info()
with open(data_file_name, 'a') as file:
file.write(str((datetime.now().strftime('%Y-%m-%d %H:%M:%S'))))
file.write(', ')
file.write(str(error_msg))
file.write('\n')