Browse Source

added test for firmware verson

added arg to demo app meter_status
added version numbers
removed hardcoded address
main
Peter Shipley 11 years ago
parent
commit
e417b2565d
7 changed files with 160 additions and 114 deletions
  1. +2
    -0
      .gitignore
  2. +46
    -8
      RainEagle/EagleClass.py
  3. +1
    -3
      bin/gnup_poweruse.txt
  4. +60
    -30
      bin/meter_status.py
  5. +49
    -71
      bin/plot_power.py
  6. +1
    -1
      doc.txt
  7. +1
    -1
      setup.py

+ 2
- 0
.gitignore View File

@@ -2,8 +2,10 @@


EGG-INFO EGG-INFO
.exrc .exrc
Dump/*
test.* test.*
Sav/* Sav/*
Tests/*
Bak/* Bak/*
*bak *bak




+ 46
- 8
RainEagle/EagleClass.py View File

@@ -2,6 +2,7 @@
__author__ = 'Peter Shipley <peter.shipley@gmail.com>' __author__ = 'Peter Shipley <peter.shipley@gmail.com>'
__copyright__ = "Copyright (C) 2014 Peter Shipley" __copyright__ = "Copyright (C) 2014 Peter Shipley"
__license__ = "BSD" __license__ = "BSD"
__version__ = "0.1.7"


import socket import socket
import sys import sys
@@ -14,6 +15,9 @@ from math import floor
from urlparse import urlparse from urlparse import urlparse
import json import json
from warnings import warn from warnings import warn
from distutils.version import LooseVersion

min_fw_ver = "2.0.21"




from pprint import pprint from pprint import pprint
@@ -143,14 +147,17 @@ class Eagle(object) :
Currently there is very little error handling ( if any at all ) Currently there is very little error handling ( if any at all )
""" """
def __init__(self, **kwargs): def __init__(self, **kwargs):

self.debug = kwargs.get("debug", 0) self.debug = kwargs.get("debug", 0)


if self.debug : if self.debug :
print self.__class__.__name__, __name__ print self.__class__.__name__, __name__
self.checkfw = kwargs.get("checkfirmware", True)
self.addr = kwargs.get("addr", os.getenv('EAGLE_ADDR', None)) self.addr = kwargs.get("addr", os.getenv('EAGLE_ADDR', None))
self.port = kwargs.get("port", os.getenv('EAGLE_PORT', 5002)) self.port = kwargs.get("port", os.getenv('EAGLE_PORT', 5002))
self.getmac = kwargs.get("getmac", True)
self.mac = kwargs.get("mac", None)
self.timeout = kwargs.get("timeout", 10) self.timeout = kwargs.get("timeout", 10)

self.soc = None self.soc = None
self.macid = None self.macid = None


@@ -159,8 +166,12 @@ class Eagle(object) :
print "timeout : = ", self.timeout print "timeout : = ", self.timeout
print "debug : = ", self.debug print "debug : = ", self.debug



if self.addr is None :
raise AssertionError("no hostname or IP given")

# preload # preload
if self.getmac :
if self.mac is None :
self.device_info = self.list_devices() self.device_info = self.list_devices()
if self.device_info is None : if self.device_info is None :
raise IOError("Error connecting") raise IOError("Error connecting")
@@ -171,11 +182,25 @@ class Eagle(object) :
if self.debug : if self.debug :
print "Init DeviceMacId = ", self.macid print "Init DeviceMacId = ", self.macid


if self.checkfw :
mysetting = self.get_setting_data()
dev_fw_ver = mysetting['device_fw_version']
if ( LooseVersion(dev_fw_ver) < LooseVersion(min_fw_ver) ) :
warn_message = "Warning : device firmware " \
+ "{0} < {1} please concideer " \
+ "updating ".format(dev_fw_ver, min_fw_ver)
warn( warn_message, RuntimeWarning, stacklevel=3)





# socket commands as class functions # socket commands as class functions


def list_devices(self): def list_devices(self):
"""
Send the LIST_DEVICES command
returns information about the EAGLE device

"""
comm_responce = self._send_soc_comm("list_devices") comm_responce = self._send_soc_comm("list_devices")
if self.debug : if self.debug :
print "comm_responce =", comm_responce print "comm_responce =", comm_responce
@@ -195,6 +220,8 @@ class Eagle(object) :
comm_responce = self._send_soc_comm("get_device_data", MacId=macid) comm_responce = self._send_soc_comm("get_device_data", MacId=macid)
if comm_responce is None: if comm_responce is None:
raise RainEagleResponseError("get_device_data : Null reply") raise RainEagleResponseError("get_device_data : Null reply")
if self.debug :
print comm_responce
etree = ET.fromstring('<S>' + comm_responce + '</S>') etree = ET.fromstring('<S>' + comm_responce + '</S>')
rv = _et2d(etree) rv = _et2d(etree)
return rv return rv
@@ -332,6 +359,15 @@ class Eagle(object) :


# http commands as class functions # http commands as class functions


def get_device_list(self) :
"""
Send the LIST_DEVICES command
returns information about the EAGLE device

"""
comm_responce = self._send_http_comm("get_device_list")
return json.loads(comm_responce)

def get_uploaders(self) : def get_uploaders(self) :
""" """
gets list of uploaders for Web UI gets list of uploaders for Web UI
@@ -346,7 +382,7 @@ class Eagle(object) :
comm_responce = self._send_http_comm("get_uploaders") comm_responce = self._send_http_comm("get_uploaders")
return json.loads(comm_responce) return json.loads(comm_responce)


def get_uploader() :
def get_uploader(self) :
""" """
gets current uploaders config gets current uploaders config


@@ -432,7 +468,7 @@ class Eagle(object) :
return json.loads(comm_responce) return json.loads(comm_responce)




def get_historical_data_alt(self, period="day") :
def get_historical_data(self, period="day") :
""" """
get a series of summation values over an interval of time get a series of summation values over an interval of time
( http command api ) ( http command api )
@@ -473,7 +509,7 @@ class Eagle(object) :


""" """
if period not in ['day', 'week', 'month', 'year'] : if period not in ['day', 'week', 'month', 'year'] :
raise ValueError("get_historical_data_alt period must be one of day|week|month|year")
raise ValueError("get_historical_data : period must be one of day|week|month|year")
comm_responce = self._send_http_comm("get_historical_data", Period=period) comm_responce = self._send_http_comm("get_historical_data", Period=period)
return json.loads(comm_responce) return json.loads(comm_responce)


@@ -542,7 +578,7 @@ class Eagle(object) :
return json.loads(comm_responce) return json.loads(comm_responce)


def get_remote_management(self) : def get_remote_management(self) :
return get_device_config(self)
return self.get_device_config(self)


def set_remote_management(self, macid=None, status="on") : def set_remote_management(self, macid=None, status="on") :
""" set_remote_management """ set_remote_management
@@ -738,7 +774,8 @@ class Eagle(object) :


def _send_http_comm(self, cmd, **kwargs): def _send_http_comm(self, cmd, **kwargs):


print "\n\n_send_http_comm : ", cmd
if self.debug :
print "\n\n_send_http_comm : ", cmd


commstr = "<LocalCommand>\n" commstr = "<LocalCommand>\n"
commstr += "<Name>{0!s}</Name>\n".format(cmd) commstr += "<Name>{0!s}</Name>\n".format(cmd)
@@ -747,7 +784,8 @@ class Eagle(object) :
commstr += "<{0}>{1!s}</{0}>\n".format(k, v) commstr += "<{0}>{1!s}</{0}>\n".format(k, v)
commstr += "</LocalCommand>\n" commstr += "</LocalCommand>\n"


print(commstr)
if self.debug :
print(commstr)


url = "http://{0}/cgi-bin/cgi_manager".format(self.addr) url = "http://{0}/cgi-bin/cgi_manager".format(self.addr)




+ 1
- 3
bin/gnup_poweruse.txt View File

@@ -27,16 +27,14 @@ set grid
set key off set key off
set pointsize 0.5 set pointsize 0.5


# 2014-03-09 13:24:21 24.2220 0.0970 2649.2700 0.0000
set xtics rotate set xtics rotate


set xtics 3600 set xtics 3600
set xdata time set xdata time
set timefmt "%Y-%m-%d %H:%M:%S" set timefmt "%Y-%m-%d %H:%M:%S"
set format x "%a %b %d %H:%M" set format x "%a %b %d %H:%M"
#set xrange [ "2014-03-04 00:00:00" : ]
set xrange [ "2014-03-04 00:00:00" : ]


# set xrange [ "2014-03-04 00:00:00" : ]


set style data lines set style data lines
set autoscale y set autoscale y


+ 60
- 30
bin/meter_status.py View File

@@ -2,27 +2,60 @@
""" """
A simple script get current meter values A simple script get current meter values
""" """
__author__ = "Peter Shipley"


import sys
sys.path.append('/usr/home/shipley/Projects/Eagle') # temp
__author__ = "Peter Shipley"
__version__ = "0.1.7"




# import RainEagle # import RainEagle
from RainEagle import Eagle, to_epoch_1970 from RainEagle import Eagle, to_epoch_1970
import time import time
import os
import argparse
from pprint import pprint from pprint import pprint


debug = 0 debug = 0



def create_parser():
parser = argparse.ArgumentParser(
description="print power meter status")

parser.add_argument("-a", "--address", dest="addr",
default=os.getenv('EAGLE_ADDR', None),
help="hostname or IP device")

parser.add_argument("-p", "--port", dest="port", type=int,
default=os.getenv('EAGLE_PORT', 5002),
help="command socket port")

parser.add_argument("-d", "--debug", dest="debug",
default=debug, action="count",
help="print debug info")

parser.add_argument("-m", "--mac", dest="mac",
help="Eagle radio mac addrress")

parser.add_argument("-t", "--timeout", dest="timeout",
help="Socket timeout")

parser.add_argument("-v", '--version', action='version',
version="%(prog)s {0}".format(__version__) )

return parser


def main() : def main() :
eg = Eagle( debug=debug , addr="10.1.1.39")

parser = create_parser()
args = parser.parse_args()

eg = Eagle(**vars(args))
# timeout=45, # timeout=45,


r = eg.get_device_data() r = eg.get_device_data()


print_instantdemand( r['InstantaneousDemand'])
print_instantdemand(r['InstantaneousDemand'])
print print


print_currentsummation(r['CurrentSummation']) print_currentsummation(r['CurrentSummation'])
@@ -30,12 +63,14 @@ def main() :


exit(0) exit(0)



def twos_comp(val, bits=32): def twos_comp(val, bits=32):
"""compute the 2's compliment of int value val""" """compute the 2's compliment of int value val"""
if( (val&(1<<(bits-1))) != 0 ): if( (val&(1<<(bits-1))) != 0 ):
val = val - (1<<bits)
val = val - (1<<bits)
return val return val



def print_currentsummation(cs) : def print_currentsummation(cs) :


multiplier = int(cs['Multiplier'], 16) multiplier = int(cs['Multiplier'], 16)
@@ -44,32 +79,24 @@ def print_currentsummation(cs) :
received = int(cs['SummationReceived'], 16) received = int(cs['SummationReceived'], 16)


if multiplier == 0 : if multiplier == 0 :
multiplier = 1
multiplier = 1


if divisor == 0 : if divisor == 0 :
divisor = 1
divisor = 1


reading_received = received * multiplier / float (divisor) reading_received = received * multiplier / float (divisor)
reading_delivered = delivered * multiplier / float (divisor) reading_delivered = delivered * multiplier / float (divisor)


time_stamp = to_epoch_1970(cs['TimeStamp'])
print "{0:s} : ".format(time.asctime(time.localtime(time_stamp)))
if 'TimeStamp' in cs :
time_stamp = to_epoch_1970(cs['TimeStamp'])
print "{0:s} : ".format(time.asctime(time.localtime(time_stamp)))
print "\tReceived = {0:{width}.3f} Kw".format(reading_received, width=10) print "\tReceived = {0:{width}.3f} Kw".format(reading_received, width=10)
print "\tDelivered = {0:{width}.3f} Kw".format(reading_delivered, width=10) print "\tDelivered = {0:{width}.3f} Kw".format(reading_delivered, width=10)
print "\t\t{0:{width}.3f} Kw".format( (reading_delivered - reading_received), width=14) print "\t\t{0:{width}.3f} Kw".format( (reading_delivered - reading_received), width=14)




# print "{0}\t{1:.4f}\t{2:0.4f}\t{3:.4f}".format(
# time.strftime("%Y-%m-%d %H:%M:%S", time_struct),
# reading_received,
# reading_delivered,
# (reading_delivered - reading_received) )


def print_instantdemand(idemand) : def print_instantdemand(idemand) :


time_stamp = to_epoch_1970(idemand['TimeStamp'])


multiplier = int(idemand['Multiplier'], 16) multiplier = int(idemand['Multiplier'], 16)
divisor = int(idemand['Divisor'], 16) divisor = int(idemand['Divisor'], 16)
@@ -79,27 +106,30 @@ def print_instantdemand(idemand) :
demand = int(idemand['Demand'], 16) demand = int(idemand['Demand'], 16)


if demand > 0x7FFFFFFF: if demand > 0x7FFFFFFF:
demand -= 0x100000000
demand -= 0x100000000


if multiplier == 0 : if multiplier == 0 :
multiplier = 1
multiplier = 1


if divisor == 0 : if divisor == 0 :
divisor = 1
divisor = 1


reading = (demand * multiplier) / float (divisor )
reading = (demand * multiplier) / float (divisor)

if 'TimeStamp' in idemand :
time_stamp = to_epoch_1970(idemand['TimeStamp'])
print "{0:s} : ".format(time.asctime(time.localtime(time_stamp)))


print "{0:s} : ".format(time.asctime(time.localtime(time_stamp)))
print "\tDemand = {0:{width}.3f} Kw".format(reading, width=10) print "\tDemand = {0:{width}.3f} Kw".format(reading, width=10)
print "\tAmps = {0:{width}.3f}".format( ((reading * 1000) / 240), width=10 )
print "\tAmps = {0:{width}.3f}".format( ((reading * 1000) / 240), width=10)




#
#
if __name__ == "__main__": if __name__ == "__main__":
# import __main__ # import __main__
# print(__main__.__file__)
# print("syntax ok")
# print(__main__.__file__)
# print("syntax ok")
main() main()
exit(0)
exit(0)





+ 49
- 71
bin/plot_power.py View File

@@ -2,12 +2,10 @@
""" """
A simple script to generate guuplot data from meter history A simple script to generate guuplot data from meter history
""" """
__author__ = "Peter Shipley"


__author__ = "Peter Shipley"
__version__ = "0.1.7"


import sys
sys.path.append('/usr/home/shipley/Projects/Eagle') # temp


import RainEagle import RainEagle
import time import time
@@ -22,115 +20,95 @@ max_delta_received = 0
max_delta_delivered = 0 max_delta_delivered = 0
day_delta_received = 0 day_delta_received = 0
day_delta_delivered = 0 day_delta_delivered = 0
curr_day=-1
curr_day = -1



def main(eg) : def main(eg) :
# print_header()
print_data(eg) print_data(eg)
# print_footer()
exit(0) exit(0)


def print_header() :
print """
set terminal png size 2600,500
set datafile separator "\t"
set xlabel "time"
set ylabel "power"
set grid
set key off
set pointsize 0.5
set xtics 3600
set xdata time
set timefmt "%Y-%m-%d %H:%M:%S"
set format x "%a %b %d %H:%M"
#set xrange [ "2014-03-04 00:00:00" : ]
# set xrange [ "2014-03-04 00:00:00" : "2014-03-09 17:20:00" ]
set style data lines
set autoscale y
set title "Power Use"
set output "poweruse.png"
plot "-" using 1:3 t "inbound" w lines, "-" using 1:5 t "outbound"
"""

def print_footer() :
pass


def print_data(eg) : def print_data(eg) :
rh = eg.get_history_data() rh = eg.get_history_data()
#+ # endtime=None, frequency=None ) :
#+ # endtime=None, frequency=None) :


for dat in rh['HistoryData']['CurrentSummation'] : for dat in rh['HistoryData']['CurrentSummation'] :
print_currentsummation(dat)
print_currentsummation(dat)

print "# day_delta_received={0:0.4f}\t" \
+ " day_delta_delivered={1:0.4f} : {2:0.4f}".format(
day_delta_received,
day_delta_delivered,
(day_delta_delivered - day_delta_received))
print "# max_delta_received={0:0.4f}\t" \
+ " max_delta_delivered={1:0.4f}".format(
max_delta_received, max_delta_delivered)


print "# day_delta_received={0:0.4f}\tday_delta_delivered={1:0.4f} : {2:0.4f}".format(day_delta_received, day_delta_delivered, ( day_delta_delivered - day_delta_received ) )
print "# max_delta_received={0:0.4f}\tmax_delta_delivered={1:0.4f}".format(max_delta_received, max_delta_delivered)


def print_currentsummation(cs) : def print_currentsummation(cs) :
global last_delivered global last_delivered
global last_received global last_received


global max_delta_received
global max_delta_received
global max_delta_delivered global max_delta_delivered
global day_delta_received
global day_delta_received
global day_delta_delivered global day_delta_delivered
global curr_day global curr_day


time_stamp = to_epoch_1970(cs['TimeStamp']) time_stamp = to_epoch_1970(cs['TimeStamp'])


multiplier=int(cs['Multiplier'], 16)
divisor=int(cs['Divisor'], 16)
delivered=int(cs['SummationDelivered'], 16)
received=int(cs['SummationReceived'], 16)
multiplier = int(cs['Multiplier'], 16)
divisor = int(cs['Divisor'], 16)
delivered = int(cs['SummationDelivered'], 16)
received = int(cs['SummationReceived'], 16)


# print "Multiplier=", multiplier, "Divisor=", divisor, "Demand=", demand # print "Multiplier=", multiplier, "Divisor=", divisor, "Demand=", demand
if multiplier == 0 : if multiplier == 0 :
multiplier=1
multiplier = 1


if divisor == 0 : if divisor == 0 :
divisor=1
divisor = 1


reading_received = received * multiplier / float (divisor )
reading_received = received * multiplier / float(divisor)
delta_received = (reading_received - last_received) delta_received = (reading_received - last_received)
last_received = reading_received last_received = reading_received
if ( delta_received > max_delta_received and delta_received < 1000) :
max_delta_received = delta_received
#print "new max_delta_received :", max_delta_received
if (delta_received > max_delta_received and delta_received < 1000) :
max_delta_received = delta_received
#print "new max_delta_received :", max_delta_received



reading_delivered = delivered * multiplier / float (divisor )
reading_delivered = delivered * multiplier / float(divisor)
delta_delivered = (reading_delivered - last_delivered) delta_delivered = (reading_delivered - last_delivered)
last_delivered = reading_delivered last_delivered = reading_delivered
if ( delta_delivered > max_delta_delivered and delta_delivered < 1000) :
max_delta_delivered = delta_delivered
#print "\t\tnew max_delta_delivered :", max_delta_delivered



if (delta_delivered > max_delta_delivered and delta_delivered < 1000) :
max_delta_delivered = delta_delivered
#print "\t\tnew max_delta_delivered :", max_delta_delivered


time_struct = time.localtime(time_stamp) time_struct = time.localtime(time_stamp)
if curr_day != time_struct.tm_mday :
curr_day = time_struct.tm_mday
print "# day_delta_received={0:0.4f}\tday_delta_delivered={1:0.4f} : {2:0.4f}".format(day_delta_received, day_delta_delivered, ( day_delta_delivered - day_delta_received ) )
day_delta_received = 0
day_delta_delivered = 0
if curr_day != time_struct.tm_mday :
curr_day = time_struct.tm_mday
print "# day_delta_received={0:0.4f}\tday_delta_delivered={1:0.4f}" \
+ ": {2:0.4f}".format(day_delta_received,
day_delta_delivered,
(day_delta_delivered - day_delta_received))
day_delta_received = 0
day_delta_delivered = 0


day_delta_received += delta_received day_delta_received += delta_received
day_delta_delivered += delta_delivered day_delta_delivered += delta_delivered


print "{0}\t{1:.4f}\t{2:0.4f}\t{3:.4f}\t{4:0.4f}".format( print "{0}\t{1:.4f}\t{2:0.4f}\t{3:.4f}\t{4:0.4f}".format(
time.strftime("%Y-%m-%d %H:%M:%S", time_struct),
reading_received,
delta_received,
reading_delivered,
delta_delivered)

time.strftime("%Y-%m-%d %H:%M:%S", time_struct),
reading_received,
delta_received,
reading_delivered,
delta_delivered)




if __name__ == "__main__": if __name__ == "__main__":
# import __main__ # import __main__
# print(__main__.__file__)
# print("syntax ok")
reagle = RainEagle.Eagle( debug=0 , addr="10.1.1.39")
# print(__main__.__file__)
# print("syntax ok")
reagle = RainEagle.Eagle(debug=0)
main(reagle) main(reagle)
exit(0)
exit(0)

+ 1
- 1
doc.txt View File

@@ -70,7 +70,7 @@ CLASSES
| 'gateway_ip_addr': '10.11.12.13' | 'gateway_ip_addr': '10.11.12.13'
| 'gateway_mac_id': 'D8:D5:B9:00:90:24' | 'gateway_mac_id': 'D8:D5:B9:00:90:24'
| |
| get_historical_data_alt(self, period='day')
| get_historical_data(self, period='day')
| get a series of summation values over an interval of time | get a series of summation values over an interval of time
| ( http command api ) | ( http command api )
| |


+ 1
- 1
setup.py View File

@@ -29,7 +29,7 @@ class install_scripts_and_symlinks(install_scripts):


setup( setup(
name='RainEagle', name='RainEagle',
version='0.1.6',
version='0.1.7',
author='Peter Shipley', author='Peter Shipley',
author_email='Peter.Shipley@gmail.com', author_email='Peter.Shipley@gmail.com',
packages=find_packages(), packages=find_packages(),


Loading…
Cancel
Save