changeset 317:629cd8c36831

rewrite to cyclone. sends data to influx Ignore-this: 1c842a1ddee0a0601497ff54121baaeb
author drewp@bigasterisk.com
date Mon, 16 Jan 2017 16:54:10 -0800
parents 02d9915b3bbb
children 33883457d1c2
files service/dpms/dpms.py
diffstat 1 files changed, 68 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/service/dpms/dpms.py	Fri Nov 25 17:56:26 2016 -0800
+++ b/service/dpms/dpms.py	Mon Jan 16 16:54:10 2017 -0800
@@ -21,8 +21,10 @@
 
 """
 
-from bottle import run, get, put, request, response
-import subprocess, sys, socket
+from twisted.internet import reactor, task
+import cyclone.web
+from influxdb import InfluxDBClient
+import subprocess, sys, socket, time, os
 from rdflib import Namespace, URIRef
 DEV = Namespace("http://projects.bigasterisk.com/device/")
 ROOM = Namespace("http://projects.bigasterisk.com/room/")
@@ -32,51 +34,84 @@
 sys.path.append("../../lib")
 from localdisplay import setDisplayToLocalX
 
+influx = InfluxDBClient('bang6', 9060, 'root', 'root', 'main')
+
 def getMonitorState():
     out = subprocess.check_output(['xset', 'q'])
     for line in out.splitlines():
         line = line.strip()
         if line == 'Monitor is On':
-            response.set_header('content-type', 'text/plain')
             return 'on'
         elif line in ['Monitor is Off', 'Monitor is in Suspend', 'Monitor is in Standby']:
-            response.set_header('content-type', 'text/plain')
             return 'off'
     raise NotImplementedError("no matching monitor line in xset output")
 
-@get("/")
-def index():
-    getMonitorState() # to make it fail if xset isn't working
-    return '''
-      Get and put the <a href="monitor">monitor power</a> with dpms.
-      <a href="graph">rdf graph</a> available.'''
+class Root(cyclone.web.RequestHandler):
+    def get(self):
+        getMonitorState() # to make it fail if xset isn't working
+        self.write('''
+          Get and put the <a href="monitor">monitor power</a> with dpms.
+          <a href="graph">rdf graph</a> available.''')
     
-@get("/monitor")
-def monitor():
-    return getMonitorState()
+class Monitor(cyclone.web.RequestHandler):
+    def get(self):
+        self.set_header('content-type', 'text/plain')
+        self.write(getMonitorState())
+        
+    def put(self):
+        body = self.request.body.strip()
+        if body in ['on', 'off']:
+            subprocess.check_call(['xset', 'dpms', 'force', body])
+            self.set_status(204)
+        else:
+            raise NotImplementedError("body must be 'on' or 'off'")
+
 
-@put("/monitor")
-def putMonitor():
-    body = request.body.read().strip()
-    if body in ['on', 'off']:
-        subprocess.check_call(['xset', 'dpms', 'force', body])
-        response.status = 204
-    else:
-        raise NotImplementedError("body must be 'on' or 'off'")
-    return ''
+class Graph(cyclone.web.RequestHandler):
+    def get(self):
+        host = socket.gethostname()
+        g = StateGraph(ctx=DEV['dpms/%s' % host])
+        g.add((URIRef("http://bigasterisk.com/host/%s/monitor" % host),
+               ROOM['powerStateMeasured'],
+               ROOM[getMonitorState()]))
+
+        self.set_header('Content-type', 'application/x-trig')
+        self.write(g.asTrig())
+
 
-@get("/graph")
-def graph():
-    host = socket.gethostname()
-    g = StateGraph(ctx=DEV['dpms/%s' % host])
-    g.add((URIRef("http://bigasterisk.com/host/%s/monitor" % host),
-           ROOM['powerStateMeasured'],
-           ROOM[getMonitorState()]))
-    
-    response.set_header('Content-type', 'application/x-trig')
-    return g.asTrig()
+class Poller(object):
+    def __init__(self):
+        self.lastSent = None
+        self.lastSentTime = 0
+        task.LoopingCall(self.poll).start(5)
+        
+    def poll(self):
+        now = int(time.time())
+        try:
+            state = getMonitorState()
+        except subprocess.CalledProcessError, e:
+            print repr(e)
+            os.abort()
+        if state != self.lastSent or (now > self.lastSentTime + 3600):
+            influx.write_points([
+                {'measurement': 'power',
+                 'tags': {'device': '%sMonitor' % socket.gethostname()},
+                 'fields': {'value': 1 if state == 'on' else 0},
+                 'time': now
+                 }], time_precision='s')
+            
+            self.lastSent = state
+            self.lastSentTime = now
 
 setDisplayToLocalX()
+poller = Poller()
+            
+reactor.listenTCP(9095, cyclone.web.Application([
+    (r'/', Root),
+    (r'/monitor', Monitor),
+    (r'/graph', Graph),
+]), interface='::')
 
-run(host="[::]", server='gunicorn', port=9095, quiet=True)
+reactor.run()
 
+