diff --git a/README.md b/README.md
index a7379d8..b168117 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,14 @@
Python Class for utilizing the Rainforest Automation Eagle ( RFA-Z109 ) socket API
- *** This is just skeleton so far ***
+ import import RainEagle
+
+ raineagle = RainEagle.Eagle( debug=0 , addr="10.1.1.39")
+ ret_data = eg.list_devices()
+
+ print "device MacID = ", ret_data['DeviceInfo']['DeviceMacId']
+
+
Rainforest Automation Documentation
diff --git a/RainEagle/EagleClass.py b/RainEagle/EagleClass.py
index 639a2a2..34f0704 100644
--- a/RainEagle/EagleClass.py
+++ b/RainEagle/EagleClass.py
@@ -5,10 +5,15 @@ import os
import time
import xml.etree.ElementTree as ET
+from pprint import pprint
+
+
+
__all__ = ['Eagle']
def et2d(et) :
+
""" Etree to Dict
converts an ETree to a Dict Tree
@@ -55,7 +60,17 @@ def et2d(et) :
#
# Simple Base class for ISY Class
class Eagle(object) :
+ """
+ Class for talking to Rainforest Automation EAGLE (RFA-Z109)
+ args:
+ debug print debug messages if true
+ addr address of device
+ port port on device (default 5002)
+ getmac connect to device at start up and get macid (default true)
+
+ Currently there is very little error handling ( if any at all )
+ """
def __init__(self, **kwargs):
self.debug = kwargs.get("debug", 0)
@@ -63,143 +78,71 @@ class Eagle(object) :
print self.__class__.__name__, __name__
self.addr = kwargs.get("addr", os.getenv('EAGLE_ADDR', None))
self.port = kwargs.get("port", os.getenv('EAGLE_PORT', 5002))
+ self.getmac = kwargs.get("getmac", True)
self.soc = None
+ self.macid = None
+ # preload
+ if self.getmac :
+ self.device_info = self.list_devices()
+ if self.debug :
+ pprint(self.device_info)
+ # self.macid = self.device_info['DeviceInfo']['DeviceMacId']
+ if self.debug :
+ print "DeviceMacId = ", self.macid
- def connect(self) :
- self.soc = socket.create_connection( (self.addr, self.port), 10)
-
-# self.soc_rf = self.soc.makefile("rb")
-# self.soc_wf = self.soc.makefile("wb")
-
- def disconnect(self):
-
-# try :
-# if self.soc_rf :
-# self.soc_rf.close()
-# self.soc_rf = False
-# except IOError :
-# pass
-#
-# try :
-# if self.soc_wf :
-# self.soc_wf.close()
-# self.soc_wf = False
-# except IOError :
-# pass
-#
- try :
- if self.soc :
- self.soc_sock.close()
- self.soc_sock = False
- except IOError :
- pass
-
- def _reconnect(self):
- self.disconnect()
- self.connect()
-
-
- def _send_comm(self, cmd, **kwargs):
- commstr = "\r\n "
- commstr += "{0!s}\r\n".format(cmd)
- for k, v in kwargs.items() :
- commstr += "<{0}>{1!s}{0}>\r\n".format(k, v)
- commstr += "\r\n"
-
-#+ self.soc.send(commstr)
- print "commstr : ", commstr
-
-# self.soc_wf.write(commstr)
-# self.soc_wf.flush()
-
-#+ time.sleep(1)
-
- replystr = ""
-#+ while 1 :
-#+ buf = self.soc.recv(1000)
-#+ if not buf:
-#+ break
-#+ replystr += buf
-
- return replystr
-
# commands as class funtions
def list_devices(self):
comm_responce = self._send_comm("list_devices")
- # temp debug data
- comm_responce = "" \
- " 0xd8d5b90000000xxx" \
- " 0x9ac4382dffa81xxx" \
- " 7e572b66c5b444xxx" \
- " 94227dca4e773xxx" \
- " 1.4.27 (5278)" \
- " 1.2.3" \
- " Rainforest Automation, I" \
- " RFA-Z109 EAGLE" \
- " 20130308PO020621" \
- "\n"
-
+ if self.debug :
+ print "comm_responce =", comm_responce
etree = ET.fromstring('' + comm_responce + '' )
rv = et2d(etree)
+ if self.macid == None :
+ self.macid = rv['DeviceInfo']['DeviceMacId']
return rv
# 3
- def get_device_data(self, macid) :
+ def get_device_data(self, macid=None) :
""" Send the GET_DEVICE_DATA command to get a data dump """
+ if macid == None :
+ macid = self.macid
comm_responce = self._send_comm("get_device_data", MacId=macid)
- # temp debug data
- comm_responce = "" \
- " 0xd8d5b90000000xxx" \
- " Rejoining" \
- " 0x001350030011bxxx" \
- " 0x7fffffffffffffff" \
- " 0x0000ffff" \
- " 24" \
- " 156" \
- "" \
- "" \
- " 0xd8d5b90000000xxx" \
- " 0x9ac4382dffa81xxx" \
- " 7e572b66c5b44xxx" \
- " 94227dca4e773xxx" \
- " 1.4.27 (5278)" \
- " 1.2.3" \
- " Rainforest Automation, I" \
- " RFA-Z109 EAGLE" \
- " 20130308PO020621" \
- "" \
- "" \
- " 0xd8d5b90000000xxx" \
- " 0x001350030011bxxx" \
- " 0x00000bf1" \
- " 0x195193e3" \
- " 0x00000001" \
- " 0x000003e8" \
- " 0x00000003" \
- " 0x0000000f" \
- " 0x0001" \
- ""
-
etree = ET.fromstring('' + comm_responce + '' )
rv = et2d(etree)
return rv
# 10
- def get_instantaneous_demand(self, macid, interval) :
- """ Send the GET_INSTANTANEOUS_DEMAND command to get the real time demand from the meter"""
+ def get_instantaneous_demand(self, macid=None) :
+ """ Send the GET_INSTANTANEOUS_DEMAND command
+ get the real time demand from the meter
+
+ args:
+ MacId 16 hex digits, MAC addr of EAGLE ZigBee radio
+ """
+ if macid == None :
+ macid = self.macid
comm_responce = self._send_comm("get_instantaneous_demand",
- MacId=macid, Interval=interval)
+ MacId=macid)
etree = ET.fromstring('' + comm_responce + '' )
rv = et2d(etree)
return rv
# 11
- def get_demand_values(self, macid, interval, frequency=None ) :
- """ Send the GET_DEMAND_VALUES command to get a series of instantaneous demand values"""
+ def get_demand_values(self, macid=None, interval="hour", frequency=None ) :
+ """ Send the GET_DEMAND_VALUES command
+ get a series of instantaneous demand values
+
+ args:
+ MacId 16 hex digits, MAC addr of EAGLE ZigBee radio
+ Interval hour | day | week
+ [Frequency] int seconds between samples
+ """
+ if macid == None :
+ macid = self.macid
kwargs = {"MacId": macid, "Interval": interval}
if frequency :
kwargs["Frequency"] = frequency
@@ -209,8 +152,16 @@ class Eagle(object) :
return rv
# 12
- def get_summation_values(self, macid, interval) :
- """ Send the GET_SUMMATION_VALUES command to get a series of net summation values """
+ def get_summation_values(self, macid=None, interval="day") :
+ """ Send the GET_SUMMATION_VALUES command
+ get a series of net summation values
+
+ args:
+ MacId 16 hex digits, MAC addr of EAGLE ZigBee radio
+ Interval day | week | month | year
+ """
+ if macid == None :
+ macid = self.macid
comm_responce = self._send_comm("get_summation_values",
MacId=macid, Interval=interval )
etree = ET.fromstring('' + comm_responce + '' )
@@ -218,8 +169,22 @@ class Eagle(object) :
return rv
# 14
- def set_fast_poll(self, macid, frequency, duration) :
- """ set the fast poll mode on the meter. """
+ def set_fast_poll(self, macid=None, frequency="0x04", duration="0xFF") :
+ """ Send the SET_FAST_POLL command
+ set the fast poll mode on the meter
+
+ args:
+ MacId 16 hex digits, MAC addr of EAGLE ZigBee radio
+ Frequency 0x01 - 0xFF Freq to poll meter, in seconds
+ Duration 0x00 - 0x0F Duration of fast poll mode, in minutes (max 15)
+ """
+ if macid == None :
+ macid = self.macid
+ if isinstance(frequency, int) :
+ frequency = "{:#04x}".format(m)
+ if isinstance(duration, int) :
+ frequency = "{:#04x}".format(m)
+
comm_responce = self._send_comm("get_instantaneous_demand",
MacId=macid, Frequency=frequency, Duration=duration)
etree = ET.fromstring('' + comm_responce + '' )
@@ -227,8 +192,15 @@ class Eagle(object) :
return rv
# 15
- def get_fast_poll_status(self, macid) :
- """ get the current status of fast poll mode. """
+ def get_fast_poll_status(self, macid=None) :
+ """ Send the GET_FAST_POLL_STATUS command
+ get the current status of fast poll mode.
+
+ args:
+ MacId 16 hex digits, MAC addr of EAGLE ZigBee radio
+ """
+ if macid == None :
+ macid = self.macid
comm_responce = self._send_comm("get_fast_poll_status", MacId=macid)
etree = ET.fromstring('' + comm_responce + '' )
rv = et2d(etree)
@@ -236,8 +208,12 @@ class Eagle(object) :
# 17
- def get_history_data(self, macid, starttime, endtime=None, frequency=None ) :
- """ get a series of summation values over an interval of time """
+ def get_history_data(self, macid=None, starttime="0x00000000", endtime=None, frequency=None ) :
+ """ Send the GET_HISTORY_DATA command
+ get a series of summation values over an interval of time
+ """
+ if macid == None :
+ macid = self.macid
kwargs = {"MacId": macid, "StartTime": starttime}
if endtime :
kwargs["EndTime"] = endtime
@@ -248,6 +224,61 @@ class Eagle(object) :
rv = et2d(etree)
return rv
+
+ # Support functions
+
+ def connect(self) :
+ self.soc = socket.create_connection( (self.addr, self.port), 10)
+
+ def disconnect(self):
+ try :
+ if self.soc :
+ self.soc.close()
+ self.soc = False
+ except IOError :
+ pass
+
+
+ def _send_comm(self, cmd, **kwargs):
+
+ if cmd == "set_fast_poll" :
+ command_tag = "RavenCommand"
+ else :
+ command_tag = "LocalCommand"
+
+ commstr = "<{0}>\n ".format(command_tag)
+ commstr += "{0!s}\n".format(cmd)
+ for k, v in kwargs.items() :
+ commstr += "<{0}>{1!s}{0}>\n".format(k, v)
+ commstr += "{0}>\n".format(command_tag)
+
+ self.connect()
+ self.soc.sendall(commstr)
+ if self.debug :
+ print "commstr : \n", commstr
+
+ # time.sleep(1)
+
+ replystr = ""
+ while 1 :
+ buf = self.soc.recv(1000)
+ if not buf:
+ break
+ replystr += buf
+
+ self.disconnect()
+ return replystr
+
+ def to_unix_time(self, t) :
+ """ converts time stored as
+ offset in seconds from "Jan 1 00:00:00 2000"
+ to unix's epoch of 1970
+ """
+ if isinstance(t, (int, long, float) ) :
+ return t + 946684800
+ if isinstance(t, str) and t.startswith('0x') :
+ return 946684800 + int(t, 16)
+
# Do nothing
# (syntax check)
#
diff --git a/RainEagle/__init__.py b/RainEagle/__init__.py
index a2a1671..34337b7 100644
--- a/RainEagle/__init__.py
+++ b/RainEagle/__init__.py
@@ -2,21 +2,29 @@
"""
+
import sys
if sys.hexversion < 0x20703f0 :
sys.stderr.write("You need python 2.7 or later to run this script\n")
+__revision__ = "$Id: 20140301 $"
+__version__ = '0.1.20140301'
+__author__ = 'Peter Shipley '
+__copyright__ = "Copyright (C) 2014 Peter Shipley"
+__license__ = "BSD"
+
-from RainEagle.EagleClass import Eagle
+from EagleClass import Eagle
+#from RainEagle.EagleClass import Eagle
__all__ = ['Eagle']
if __name__ == "__main__":
- import __main__
+ #import __main__
#print(__main__.__file___)
- print("ISY.__init__")
+ print("RainEagle.__init__")
print("syntax ok")
exit(0)
diff --git a/test.py b/test.py
index fa8b870..e30329c 100644
--- a/test.py
+++ b/test.py
@@ -1,12 +1,56 @@
import RainEagle
+import time
from pprint import pprint
+def too_unix_time(t) :
+ """ converts time stored as
+ offset in seconds from "Jan 1 00:00:00 2000"
+ to unix's epoch of 1970
+ """
+ if isinstance(t, (int, long, float) ) :
+ return t + 946684800
+ if isinstance(t, str) and t.startswith('0x') :
+ return 946684800 + int(t, 16)
-eg = RainEagle.Eagle( debug=1 )
+eg = RainEagle.Eagle( debug=0 , addr="10.1.1.39")
+
+
+print "\nlist_devices :"
r = eg.list_devices()
pprint(r)
-r = eg.get_device_data("EE:24:01:05:50:23")
+# print "\nget_device_data :"
+# r = eg.get_device_data()
+# pprint(r)
+# time_stamp_str=r['InstantaneousDemand']['TimeStamp']
+# time_stamp = eg.to_unix_time(time_stamp_str)
+# print "time = ", time.asctime(time.localtime(time_stamp))
+
+
+print "\nget_instantaneous_demand :"
+r = eg.get_instantaneous_demand()
+pprint(r)
+
+
+print "\nget_demand_values :"
+r = eg.get_demand_values(eg.macid, interval="hour")
pprint(r)
+
+print "\nget_summation_values :"
+r = eg.get_summation_values(eg.macid, interval="day")
+pprint(r)
+
+# set_fast_poll(self, macid=None, frequency, duration) :
+
+
+print "\nget_fast_poll_status :"
+r = eg.get_fast_poll_status(eg.macid)
+pprint(r)
+
+etime = eg.to_unix_time( r['FastPollStatus']['EndTime'])
+print "EndTime = ", time.asctime(time.localtime(etime))
+
+# def get_history_data(self, macid=None, starttime,
+# endtime=None, frequency=None ) :