1190
|
1 #!bin/python
|
|
2
|
|
3 """
|
|
4 sample supervisord block
|
|
5
|
|
6 [program:dpms_9095]
|
|
7 directory=/my/proj/homeauto/service/dpms
|
|
8 command=/my/proj/homeauto/service/dpms/bin/python dpms.py
|
|
9 user=drewp
|
|
10
|
|
11 On one box, this goes super slow when avahi daemon is running. Maybe
|
|
12 it's for an attempted dns lookup of the requesting IP address, which I
|
|
13 wish I could switch off.
|
|
14
|
|
15 --
|
|
16
|
|
17 may need this:
|
|
18 ps axf | grep /run/gdm
|
|
19 18339 tty7 Ss+ 0:00 \_ /usr/bin/X :0 -background none -verbose -auth /run/gdm/auth-for-gdm-iQoCDZ/database -nolisten tcp vt7
|
|
20 eval xauth add `sudo xauth -f /run/gdm/auth-for-gdm-iQoCDZ/database list :0`
|
|
21
|
|
22 """
|
|
23
|
|
24 from twisted.internet import reactor, task
|
|
25 import cyclone.web
|
|
26 from influxdb import InfluxDBClient
|
|
27 import subprocess, sys, socket, time, os
|
|
28 from rdflib import Namespace, URIRef
|
1267
|
29 from logsetup import log, enableTwistedLog
|
|
30
|
|
31 from dpms import DPMS, DPMSModeOn
|
1190
|
32 DEV = Namespace("http://projects.bigasterisk.com/device/")
|
|
33 ROOM = Namespace("http://projects.bigasterisk.com/room/")
|
|
34
|
|
35 sys.path.append("/my/site/magma")
|
1267
|
36 from patchablegraph import PatchableGraph, CycloneGraphEventsHandler, CycloneGraphHandler
|
|
37 #sys.path.append("../../lib")
|
|
38 #from localdisplay import setDisplayToLocalX
|
1190
|
39
|
|
40 influx = InfluxDBClient('bang6', 9060, 'root', 'root', 'main')
|
|
41
|
1267
|
42 os.environ['DISPLAY'] = ':0.0'
|
|
43
|
|
44 dpms = DPMS()
|
|
45 host = socket.gethostname()
|
|
46
|
1190
|
47 def getMonitorState():
|
1267
|
48 level, enabled = dpms.Info()
|
|
49 return 'on' if level == DPMSModeOn else 'off'
|
1190
|
50
|
|
51 class Root(cyclone.web.RequestHandler):
|
|
52 def get(self):
|
|
53 getMonitorState() # to make it fail if xset isn't working
|
|
54 self.write('''
|
|
55 Get and put the <a href="monitor">monitor power</a> with dpms.
|
|
56 <a href="graph">rdf graph</a> available.''')
|
|
57
|
|
58 class Monitor(cyclone.web.RequestHandler):
|
|
59 def get(self):
|
|
60 self.set_header('content-type', 'text/plain')
|
|
61 self.write(getMonitorState())
|
|
62
|
|
63 def put(self):
|
|
64 body = self.request.body.strip()
|
|
65 if body in ['on', 'off']:
|
|
66 subprocess.check_call(['xset', 'dpms', 'force', body])
|
|
67 self.set_status(204)
|
|
68 else:
|
|
69 raise NotImplementedError("body must be 'on' or 'off'")
|
|
70
|
|
71 class Poller(object):
|
|
72 def __init__(self):
|
|
73 self.lastSent = None
|
|
74 self.lastSentTime = 0
|
|
75 task.LoopingCall(self.poll).start(5)
|
|
76
|
|
77 def poll(self):
|
|
78 now = int(time.time())
|
1267
|
79 state = getMonitorState()
|
|
80
|
|
81 ctx=DEV['dpms/%s' % host]
|
|
82 masterGraph.patchObject(
|
|
83 ctx,
|
|
84 URIRef("http://bigasterisk.com/host/%s/monitor" % host),
|
|
85 ROOM['powerStateMeasured'],
|
|
86 ROOM[getMonitorState()])
|
|
87
|
1190
|
88 if state != self.lastSent or (now > self.lastSentTime + 3600):
|
|
89 influx.write_points([
|
|
90 {'measurement': 'power',
|
1267
|
91 'tags': {'device': '%sMonitor' % host},
|
1190
|
92 'fields': {'value': 1 if state == 'on' else 0},
|
|
93 'time': now
|
|
94 }], time_precision='s')
|
|
95
|
|
96 self.lastSent = state
|
|
97 self.lastSentTime = now
|
|
98
|
1267
|
99 masterGraph = PatchableGraph()
|
1190
|
100 poller = Poller()
|
|
101
|
|
102 reactor.listenTCP(9095, cyclone.web.Application([
|
|
103 (r'/', Root),
|
|
104 (r'/monitor', Monitor),
|
1267
|
105 (r'/graph', CycloneGraphHandler, {'masterGraph': masterGraph}),
|
|
106 (r'/graph/events', CycloneGraphEventsHandler, {'masterGraph': masterGraph}),
|
1190
|
107 ]), interface='::')
|
|
108
|
|
109 reactor.run()
|
|
110
|
|
111
|