327
|
1 #!/usr/bin/env python
|
|
2
|
|
3 # Read lirc output, in order to sense key presses on an IR remote.
|
|
4 # There are various Python packages that claim to do this but
|
|
5 # they tend to require elaborate setup and I couldn't get any to work.
|
|
6 # This approach requires a lircd.conf but does not require a lircrc.
|
|
7 # If irw works, then in theory, this should too.
|
|
8 # Based on irw.c, https://github.com/aldebaran/lirc/blob/master/tools/irw.c
|
|
9
|
|
10
|
|
11 import socket
|
|
12 import logging
|
|
13 import requests
|
|
14 from rdflib import Graph, Namespace
|
|
15
|
|
16 ROOM = Namespace("http://projects.bigasterisk.com/room/")
|
|
17 SOCKPATH = "/var/run/lirc/lircd"
|
|
18
|
|
19 logging.basicConfig(level=logging.INFO)
|
|
20 log = logging.getLogger()
|
|
21
|
|
22 class Listener:
|
|
23 def __init__(self):
|
|
24 self.lastKey = None, None
|
|
25 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
26 log.info('starting up on %s', SOCKPATH)
|
|
27 self.sock.connect(SOCKPATH)
|
|
28
|
|
29 def run(self):
|
|
30 while True:
|
|
31 keyname, updown = self.next_key()
|
|
32 log.debug('%r (%r)', keyname, updown)
|
|
33 if self.lastKey[0] is None or (
|
|
34 keyname == self.lastKey[0] and
|
|
35 updown < self.lastKey[1]):
|
|
36 g = Graph()
|
|
37 g.add((ROOM['remoteButton/%s' % keyname],
|
|
38 ROOM['state'],
|
|
39 ROOM['press']))
|
|
40 nt = g.serialize(format='n3')
|
|
41 resp = requests.post('http://bang6:9071/oneShot', headers={
|
|
42 'Content-Type': 'text/n3',
|
|
43 'user-agent': 'irRemote',
|
|
44 }, data=nt)
|
|
45 log.info('new press: %r', keyname)
|
|
46 if resp.status_code != 200:
|
|
47 log.warning('reasoning responded with %s. %r',
|
|
48 resp.status_code, resp.__dict__)
|
|
49 self.lastKey = keyname, updown
|
|
50
|
|
51 def next_key(self):
|
|
52 '''Get the next key pressed. Return keyname, updown.
|
|
53 '''
|
|
54 while True:
|
|
55 data = self.sock.recv(128)
|
|
56 # print("Data: " + data)
|
|
57 data = data.strip()
|
|
58 if data:
|
|
59 break
|
|
60
|
|
61 words = data.split()
|
|
62 try:
|
|
63 return words[2].decode('ascii'), int(words[1], 16)
|
|
64 except:
|
|
65 log.warning('failed on %r', data)
|
|
66 raise
|
|
67
|
|
68 if __name__ == '__main__':
|
|
69 Listener().run()
|
|
70
|
|
71
|