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