2 # UCC Door Server - hardware interface server
3 # reads status of reed switches and provides a D-BUS interface to read them
6 # Released under an MIT-style license; see COPYING for details.
8 # statuses: 1 means open circuit, 0 means closed circuit, -1 means error
10 import dbus, dbus.service
12 from LATClient import LATClient
13 from select import select
15 def check_LAT_service(servicename, retries=3):
16 latclient = LATClient(service=servicename.upper())
17 rfh, wfh = latclient.get_fh()
18 results = {'error': retries, 'closed': retries, 'open': retries}
19 test_string = "got wombles?"
21 # Only return after n(retries) consistent results, although not necessarily
22 # in order. This means we poll at least (retries) and up to (retries ** 2) times.
23 # This is mtearle's original code. No idea if it's the Right Thing.
26 wfh.write(test_string)
30 if results['error'] == 0: return -1
32 rr, wr, er = select([rfh], [], [], 3.0)
35 if results['open'] == 0: return 1
37 recv = rfh.read(len(test_string))
38 if recv <> test_string:
40 if results['error'] == 0: return -1
42 results['closed'] -= 1
43 if results['closed'] == 0: return 0
45 class Door(dbus.service.Object):
47 def __init__(self, doorname, bus):
48 self.interval = 10 # seconds
49 self.service = doorname
52 if 'pir' in self.service:
55 # set up D-BUS service name
56 object_path = '/au/asn/ucc/doors/%s' % doorname
57 dbus.service.Object.__init__(self, bus, object_path)
64 newstatus = check_LAT_service(self.service, self.retries)
68 if newstatus != self.status:
69 self.status = newstatus
71 self.status_changed(newstatus)
73 # set up timeout again
74 gobject.timeout_add_seconds(self.interval, self.poll)
76 @dbus.service.signal('au.asn.ucc.DoorInterface', signature='n')
77 def status_changed(self, newstatus):
80 @dbus.service.method('au.asn.ucc.DoorInterface', in_signature='',
85 if __name__ == '__main__':
86 doors = ('uccdoor', 'unisfadoor', 'chdoor', 'mrdoor', 'uccpir')
88 from dbus.mainloop.glib import DBusGMainLoop
89 DBusGMainLoop(set_as_default=True)
91 system_bus = dbus.SystemBus()
92 system_bus.request_name('au.asn.ucc.DoorServer')
97 door_objects.append(Door(door, system_bus))
100 loop = gobject.MainLoop()
103 except KeyboardInterrupt: