Package sparked :: Module monitors
[hide private]
[frames] | no frames]

Source Code for Module sparked.monitors

  1  # Copyright (c) 2010 Arjan Scherpenisse 
  2  # See LICENSE for details. 
  3  # -*- test-case-name: sparked.test.test_monitors -*- 
  4   
  5  """ 
  6  Classes for monitoring the system's state. 
  7  """ 
  8   
  9  from twisted.application import service 
 10  from twisted.internet import reactor 
 11  from twisted.python import log 
 12   
 13  from sparked.hardware import power, network 
 14  from sparked.internet import zeroconf 
 15  from sparked import events 
 16   
 17   
 18   
19 -class MonitorContainer (service.MultiService):
20 """ 21 A container for monitoring services. 22 23 @ivar monitors: A list of L{Monitor} objects. 24 @ivar events: An L{events.EventDispatcher} which triggers an "updated" event when one of the monitors state changes. 25 """ 26 27 monitors = None 28 events = None 29 verbose = False 30
31 - def __init__(self):
32 service.MultiService.__init__(self) 33 self.events = events.EventDispatcher() 34 self.monitors = []
35 36
37 - def startService(self):
38 service.MultiService.startService(self) 39 reactor.callLater(0, self.update)
40 41
42 - def addMonitor(self, monitor):
43 """ 44 Add a monitor to the container, and notify that the monitor has changed. 45 """ 46 self.monitors.append(monitor) 47 monitor.added(self) 48 self.update()
49 50
51 - def removeMonitor(self, monitor):
52 """ 53 Remove a monitor from the container 54 """ 55 i = self.monitors.index(monitor) 56 self.monitors[i].removed(self) 57 del self.monitors[i] 58 self.update()
59 60
61 - def update(self):
62 """ 63 Notify the container that monitor state has been changed or the monitors have been modified. 64 """ 65 self.events.dispatch("updated", self) 66 if self.verbose: 67 log.msg("= STATUS =====================") 68 for m in self.monitors: 69 if m.ok: 70 stat = "ok" 71 else: 72 stat = "FAIL" 73 log.msg("%-26s%4s" % (m.title, stat)) 74 log.msg("==============================")
75 76
77 - def ok(self):
78 for m in self.monitors: 79 if not m.ok: return False 80 return True
81 82
83 -class Monitor(object):
84 """ 85 A generic monitor 86 87 @ivar ok: Boolean flag which tells if the monitor's state is 'ok' or not. 88 """ 89 90 ok = False 91
92 - def added(self, container):
93 """ 94 Called when monitor is added to container. The container can 95 be used to hook services to. 96 """ 97 pass
98
99 - def removed(self, container):
100 """ 101 Called when monitor is removed from container. The container can 102 be used to hook services to. 103 """ 104 pass
105 106 107
108 -class PowerMonitor (Monitor):
109 title = "Computer power" 110
111 - def added(self, container):
112 self.container = container 113 self.svc = power.PowerService() 114 self.svc.setServiceParent(container) 115 power.powerEvents.addObserver("available", self.powerEvent)
116 117
118 - def removed(self):
119 self.svc.disownServiceParent()
120 121
122 - def powerEvent(self, available):
123 if available != self.ok: 124 self.ok = available 125 self.container.update()
126 127 128
129 -class NetworkMonitor(Monitor):
130 title = "Network connection" 131
132 - def added(self, container):
133 self.container = container 134 self.svc = network.NetworkConnectionService() 135 self.svc.setServiceParent(container) 136 network.networkEvents.addObserver("connected", self.event)
137 138
139 - def removed(self):
140 self.svc.disownServiceParent()
141 142
143 - def event(self, connected):
144 if connected != self.ok: 145 self.ok = connected 146 self.container.update()
147 148 149
150 -class NetworkWebMonitor(Monitor):
151 title = "Internet connection" 152
153 - def added(self, container):
154 self.container = container 155 self.svc = network.NetworkWebConnectionService() 156 self.svc.setServiceParent(container) 157 network.networkEvents.addObserver("web-connected", self.event)
158 159
160 - def removed(self):
161 self.svc.disownServiceParent()
162 163
164 - def event(self, connected):
165 if connected != self.ok: 166 self.ok = connected 167 self.container.update()
168 169 170
171 -class NamedZeroconfMonitor(Monitor):
172 """ 173 Monitor which is 'ok' when it has detected a service with given 174 type and name. 175 176 @ivar type: The service type that needs to be matched. E.g. C{_daap._tcp}. 177 @ivar name: The service name that needs to be matched. E.g. C{Arjan's Music}. 178 """ 179
180 - def __init__(self, name, type):
181 self.name = name 182 self.title = name 183 self.type = type
184 185
186 - def added(self, container):
187 self.container = container 188 zeroconf.zeroconfService.subscribeTo(self.type) 189 zeroconf.zeroconfEvents.addObserver("service-found", self._found) 190 zeroconf.zeroconfEvents.addObserver("service-lost", self._lost)
191 192
193 - def _found(self, name, **kw):
194 if kw['type'] == self.type and name == self.name: 195 self.ok = True 196 self.container.update()
197 198
199 - def _lost(self, name, **kw):
200 if kw['type'] == self.type and name == self.name: 201 self.ok = False 202 self.container.update()
203