diff service/powerEagle/reader.py @ 1335:013af6808aca

update powereagle to py3, be a server with /stats/, save 'price' field Ignore-this: 1b738295b503fb7409311ddd637b7a18 darcs-hash:8965d44bb93751bd5639768f8cd1defa15ab1dab
author drewp <drewp@bigasterisk.com>
date Tue, 23 Apr 2019 03:57:55 -0700
parents bff11263c71e
children a93fbf0d0daa
line wrap: on
line diff
--- a/service/powerEagle/reader.py	Tue Apr 23 02:56:07 2019 -0700
+++ b/service/powerEagle/reader.py	Tue Apr 23 03:57:55 2019 -0700
@@ -1,42 +1,53 @@
 #!bin/python
-import json, logging, time, os
-import sys
-sys.path.append("/my/proj/homeauto/lib")
-from logsetup import log
+import json, time, os, binascii, traceback
+
+from cyclone.httpclient import fetch
+from docopt import docopt
+from greplin import scales
+from greplin.scales.cyclonehandler import StatsHandler
+from influxdb import InfluxDBClient
+from twisted.internet import reactor
 from twisted.internet.defer import inlineCallbacks
-from twisted.internet import reactor
-from cyclone.httpclient import fetch
-from influxdb import InfluxDBClient
+import cyclone.web
+
+from standardservice.logsetup import log, verboseLogging
 
 from private_config import deviceIp, cloudId, installId, macId, periodSec
 
-auth = (cloudId + ':' + installId).encode('base64').strip()
-influx = InfluxDBClient('bang', 9060, 'root', 'root', 'main')
+STATS = scales.collection('/root',
+                          scales.PmfStat('poll'),
+                          )
+
+authPlain = cloudId + ':' + installId
+auth = binascii.b2a_base64(authPlain.encode('ascii')).strip(b'=\n')
 
 class Poller(object):
-    def __init__(self, carbon):
-        self.carbon = carbon
+    def __init__(self, influx):
+        self.influx = influx
         reactor.callLater(0, self.poll)
 
+    @STATS.poll.time()
     @inlineCallbacks
     def poll(self):
         ret = None
         startTime = time.time()
         try:
+            url = (f'http://{deviceIp}/cgi-bin/cgi_manager').encode('ascii')
             resp = yield fetch(
-                'http://{deviceIp}/cgi-bin/cgi_manager'.format(deviceIp=deviceIp),
-                method='POST',
-                headers={'Authorization': ['Basic %s' % auth]},
-                postdata='''<LocalCommand>
+                url,
+                method=b'POST',
+                headers={b'Authorization': [b'Basic %s' % auth]},
+                postdata=(f'''<LocalCommand>
                               <Name>get_usage_data</Name>
                               <MacId>0x{macId}</MacId>
                             </LocalCommand>
                             <LocalCommand>
                               <Name>get_price_blocks</Name>
                               <MacId>0x{macId}</MacId>
-                            </LocalCommand>'''.format(macId=macId),
+                            </LocalCommand>''').encode('ascii'),
                 timeout=10)
             ret = json.loads(resp.body)
+            log.debug(ret)
             if ret['demand_units'] != 'kW':
                 raise ValueError
             if ret['summation_units'] != 'kWh':
@@ -49,12 +60,21 @@
             sd = float(ret['summation_delivered'])
             if sd > 0: # Sometimes nan
                 pts.append(dict(measurement='housePowerSumDeliveredKwh',
-                     fields=dict(value=float()),
-                     tags=dict(house='berkeley'),
-                     time=int(startTime)))
+                                fields=dict(value=float()),
+                                tags=dict(house='berkeley'),
+                                time=int(startTime)))
+            if 'price' in ret:
+                pts.append(dict(
+                    measurement='price',
+                    fields=dict(price=float(ret['price']),
+                                price_units=float(ret['price_units'])),
+                    tags=dict(house='berkeley'),
+                    time=int(startTime),
+                ))
                    
-            influx.write_points(pts, time_precision='s')
+            self.influx.write_points(pts, time_precision='s')
         except Exception as e:
+            traceback.print_exc()
             log.error("failed: %r", e)
             log.error(repr(ret))
             os.abort()
@@ -64,8 +84,23 @@
         reactor.callLater(max(1, goal - now), self.poll)
 
 
-log.setLevel(logging.INFO)
-influx = InfluxDBClient('bang', 9060, 'root', 'root', 'main')
+if __name__ == '__main__':
+    arg = docopt("""
+    Usage: reader.py [options]
+
+    -v           Verbose
+    --port PORT  Serve on port [default: 10016].
+    """)
+    verboseLogging(arg['-v'])
 
-p = Poller(influx)
-reactor.run()
+    influx = InfluxDBClient('bang', 9060, 'root', 'root', 'main')
+    p = Poller(influx)
+
+    reactor.listenTCP(
+        int(arg['--port']),
+        cyclone.web.Application(
+            [
+                (r'/stats/(.*)', StatsHandler, {'serverName': 'powerEagle'}),
+            ],
+        ))
+    reactor.run()