Hi guys,
lirc definitely doesn't work out of the box and if you get it to work it
generates to much key events on one key press. I was a little fed up with it so
I created a fix for lirc_input.py which adds the tweakebility of delay and
repeat to elisa again. I guess some of you would code a little bit different,
but it's hack and it works for me.
regards,
Stephan Roolvink
> Date: Tue, 9 Sep 2008 20:20:29 +0200
> From: [EMAIL PROTECTED]
> To: [email protected]
> Subject: Re: [Elisa] Lirc & AC3 passthrough
>
> Matthias Saou wrote:
> > Ola Thoresen wrote :
> >
> >> Lirc works 'out of the box' for me - Fedora 9, gnome and Elisa 5.8.
> >
> > 'Out of the box'!? Where the heck did you get the below file from?
> > I definitely can't find it in my 'box' nor in the elisa sources! :-)
>
>
>
> That's why I said 'out of the box' (in quotes).
> I think that file was generated by the script you found.
>
> What I ment was that I did not have to play around with .lircrc or
> /etc/lircd.conf (after I got my remote working with
> gnome-lirc-properties in the first place).
>
>
> > So if I understand correctly, elisa short circuits the ~/.lircrc file?
> > Does anyone know the reason for this? Be able to some day integrate the
> > configuration utility into the UI? (then not have to overwrite
> > ~/.lircrc nor do any ugly parsing of that file)
>
> They now have standardized the key-names.
> For fedora, there is already a lot of nice lircd.conf-files with the
> correct names added.
> See http://fedoraproject.org/wiki/Features/BetterLIRCSupport
>
> And work is underway upstream to fix this everywhere:
> http://thread.gmane.org/gmane.comp.hardware.lirc/6884
>
> This makes it much easier for apps like Elisa to just bypass .lircrc and
> use the names directly in the code.
>
> KEY_MUTE should be the mute-key on all remotes, KEY_VOL_UP is volume up
> and so on, so there is no need for another abstraction layer for each
> user any more.
>
> So I agree that it is not completely out of the box yet, but I think
> we're getting there.
>
>
>
> Rgds.
>
> Ola (T)
>
>
>
> --
> _,--', _._.--._____
> .--.--';_'-.', ';_ _.,-' Ola Thoresen
> .'--'. _.' {`'-;_ .-.>.'
> '-:_ ) / `' '=. It is easier to fix Unix
> ) > {_/, /~) than to live with Windows
> |/ `^ .'
>
_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/# -*- coding: utf-8 -*-
#
# The LIRC Plugin for elisa
#
# Copyright (C) 2008 by Benjamin Kampmann <[EMAIL PROTECTED]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author: Benjamin Kampmann <[EMAIL PROTECTED]>
if __name__ == '__main__':
# import and install the glib2reactor is the first thing today in case we
# execute directly
from twisted.internet import glib2reactor
glib2reactor.install()
from twisted.protocols.basic import LineReceiver
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet.unix import Client
from elisa.core.components.input_provider import PushInputProvider
from elisa.core.input_event import InputEvent, EventValue, \
EventSource, EventType
from twisted.internet import reactor, defer
import os
import pkg_resources
import threading
import time
class NoMappingsFound(Exception):
"""
Raised when the mappings file is not found or if it is empty.
"""
class CallbackProtocol(LineReceiver):
delimiter = "\n"
def __init__(self, callback):
self.callback = callback
def lineReceived(self, line):
args = line.split()
self.callback(*args)
class CallbackConnector(ClientFactory):
def __init__(self, callback, lostback = None):
self.callback = callback
self.lostback = lostback
def buildProtocol(self, addr):
return CallbackProtocol(self.callback)
def connectionLost(self, *args):
if self.lostback:
self.lostback()
class LircInput(PushInputProvider):
default_config = {'input_map' : 'streamzap.map',
'device' : '/dev/lircd',
'repeat' : '1',
'delay' : '0.15'}
config_doc = {'input_map' : 'Path to the file containing the lirc' \
'mapping', 'device' : 'the lirc deamon device'\
'repeat', 'number' : 'number of imput event to ignore after initial event'\
'delay', 'seconds' : 'seconds of delay between events'}
repeat_timer = None
repeat_interval = False
repeatc = 1
delay = 0.15
def __init__(self):
super(LircInput, self).__init__()
self.mappings = {}
self._client = None
def initialize(self):
dfr = super(LircInput, self).initialize()
def initialized(result):
input_map_file = self.config.get('input_map')
self.repeatc = self.config.get('repeat')
self.delay = self.config.get('delay')
filename = os.path.basename(input_map_file)
data = ""
if not os.path.isabs(input_map_file):
# let's try to use lirc config shipped with the plugin
path = "map_files/%s" % filename
if pkg_resources.resource_exists(self.__module__, path):
lirc_config = pkg_resources.resource_filename(self.__module__,
path)
self.info("Using %s lirc map file", lirc_config)
data = open(lirc_config).read()
else:
msg = "Given InputMap '%s' not found" % input_map_file
return defer.fail(NoMappingsFound(msg))
else:
# the user configured an absolute lirc config file location
self.info("Using %s lirc map file", input_map_file)
try:
data = open(input_map_file).read()
except IOError:
msg = "Given InputMap '%s' not found" % input_map_file
return defer.fail(NoMappingsFound(msg))
if data:
self._parse_to_mapping(data)
if not len(self.mappings):
msg = "No Mappings found in %s" % input_map_file
return defer.fail(NoMappingsFound(msg))
self._setup_client()
return self
dfr.addCallback(initialized)
return dfr
def _setup_client(self):
connector = CallbackConnector(self._got_event)
self._client = Client(self.config.get('device'), connector,
reactor=reactor)
def repeat_ok(self):
self.repeat_interval = False
self.repeat_timer = None
def _got_event(self, hex_key, repeat, key_value, remote):
repeat = int(repeat, 16)
if not self.repeat_interval and repeat>self.repeatc or repeat==0:
if repeat==0 and not self.repeat_timer==None:
self.repeat_timer.cancel()
self.repeat_interval = True
self.repeat_timer = threading.Timer(self.delay,self.repeat_ok)
self.repeat_timer.start()
if '*' in self.mappings:
# ignore remote name provided by LIRC and take first remote registered in the
# mappings
mappings = self.mappings[self.mappings.keys()[0]]
elif remote not in self.mappings:
self.debug("Unknown remote %s", remote)
return
else:
mappings = self.mappings[remote]
if hex_key in mappings:
value = mappings[hex_key]
elif key_value in mappings:
value = mappings[key_value]
else:
self.debug("Can't find '%s' nor '%s' in mappings for '%s'",
hex_key, key_value, remote)
return
evt = InputEvent(EventSource.REMOTE, EventType.OTHER, value)
self.input_manager.process_event(evt)
def _parse_to_mapping(self, data):
"""
parse the lirc input mappings
"""
for line in data.split('\n'):
line = line.strip()
splitted = line.split()
if line.startswith('#') or len(splitted) != 3:
self.info("Skipping %s", line)
continue
remote, key, elisa_key = splitted
if not hasattr(EventValue, elisa_key):
self.warning("Don't know key '%s'.", elisa_key)
continue
event_key = getattr(EventValue, elisa_key)
if not remote in self.mappings:
self.mappings[remote] = {}
self.debug("Adding %s as mapped to %s for the remote %s" %
(event_key, key, remote))
self.mappings[remote][key] = event_key
if __name__ == '__main__':
res = None
def setup_done(resource):
global res
res = resource
print """
You are now in the interactive tests. You have the DaapDebug object
at *daap_debug* and you can play around with its get_* methods. It is
holding the connection to your server. The login already worked :) .
"""
def setup():
config = LircInput.default_config
dfr = LircInput.create(config)
dfr.addCallback(setup_done)
reactor.callWhenRunning(setup)
reactor.simulate()
reactor.startRunning()
import IPython
IPython.Shell.IPShellGTK([], locals()).mainloop()