├── eagle_http ├── __init__.py ├── api_classes.py ├── base_class.py └── eagle_http.py ├── .gitignore ├── setup.cfg ├── requirements.txt ├── .DS_Store ├── EAGLE_REST_API 1.0.pdf ├── MANIFEST.in ├── setup.py ├── LICENSE └── README.md /eagle_http/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /venv 2 | *.pyc 3 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | lxml==3.4.2 2 | wsgiref==0.1.2 3 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rainforestautomation/Eagle-Http-API/HEAD/.DS_Store -------------------------------------------------------------------------------- /EAGLE_REST_API 1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rainforestautomation/Eagle-Http-API/HEAD/EAGLE_REST_API 1.0.pdf -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # Include the license file 2 | include LICENSE 3 | 4 | # If using Python 2.6 or less, then have to include package data, even though 5 | # it's already declared in setup.py 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | Setup module 3 | """ 4 | 5 | from setuptools import setup, find_packages 6 | 7 | 8 | setup( 9 | name="eagle_http", 10 | version="1.0.0", 11 | author="Rainforest Automation", 12 | packages=find_packages(), 13 | setup_requires=["lxml==3.4.2","wsgiref==0.1.2"] 14 | ) 15 | -------------------------------------------------------------------------------- /eagle_http/api_classes.py: -------------------------------------------------------------------------------- 1 | from base_class import * 2 | from base_class import BaseCluster as MessageCluster 3 | from base_class import BaseCluster as TimeCluster 4 | from base_class import BaseCluster as InstantaneousDemand 5 | from base_class import BaseCluster as NetworkInfo 6 | from base_class import BaseCluster as PriceCluster 7 | from base_class import BaseCluster as DeviceInfo 8 | from base_class import BaseCluster as MessageCluster 9 | from base_class import BaseCluster as CurrentSummation 10 | from base_class import BaseCluster as ScheduleInfo 11 | from base_class import BaseCluster as BlockPriceDetail 12 | from base_class import BaseCluster as HistoryData 13 | -------------------------------------------------------------------------------- /eagle_http/base_class.py: -------------------------------------------------------------------------------- 1 | from lxml import etree 2 | from lxml import objectify 3 | import json 4 | 5 | 6 | class BaseCluster(): 7 | 8 | def __init__(self, isJson, data, block_string): 9 | self.json = isJson 10 | self.block_string = block_string 11 | self.data = block_string 12 | if isJson: 13 | self.json_init(data) 14 | else: 15 | self.xml_init(data) 16 | 17 | def json_init(self, json_obj): 18 | print json_obj 19 | for rootkey in json_obj: 20 | for key in json_obj[rootkey]: 21 | setattr(self, key, json_obj[rootkey][key]) 22 | 23 | def xml_init(self, xml): 24 | for element in xml.iterchildren(): 25 | setattr(self, element.tag, element.text) 26 | 27 | def __repr__(self): 28 | return self.data 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Rainforest Automation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /eagle_http/eagle_http.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from lxml import etree 3 | from lxml import objectify 4 | import requests 5 | import copy 6 | from api_classes import * 7 | import datetime 8 | 9 | 10 | class eagle_http(): 11 | host_local = 'eaf' 12 | host = 'https://rainforestcloud.com' 13 | port = 9445 14 | rurl = '/cgi-bin/post_manager' 15 | history = [] 16 | local = False 17 | # XML Fragment constructs 18 | command_root = etree.Element('Command') 19 | command_name = etree.Element('Name') 20 | mac_id = etree.Element('DeviceMacId') 21 | msg_id = etree.Element('Id') 22 | format_ = etree.Element('Format') 23 | history_start_time = etree.Element('StartTime') 24 | history_end_time = etree.Element('EndTime') 25 | history_frequency = etree.Element('Frequency') 26 | schedule_event = etree.Element('Event') 27 | schedule_frequency = etree.Element('Frequency') 28 | schedule_enabled = etree.Element('Enabled') 29 | target = etree.Element('Target') 30 | # command list 31 | cmd_get_network_info = "get_network_info" 32 | cmd_get_network_status = "get_network_status" 33 | cmd_get_instantaneous_demand = "get_instantaneous_demand" 34 | cmd_get_price = "get_price" 35 | cmd_get_message = "get_message" 36 | cmd_confirm_message = "confirm_message" 37 | cmd_get_current_summation = "get_current_summation" 38 | cmd_get_history_data = "get_history_data" 39 | cmd_set_schedule = "set_schedule" 40 | cmd_get_schedule = "get_schedule" 41 | noisy = True 42 | json = False 43 | 44 | def __init__(self, uname, password, cloud_id): 45 | self.user_name = uname 46 | self.user_password = password 47 | self.cloud_id = cloud_id 48 | self.construct_headers( 49 | self.cloud_id, 50 | self.user_name, 51 | self.user_password) 52 | 53 | def construct_headers(self, cloud_id, user_name, password_): 54 | self.headers = { 55 | 'Cloud-ID': str(cloud_id), 56 | 'User': str(user_name), 57 | 'Password': str(password_) 58 | } 59 | return self.headers 60 | 61 | def send(self, send_data, request_headers): 62 | requests.packages.urllib3.disable_warnings() 63 | if self.local: 64 | self.final_url = "https://" + self.user_name + ":" + \ 65 | self.user_password + "@eagle-" + self.user_name + ".local" + self.rurl 66 | print self.final_url 67 | else: 68 | self.final_url = self.host + ":" + str(self.port) + self.rurl 69 | try: 70 | self.req = requests.post( 71 | self.final_url, 72 | data=send_data, 73 | headers=request_headers, 74 | verify=False) 75 | if self.noisy: 76 | print self.final_url 77 | print send_data 78 | print self.req.text 79 | if self.json: 80 | returned_object = self.parse_json_response(self.req.text) 81 | else: 82 | returned_object = self.parse_xml_response(self.req.text) 83 | self.write_history(send_data, self.req.text, returned_object) 84 | except Exception as e: 85 | print "Exception raised: " + str(e) 86 | 87 | def parse_xml_response(self, text): 88 | try: 89 | self.xmlTree = objectify.fromstring(text) 90 | module = __import__('api_classes') 91 | # print self.xmlTree.tag 92 | class_ = getattr(module, self.xmlTree.tag) 93 | instance = class_(self.json, self.xmlTree, text) 94 | setattr(self, self.xmlTree.tag, instance) 95 | return instance 96 | except: 97 | raise 98 | 99 | def parse_json_response(self, text): 100 | module = __import__('api_classes') 101 | json_obj = json.loads(text) 102 | class_ = "" 103 | for key in json_obj: 104 | class_ = getattr(module, key) 105 | instance = class_(self.json, json_obj, text) 106 | print instance 107 | setattr(self, key, instance) 108 | return instance 109 | 110 | def write_history(self, sent, received, return_obj): 111 | history_obj = { 112 | 'time': str(datetime.datetime.now()), 113 | 'command': self.command_name.text, 114 | 'sent': sent, 115 | 'received': received, 116 | 'object': return_obj 117 | } 118 | self.history.append(history_obj) 119 | 120 | def readback(self, readback_count=100): 121 | i = 0 122 | for item in reversed(self.history): 123 | print "Item Number: " + str(i) 124 | print "Datetime: " + str(item['time']) 125 | print "Command Sent: " + str(item['command']) 126 | print "SENT --------------------------" 127 | print str(item['sent']) 128 | print "RECEIVED -----------------------" 129 | print str(item['received']) 130 | if i > readback_count: 131 | break 132 | i = i + 1 133 | 134 | def compose_root(self, command, mac_id): 135 | command_base = copy.copy(self.command_root) 136 | self.command_name.text = command 137 | command_base.append(self.command_name) 138 | if mac_id is not None: 139 | self.mac_id.text = mac_id 140 | command_base.append(self.mac_id) 141 | if self.json == True: 142 | print "json" 143 | self.format_.text = 'JSON' 144 | command_base.append(self.format_) 145 | return command_base 146 | 147 | def get_network_info(self, mac_id=None): 148 | self.command = self.compose_root(self.cmd_get_network_info, mac_id) 149 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 150 | self.send(self.xml_fragment, self.headers) 151 | 152 | def get_network_status(self, mac_id=None): 153 | self.command = self.compose_root(self.cmd_get_network_status, mac_id) 154 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 155 | self.send(self.xml_fragment, self.headers) 156 | 157 | def get_instantaneous_demand(self, mac_id=None): 158 | self.command = self.compose_root( 159 | self.cmd_get_instantaneous_demand, mac_id) 160 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 161 | self.send(self.xml_fragment, self.headers) 162 | 163 | def get_price(self, mac_id=None): 164 | self.command = self.compose_root(self.cmd_get_price, mac_id) 165 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 166 | self.send(self.xml_fragment, self.headers) 167 | 168 | def get_message(self, mac_id=None): 169 | self.command = self.compose_root(self.cmd_get_message, mac_id) 170 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 171 | self.send(self.xml_fragment, self.headers) 172 | 173 | def confirm_message(self, message_id, mac_id=None): 174 | self.command = self.compose_root(self.cmd_confirm_message, mac_id) 175 | self.msg_id.text = message_id 176 | self.command.append(self.msg_id) 177 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 178 | self.send(self.xml_fragment, self.headers) 179 | 180 | def get_current_summation(self, mac_id=None): 181 | self.command = self.compose_root( 182 | self.cmd_get_current_summation, mac_id) 183 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 184 | self.send(self.xml_fragment, self.headers) 185 | 186 | def get_history_data(self, start_time, end_time=None, 187 | frequency=None, mac_id=None): 188 | self.command = self.compose_root(self.cmd_get_history_data, mac_id) 189 | self.command.append(self.history_start_time) 190 | self.history_start_time.text = start_time 191 | if end_time is not None: 192 | self.history_end_time.text = end_time 193 | self.command.append(self.history_end_time) 194 | if frequency is not None: 195 | self.history_frequency.text = frequency 196 | self.command.append(self.history_frequency) 197 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 198 | self.send(self.xml_fragment, self.headers) 199 | 200 | def set_schedule(self, event, frequency, enabled, mac_id=None): 201 | # event could be demand, summation,message,scheduled_prices, price, 202 | # billing_period,block_period,profile_data 203 | self.command = self.compose_root(self.cmd_set_schedule, mac_id) 204 | self.command.append(self.history_start_time) 205 | self.schedule_event.text = event 206 | self.schedule_frequency.text = frequency 207 | self.schedule_enabled.text = enabled 208 | self.command.append(self.schedule_event) 209 | self.command.append(self.schedule_frequency) 210 | self.command.append(self.schedule_enabled) 211 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 212 | self.send(self.xml_fragment, self.headers) 213 | 214 | def get_schedule(self, event, mac_id=None): 215 | self.command = self.compose_root(self.cmd_get_schedule, mac_id) 216 | self.schedule_event.text = event 217 | self.command.append(self.schedule_event) 218 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 219 | self.send(self.xml_fragment, self.headers) 220 | 221 | def reboot(self, target, mac_id=None): 222 | self.command = self.compose_root(self.cmd_get_network_info, mac_id) 223 | self.target.text = target 224 | self.command.append(self.target) 225 | self.xml_fragment = etree.tostring(self.command, pretty_print=True) 226 | self.send(self.xml_fragment, self.headers) 227 | 228 | 229 | if __name__ == '__main__': 230 | instance = eagle_http('001226', '94496e6dcf06b7d1', 'cloud_id') 231 | instance.local = True 232 | instance.get_network_info() 233 | instance.get_network_status() 234 | instance.get_instantaneous_demand() 235 | instance.get_price() 236 | instance.get_message() 237 | instance.confirm_message('0xFF') 238 | instance.get_history_data('0x1c91d800', '0x1c91d87d') 239 | instance.set_schedule('demand', '0x000a', 'Y') 240 | instance.get_schedule('demand') 241 | instance.json = True 242 | instance.get_network_info() 243 | instance.get_network_status() 244 | instance.get_instantaneous_demand() 245 | instance.get_price() 246 | instance.get_message() 247 | instance.confirm_message('0xFF') 248 | instance.get_history_data('0x1c91d800', '0x1c91d87d') 249 | instance.set_schedule('demand', '0x000a', 'Y') 250 | instance.get_schedule('demand') 251 | instance.readback(100) 252 | print instance.NetworkInfo 253 | print instance.NetworkInfo.DeviceMacId 254 | print instance.history[0]['command'] 255 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2015-04-20 Chrome Browser Extension Released! 2 | 3 | ![alt tag](https://lh3.googleusercontent.com/-BGEkB6ghmKoZfKBUjj_i0jpYQEoeYy_ApB4Yoweeg5hbkTGdC0ZxznTYkgiMCyse4Bd8cLOow=s640-h400-e365) 4 | 5 | A new chrome extension has been released which allows you to view your energy usage by simply looking at an icon in your browser. To tryi it out, go here: 6 | 7 | https://chrome.google.com/webstore/detail/rainforest-automation-eag/jogodcnmpmgfihdjebbnbmpcmolipioi 8 | 9 | 10 | # EAGLE-HTTP-API 11 | 12 | The Rainforest Automation Eagle is a energy monitoring unit which allows you to monitor your home's power condumption in real time by connecting to your smart meter through Zigbee. 13 | 14 | You can purchase an Eagle through the Amazon store (please ensure your house is connected with a smart meter and your utility support HAN registration). 15 | http://www.amazon.com/Rainforest-EAGLE-Ethernet-ZigBee-Gateway/dp/B00AII248U 16 | 17 | This API is a Python library which allows you to easily query and configure your device through a HTTP relay server with the credentials you create at rainforestcloud.com 18 | 19 | Example usage: 20 | 21 | > python 22 | > from eagle_http import * 23 | > eagle = eagle_http('your user name', 'your password', 'your cloud_id') 24 | > eagle.get_instantaneous_demand() 25 | https://rainforestcloud.com:9445/cgi-bin/post_manager 26 | 27 | get_instantaneous_demand 28 | 29 | 30 | 31 | 0xd8d5b90000002aeb 32 | 0x000781000081fd17 33 | 0x1c91ec39 34 | 0x0003b0 35 | 0x00000001 36 | 0x000003e8 37 | 0x03 38 | 0x06 39 | Y 40 | 41 | 42 | 43 | The returned XML is parsed and placed into the instance as a attribute: 44 | 45 | > eagle.InstantaneousDemand 46 | 47 | 0xd8d5b90000002aeb 48 | 0x000781000081fd17 49 | 0x1c91ec39 50 | 0x0003b0 51 | 0x00000001 52 | 0x000003e8 53 | 0x03 54 | 0x06 55 | Y 56 | 57 | 58 | 59 | Individual attributes of the reponse can also easily be accessed: 60 | 61 | > eagle.InstantaneousDemand.Demand 62 | 0x0003b0 63 | 64 | Just as easy as that. 65 | # Prerequisites 66 | 67 | In order to use this API you need: 68 | 69 | * A Rainforest Automation Eagle running 2.20 or greater firmware 70 | * An account from https://www.rainforestcloud.com with the target eagle added 71 | * A computer with Python installed 72 | 73 | # Installation 74 | 75 | Installation is straight forward, and the preqreqs are lxml and requests 76 | 77 | > pip install eagle_http 78 | 79 | Good to go! 80 | 81 | 82 | #List Of Commands: 83 | 84 | * eagle = eagle_http('your user name', 'your password', 'your cloud_id') 85 | 86 | Instantiates the eagle_http object (fill in your details) 87 | 88 | * eagle.get_network_info([mac_id]) 89 | * mac_id - (Optional) is intended for eagles with multiple zigbee radios 90 | 91 | Returns network info details of eagle. 92 | 93 | 94 | 0xd8d5b90000002aeb 95 | 0x94496e6dcf06b7d1 96 | 0x4aecc18d050a0527 97 | 0x2b8caac18554435f 98 | 1.4.48 (6952) 99 | 1.2.5 100 | Rainforest Automation, Inc. 101 | Z109-EAGLE 102 | 2014051823520701 103 | 0x1301 104 | Zigbee 105 | 106 | 107 | json: 108 | 109 | { 110 | "NetworkInfo": { 111 | "DeviceMacId": "0xd8d5b90000002aeb", 112 | "InstallCode": "0x94496e6dcf06b7d1", 113 | "LinkKeyHigh": "0x4aecc18d050a0527", 114 | "LinkKeyLow": "0x2b8caac18554435f", 115 | "FWVersion": "1.4.48 (6952)", 116 | "HWVersion": "1.2.5", 117 | "Manufacturer": "Rainforest Automation, Inc.", 118 | "ModelId": "Z109-EAGLE", 119 | "DateCode": "2014051823520701", 120 | "ImageType": "0x1301", 121 | "Protocol": "Zigbee"} 122 | } 123 | 124 | You can access the returned data attributes like so: 125 | 126 | > eagle.NetworkInfo.Status 127 | Connected 128 | 129 | * eagle.get_network_status([mac_id]) 130 | * mac_id - (Optional) is intended for eagles with multiple zigbee radios 131 | 132 | Returns network Status of Eagle 133 | 134 | 135 | 0xd8d5b90000002aeb 136 | Connected 137 | 0x000781000081fd17 138 | 0x000781000081fd17 139 | 0x8644 140 | 18 141 | 0x64 142 | Zigbee 143 | 144 | 145 | json: 146 | 147 | { 148 | "NetworkInfo": { 149 | "DeviceMacId": "0xd8d5b90000002aeb", 150 | "Status": "Connected", 151 | "CoordMacId": "0x000781000081fd17", 152 | "ExtPanId": "0x000781000081fd17", 153 | "ShortAddr": "0x8644", 154 | "Channel": "18", 155 | "LinkStrength": "0x64", 156 | "Protocol": "Zigbee"} 157 | } 158 | 159 | Which can be accessed like: 160 | 161 | >eagle.NetworkInfo.Status 162 | Connected 163 | 164 | * eagle.get_instantaneous_demand([mac_id]) 165 | * mac_id - (Optional) is intended for eagles with multiple zigbee radios 166 | 167 | Returns instantaneous demand from eagle 168 | 169 | 170 | 0xd8d5b90000002aeb 171 | 0x000781000081fd17 172 | 0x1c91ec39 173 | 0x0003b0 174 | 0x00000001 175 | 0x000003e8 176 | 0x03 177 | 0x06 178 | Y 179 | 180 | 181 | json: 182 | 183 | { 184 | "InstantaneousDemand": { 185 | "DeviceMacId": "0xd8d5b90000002aeb", 186 | "MeterMacId": "0x000781000081fd17", 187 | "TimeStamp": "0x1c9347b8", 188 | "Demand": "0x0003b0", 189 | "Multiplier": "0x00000001", 190 | "Divisor": "0x000003e8", 191 | "DigitsRight": "0x03", 192 | "DigitsLeft": "0x06", 193 | "SuppressLeadingZero": "Y"} 194 | } 195 | 196 | Which can be accessed like: 197 | 198 | >eagle.InstantaneousDemand.Demand 199 | 0x0003b0 200 | 201 | * eagle.get_price([mac_id]) 202 | * mac_id - (Optional) is intended for eagles with multiple zigbee radios 203 | 204 | Returns price cluster from Eagle: 205 | 206 | 207 | 0xd8d5b90000002aeb 208 | 0x000781000081fd17 209 | 0x1c91ec36 210 | 0x1c91ec3e 211 | 0xffff 212 | 0x0000000a 213 | 0x03d2 214 | 0x02 215 | 1 216 | Price1 217 | 218 | 219 | json: 220 | 221 | { 222 | "PriceCluster": { 223 | "DeviceMacId": "0xd8d5b90000002aeb", 224 | "MeterMacId": "0x000781000081fd17", 225 | "TimeStamp": "0x1c9347ab", 226 | "StartTime": "0x1c9347bb", 227 | "Duration": "0xffff", 228 | "Price": "0x0000000a", 229 | "Currency": "0x03d2", 230 | "TrailingDigits": "0x02", 231 | "Tier": "1", 232 | "RateLabel": "Price1"} 233 | } 234 | 235 | 236 | 237 | Which can be accessed like: 238 | 239 | >eagle.PriceCluster.Price 240 | 0x0000000a 241 | 242 | * eagle.get_message([mac_id]) 243 | * * mac_id - (Optional) is intended for eagles with multiple zigbee radios 244 | 245 | Returns message cluster from Eagle: 246 | 247 | 248 | 0xd8d5b90000002aeb 249 | 0x000781000081fd17 250 | 0x00000000 251 | 0x00000000 252 | 0x0000 253 | 0x00000000 254 | N 255 | N 256 | Y 257 | active 258 | 259 | 260 | Which can be accessed like: 261 | 262 | >eagle.MessageCluster.TimeStamp 263 | 0x00000000 264 | 265 | * eagle.confirm_message(message_id, [mac_id]) 266 | * message_id - 0x00-0xff message id number (stringified) 267 | * mac_id - (Optional) is intended for eagles with multiple zigbee radios 268 | 269 | Returns message cluster from Eagle: 270 | 271 | 272 | 0xd8d5b90000002aeb 273 | 0x000781000081fd17 274 | 0x00000000 275 | 0x00000000 276 | 0x0000 277 | 0x00000000 278 | N 279 | N 280 | Y 281 | active 282 | 283 | 284 | 285 | json: 286 | 287 | { 288 | "MessageCluster": { 289 | "DeviceMacId": "0xd8d5b90000002aeb", 290 | "MeterMacId": "0x000781000081fd17", 291 | "TimeStamp": "0x00000000", 292 | "StartTime": "0x00000000", 293 | "Duration": "0x0000", 294 | "Id": "0x00000000", 295 | "ConfirmationRequired": "N", 296 | "Confirmed": "N", 297 | "Read": "Y", 298 | "Queue": "active"} 299 | } 300 | Which can be accessed like: 301 | 302 | >eagle.MessageCluster.TimeStamp 303 | 0x00000000 304 | 305 | 306 | * eagle.get_history_data(start_time,[end_time, mac_id) 307 | * start_time - 0x00000000 - current time (zigbee time, seconds from Jan 1, 2000 UTC) 308 | * end_time - 0x00000000 - current time (zigbee time, seconds from Jan 1, 2000 UTC) 309 | * mac_id - (Optional) is intended for eagles with multiple zigbee radios 310 | 311 | Not currently working 312 | 313 | eagle.set_schedule('demand', '0x000a', 'Y') 314 | 315 | * eagle.set_schedule(event,frequency, enabled, [mac_id]) 316 | * event - how often eagle queries for one of : demand, summation,message,scheduled_prices, price, billing_period,block_period,profile_data 317 | * frequency - 0x0000- 0xffff time in seconds for a query 318 | * enabled - Y or N - whether query is enabled 319 | * mac_id - (Optional) is intended for eagles with multiple zigbee radios 320 | 321 | No response will come back. 322 | 323 | * eagle.get_schedule(event,frequency, enabled, [mac_id]) 324 | * event - how often eagle queries for one of : demand, summation,message,scheduled_prices, price, billing_period,block_period,profile_data 325 | * mac_id - (Optional) is intended for eagles with multiple zigbee radios 326 | 327 | Returns ScheduleInfo from Eagle: 328 | 329 | 330 | 0x0000000000000000 331 | 0x0000000000000000 332 | demand 333 | 10 334 | 335 | 336 | json: 337 | 338 | { 339 | "ScheduleInfo": { 340 | "DeviceMacId": "0x0000000000000000", 341 | "MeterMacId": "0x0000000000000000", 342 | "Event": "demand", 343 | "Frequency": "10"} 344 | } 345 | 346 | Which can be accessed like: 347 | 348 | >eagle.ScheduleInfo.Frequency 349 | 10 350 | 351 | ## Getting Raw XML Data 352 | 353 | This api was designed so you do not need to directly access the xml or json data, but can access instance variables instead. If you would like direct access to XML fragments returned from the HTTP API, you can simply: 354 | 355 | * Ensure instance.json = False 356 | * Make a request 357 | * Read the Instance object directly 358 | 359 | Example: 360 | 361 | > instance.get_network_info() 362 | > instance.NetworkInfo 363 | 364 | 0xd8d5b90000002aeb 365 | 0x94496e6dcf06b7d1 366 | 0x4aecc18d050a0527 367 | 0x2b8caac18554435f 368 | 1.4.48 (6952) 369 | 1.2.5 370 | Rainforest Automation, Inc. 371 | Z109-EAGLE 372 | 2014051823520701 373 | 0x1301 374 | Zigbee 375 | 376 | 377 | ## Getting Raw JSON Data 378 | 379 | Similarly, and most usefully for most pythonistas, to get the raw data in JSON you would: 380 | 381 | * Ensure instance.json = True 382 | * Make a request 383 | * Read the Instance object directly 384 | 385 | Example: 386 | 387 | > instance.json = True 388 | > instance.get_network_info() 389 | { 390 | "NetworkInfo": { 391 | "DeviceMacId": "0xd8d5b90000002aeb", 392 | "Status": "Connected", 393 | "CoordMacId": "0x000781000081fd17", 394 | "ExtPanId": "0x000781000081fd17", 395 | "ShortAddr": "0x8644", 396 | "Channel": "18", 397 | "LinkStrength": "0x64", 398 | "Protocol": "Zigbee"} 399 | } 400 | 401 | 402 | ##Telling the API to Quiet down 403 | The Eagle-Http-API is by default pretty noisy on the command line. To quiet it down: 404 | 405 | eagle.noisy = False 406 | 407 | The eagle-http object also keeps track of the send/receive history in found in eagle.history list 408 | 409 | Objects look like this: 410 | 411 | history_obj = { 412 | 'time':str(datetime.datetime.now()), 413 | 'command':self.command_name.text, 414 | 'sent_xml':sent_xml, 415 | 'recv_xml':recv_xml, 416 | 'obj':return_obj 417 | } 418 | 419 | 420 | You can access the returned objects like so: 421 | 422 | > eagle.history[0]['command'] 423 | get_network_info 424 | 425 | 426 | If you are using this tool interactively, you can use: 427 | 428 | eagle.readback(1) 429 | 430 | Item Number: 8 431 | Datetime: 2015-03-10 10:56:28.858187 432 | Command Sent: get_network_info 433 | SENT XML -------------------------- 434 | 435 | get_network_info 436 | 437 | 438 | RECEIVED XML----------------------- 439 | 440 | 0xd8d5b90000002aeb 441 | 0x94496e6dcf06b7d1 442 | 0x4aecc18d050a0527 443 | 0x2b8caac18554435f 444 | 1.4.48 (6952) 445 | 1.2.5 446 | Rainforest Automation, Inc. 447 | Z109-EAGLE 448 | 2014051823520701 449 | 0x1301 450 | Zigbee 451 | 452 | 453 | 454 | 0xd8d5b90000002aeb 455 | Connected 456 | 0x000781000081fd17 457 | 0x000781000081fd17 458 | 0x8644 459 | 18 460 | 0x64 461 | Zigbee 462 | 463 | 464 | 465 | Where the arg is a integer, and will pretty print the outgoing request and response 466 | 467 | # Commit Details 468 | 469 | - March 11th 2015 (1.1) - Added Support for JSON, 470 | Adhered to DRY wrt api_classes (now using aliases) 471 | Updated documentarion to reflect JSON changes 472 | 473 | - March 10th, 2015 (1.0) - Initial Commit 474 | 475 | 476 | # Issues 477 | 478 | The maintainer of this repo can be contacted at john dot lee at rainforestautomation dot com. Feel free to create issues if the api does something unexpected 479 | --------------------------------------------------------------------------------