Mercurial > code > home > repos > homeauto
comparison service/dpms/dpms_service.py @ 464:1007ca70c34d
use PatchableGraph
Ignore-this: dc954906750062923ef8205f8a8e8952
author | drewp@bigasterisk.com |
---|---|
date | Sat, 20 Apr 2019 23:38:56 -0700 |
parents | 6c5303b85948 |
children | a93fbf0d0daa |
comparison
equal
deleted
inserted
replaced
463:1ceb26846eca | 464:1007ca70c34d |
---|---|
24 from twisted.internet import reactor, task | 24 from twisted.internet import reactor, task |
25 import cyclone.web | 25 import cyclone.web |
26 from influxdb import InfluxDBClient | 26 from influxdb import InfluxDBClient |
27 import subprocess, sys, socket, time, os | 27 import subprocess, sys, socket, time, os |
28 from rdflib import Namespace, URIRef | 28 from rdflib import Namespace, URIRef |
29 from logsetup import log, enableTwistedLog | |
30 | |
31 from dpms import DPMS, DPMSModeOn | |
29 DEV = Namespace("http://projects.bigasterisk.com/device/") | 32 DEV = Namespace("http://projects.bigasterisk.com/device/") |
30 ROOM = Namespace("http://projects.bigasterisk.com/room/") | 33 ROOM = Namespace("http://projects.bigasterisk.com/room/") |
31 | 34 |
32 sys.path.append("/my/site/magma") | 35 sys.path.append("/my/site/magma") |
33 from stategraph import StateGraph | 36 from patchablegraph import PatchableGraph, CycloneGraphEventsHandler, CycloneGraphHandler |
34 sys.path.append("../../lib") | 37 #sys.path.append("../../lib") |
35 from localdisplay import setDisplayToLocalX | 38 #from localdisplay import setDisplayToLocalX |
36 | 39 |
37 influx = InfluxDBClient('bang6', 9060, 'root', 'root', 'main') | 40 influx = InfluxDBClient('bang6', 9060, 'root', 'root', 'main') |
38 | 41 |
42 os.environ['DISPLAY'] = ':0.0' | |
43 | |
44 dpms = DPMS() | |
45 host = socket.gethostname() | |
46 | |
39 def getMonitorState(): | 47 def getMonitorState(): |
40 out = subprocess.check_output(['xset', 'q']) | 48 level, enabled = dpms.Info() |
41 for line in out.splitlines(): | 49 return 'on' if level == DPMSModeOn else 'off' |
42 line = line.strip() | |
43 if line == 'Monitor is On': | |
44 return 'on' | |
45 elif line in ['Monitor is Off', 'Monitor is in Suspend', 'Monitor is in Standby']: | |
46 return 'off' | |
47 raise NotImplementedError("no matching monitor line in xset output") | |
48 | 50 |
49 class Root(cyclone.web.RequestHandler): | 51 class Root(cyclone.web.RequestHandler): |
50 def get(self): | 52 def get(self): |
51 getMonitorState() # to make it fail if xset isn't working | 53 getMonitorState() # to make it fail if xset isn't working |
52 self.write(''' | 54 self.write(''' |
64 subprocess.check_call(['xset', 'dpms', 'force', body]) | 66 subprocess.check_call(['xset', 'dpms', 'force', body]) |
65 self.set_status(204) | 67 self.set_status(204) |
66 else: | 68 else: |
67 raise NotImplementedError("body must be 'on' or 'off'") | 69 raise NotImplementedError("body must be 'on' or 'off'") |
68 | 70 |
69 | |
70 class Graph(cyclone.web.RequestHandler): | |
71 def get(self): | |
72 host = socket.gethostname() | |
73 g = StateGraph(ctx=DEV['dpms/%s' % host]) | |
74 g.add((URIRef("http://bigasterisk.com/host/%s/monitor" % host), | |
75 ROOM['powerStateMeasured'], | |
76 ROOM[getMonitorState()])) | |
77 | |
78 self.set_header('Content-type', 'application/x-trig') | |
79 self.write(g.asTrig()) | |
80 | |
81 | |
82 class Poller(object): | 71 class Poller(object): |
83 def __init__(self): | 72 def __init__(self): |
84 self.lastSent = None | 73 self.lastSent = None |
85 self.lastSentTime = 0 | 74 self.lastSentTime = 0 |
86 task.LoopingCall(self.poll).start(5) | 75 task.LoopingCall(self.poll).start(5) |
87 | 76 |
88 def poll(self): | 77 def poll(self): |
89 now = int(time.time()) | 78 now = int(time.time()) |
90 try: | 79 state = getMonitorState() |
91 state = getMonitorState() | 80 |
92 except subprocess.CalledProcessError, e: | 81 ctx=DEV['dpms/%s' % host] |
93 print repr(e) | 82 masterGraph.patchObject( |
94 os.abort() | 83 ctx, |
84 URIRef("http://bigasterisk.com/host/%s/monitor" % host), | |
85 ROOM['powerStateMeasured'], | |
86 ROOM[getMonitorState()]) | |
87 | |
95 if state != self.lastSent or (now > self.lastSentTime + 3600): | 88 if state != self.lastSent or (now > self.lastSentTime + 3600): |
96 influx.write_points([ | 89 influx.write_points([ |
97 {'measurement': 'power', | 90 {'measurement': 'power', |
98 'tags': {'device': '%sMonitor' % socket.gethostname()}, | 91 'tags': {'device': '%sMonitor' % host}, |
99 'fields': {'value': 1 if state == 'on' else 0}, | 92 'fields': {'value': 1 if state == 'on' else 0}, |
100 'time': now | 93 'time': now |
101 }], time_precision='s') | 94 }], time_precision='s') |
102 | 95 |
103 self.lastSent = state | 96 self.lastSent = state |
104 self.lastSentTime = now | 97 self.lastSentTime = now |
105 | 98 |
106 setDisplayToLocalX() | 99 masterGraph = PatchableGraph() |
107 poller = Poller() | 100 poller = Poller() |
108 | 101 |
109 reactor.listenTCP(9095, cyclone.web.Application([ | 102 reactor.listenTCP(9095, cyclone.web.Application([ |
110 (r'/', Root), | 103 (r'/', Root), |
111 (r'/monitor', Monitor), | 104 (r'/monitor', Monitor), |
112 (r'/graph', Graph), | 105 (r'/graph', CycloneGraphHandler, {'masterGraph': masterGraph}), |
106 (r'/graph/events', CycloneGraphEventsHandler, {'masterGraph': masterGraph}), | |
113 ]), interface='::') | 107 ]), interface='::') |
114 | 108 |
115 reactor.run() | 109 reactor.run() |
116 | 110 |
117 | 111 |