f5c8b1ae41465864c867342f7735c565cb5157e3
[~helmut/onoff.git] / dbus_service.py
1 #!/usr/bin/env python
2 """
3 A dbus service example currently providing a device called redshift, that runs
4 redshift whenever it is not activated. This could be useful to temporarily
5 disable redshift e.g. while watching a movie.
6 """
7
8 import logging
9
10 import dbus
11 import dbus.service
12 from dbus.mainloop.glib import DBusGMainLoop
13 from gi.repository import GObject
14
15 import onoff.common
16 import onoff.dbusutils
17 import onoff.process
18
19 logger = logging.getLogger("dbus_service")
20
21 class OnoffControl(dbus.service.Object):
22     domain = "de.subdivi.onoff0"
23     path = onoff.dbusutils.object_prefix
24
25     def __init__(self, bus, name, device):
26         busname = dbus.service.BusName(self.domain, bus=bus)
27         dbus.service.Object.__init__(self, busname, "%s/%s" % (self.path, name))
28         self.device = device
29         device.notify.add(self.changestate)
30         self.usecount = 0
31
32     @dbus.service.signal(domain, signature="q")
33     def changestate(self, st):
34         logger.debug("emitting state %d", st)
35
36     @dbus.service.method(domain, out_signature="q")
37     def state(self):
38         return self.device.state
39
40     @dbus.service.method(domain, in_signature="q", out_signature="q")
41     def activatetime(self, duration):
42         logger.info("activatetime %d", duration)
43         GObject.timeout_add(duration * 1000, self.unuse)
44         return self.use()
45
46     @dbus.service.method(domain, in_signature="q", out_signature="qh")
47     def activatefd(self, duration):
48         logger.info("activatefd duration %d", duration)
49         notifyfd, retfd = onoff.dbusutils.socketpair()
50         def callback(fd, _):
51             logger.info("fd %d completed", fd.fileno())
52             fd.close()
53             GObject.timeout_add(duration * 1000, self.unuse)
54             return False
55         GObject.io_add_watch(notifyfd, GObject.IO_HUP|GObject.IO_ERR, callback)
56         return (self.use(), retfd)
57
58     def use(self):
59         self.usecount += 1
60         if self.usecount <= 1:
61             self.device.activate()
62         return self.device.state
63
64     def unuse(self):
65         self.usecount -= 1
66         if not self.usecount:
67             self.device.deactivate()
68         else:
69             logger.debug("%d users left", self.usecount)
70         return False
71
72
73 def main():
74     logging.basicConfig()
75     logging.getLogger().setLevel(logging.DEBUG)
76     DBusGMainLoop(set_as_default=True)
77     bus = dbus.SessionBus()
78     dev = onoff.process.OnoffProcess(["redshift"], 3)
79     dev = onoff.common.InvertedDevice(dev)
80     OnoffControl(bus, "redshift", dev)
81     GObject.MainLoop().run()
82
83 if __name__ == "__main__":
84     main()