catch nonloadable drivers, debug, cleanup
This commit is contained in:
parent
55de2f3c38
commit
3f195745e3
1
TODO
1
TODO
@ -3,6 +3,7 @@ ToDos in Priority order:
|
||||
Known Bugs:
|
||||
- some timing issues for some users that leads to an delay to read incomming messages
|
||||
- for some users fenrir eats the orca key
|
||||
- dont break on non existing python-evdev event.
|
||||
- in special cases next word skipps a word, "word<12 spaces>word2<12 spaces>word3 (storm_dragon)
|
||||
- Fenrir key sometimes wents crazy? (maybe this is if fenrir key is released before other keys)
|
||||
- For example, in screen, it just tells me bell in window, but doesn't tell me which one. (southernprince)
|
||||
|
@ -4,6 +4,7 @@ enabled=True
|
||||
|
||||
# Select the driver used to play sounds, choices are generic and gstreamer.
|
||||
# Sox is the default.
|
||||
#driver=gstreamer
|
||||
driver=generic
|
||||
|
||||
# Sound themes. This is the pack of sounds used for sound alerts.
|
||||
|
@ -47,7 +47,7 @@ class debug():
|
||||
if not self._fileOpened:
|
||||
self.openDebugFile()
|
||||
if onAnyLevel:
|
||||
msg = 'ANY '+ str(level) + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f'))
|
||||
msg = 'ANY '+ str(level) + ' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f'))
|
||||
else:
|
||||
msg = str(level) +' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
|
||||
)
|
||||
|
@ -175,15 +175,18 @@ class settingsManager():
|
||||
return value
|
||||
|
||||
def loadDriver(self, driverName, driverType):
|
||||
if self.env['runtime'][driverType] != None:
|
||||
print('shutdown %s',driverType)
|
||||
self.env['runtime'][driverType].shutdown(self.env)
|
||||
spec = importlib.util.spec_from_file_location(driverName, os.path.dirname(os.path.realpath(__main__.__file__)) + "/" + driverType + '/' + driverName + '.py')
|
||||
driver_mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(driver_mod)
|
||||
self.env['runtime'][driverType] = driver_mod.driver()
|
||||
self.env['runtime'][driverType].initialize(self.env)
|
||||
|
||||
try:
|
||||
if self.env['runtime'][driverType] != None:
|
||||
self.env['runtime'][driverType].shutdown(self.env)
|
||||
spec = importlib.util.spec_from_file_location(driverName, os.path.dirname(os.path.realpath(__main__.__file__)) + "/" + driverType + '/' + driverName + '.py')
|
||||
driver_mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(driver_mod)
|
||||
self.env['runtime'][driverType] = driver_mod.driver()
|
||||
self.env['runtime'][driverType].initialize(self.env)
|
||||
self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType +" OK",debug.debugLevel.INFO, onAnyLevel=True)
|
||||
except Exception as e:
|
||||
self.env['runtime'][driverType] = None
|
||||
self.env['runtime']['debug'].writeDebugOut("Loading " + driverType + " Driver : "+ str(e), debug.debugLevel.ERROR)
|
||||
def shutdownDriver(self, driverType):
|
||||
if self.env['runtime'][driverType] == None:
|
||||
return
|
||||
|
@ -4,11 +4,17 @@
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
import evdev
|
||||
import time
|
||||
from evdev import InputDevice, UInput
|
||||
from select import select
|
||||
_evdevAvailable = False
|
||||
_evdevAvailableError = ''
|
||||
try:
|
||||
import evdev
|
||||
from evdev import InputDevice, UInput
|
||||
_evdevAvailable = True
|
||||
except Exception as e:
|
||||
_evdevAvailableError = str(e)
|
||||
|
||||
import time
|
||||
from select import select
|
||||
from core import inputEvent
|
||||
from core import debug
|
||||
|
||||
@ -16,19 +22,30 @@ class driver():
|
||||
def __init__(self):
|
||||
self.iDevices = {}
|
||||
self.uDevices = {}
|
||||
self.ledDevices = {}
|
||||
self.ledDevices = {}
|
||||
self._initialized = False
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.getInputDevices()
|
||||
self.env = environment
|
||||
global _evdevAvailable
|
||||
self._initialized = _evdevAvailable
|
||||
if not self._initialized:
|
||||
global _evdevAvailableError
|
||||
self.env['runtime']['debug'].writeDebugOut('InputDriver: ' + _evdevAvailableError,debug.debugLevel.ERROR)
|
||||
return
|
||||
self.getInputDevices()
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
def getInputEvent(self):
|
||||
if not self._initialized:
|
||||
time.sleep(0.005) # dont flood CPU
|
||||
return None
|
||||
if not self.iDevices:
|
||||
return None
|
||||
if self.iDevices == {}:
|
||||
return None
|
||||
|
||||
event = None
|
||||
r, w, x = select(self.iDevices, [], [], self.env['runtime']['settingsManager'].getSettingAsFloat('screen', 'screenUpdateDelay'))
|
||||
if r != []:
|
||||
@ -47,16 +64,24 @@ class driver():
|
||||
return None
|
||||
|
||||
def writeEventBuffer(self):
|
||||
if not self._initialized:
|
||||
return
|
||||
for iDevice, uDevice, event in self.env['input']['eventBuffer']:
|
||||
self.writeUInput(uDevice, event)
|
||||
|
||||
def clearEventBuffer(self):
|
||||
if not self._initialized:
|
||||
return
|
||||
del self.env['input']['eventBuffer'][:]
|
||||
|
||||
def writeUInput(self, uDevice, event):
|
||||
if not self._initialized:
|
||||
return
|
||||
uDevice.write_event(event)
|
||||
uDevice.syn()
|
||||
def getInputDevices(self):
|
||||
if not self._initialized:
|
||||
return
|
||||
deviceList = evdev.list_devices()
|
||||
readableDevices = []
|
||||
for dev in deviceList:
|
||||
@ -83,6 +108,8 @@ class driver():
|
||||
self.ledDevices = {dev.fd: dev for dev in self.ledDevices if dev.name.upper() in self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper().split(',')}
|
||||
|
||||
def mapEvent(self, event):
|
||||
if not self._initialized:
|
||||
return None
|
||||
if not event:
|
||||
return None
|
||||
mEvent = inputEvent.inputEvent
|
||||
@ -97,6 +124,8 @@ class driver():
|
||||
return None
|
||||
|
||||
def getLedState(self, led = 0):
|
||||
if not self._initialized:
|
||||
return None
|
||||
# 0 = Numlock
|
||||
# 1 = Capslock
|
||||
# 2 = Rollen
|
||||
@ -108,6 +137,8 @@ class driver():
|
||||
return led in dev.leds()
|
||||
return False
|
||||
def toggleLedState(self, led = 0):
|
||||
if not self._initialized:
|
||||
return None
|
||||
ledState = self.getLedState(led)
|
||||
for i in self.ledDevices:
|
||||
if ledState == 1:
|
||||
@ -115,6 +146,8 @@ class driver():
|
||||
else:
|
||||
self.ledDevices[i].set_led(led , 1)
|
||||
def grabDevices(self):
|
||||
if not self._initialized:
|
||||
return None
|
||||
# leve the old code until the new one is better tested
|
||||
# for fd in self.iDevices:
|
||||
# dev = self.iDevices[fd]
|
||||
@ -137,6 +170,8 @@ class driver():
|
||||
except Exception as e:
|
||||
self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible: ' + str(e),debug.debugLevel.ERROR)
|
||||
def releaseDevices(self):
|
||||
if not self._initialized:
|
||||
return None
|
||||
for fd in self.iDevices:
|
||||
try:
|
||||
self.iDevices[fd].ungrab()
|
||||
@ -154,7 +189,9 @@ class driver():
|
||||
self.iDevices.clear()
|
||||
self.uDevices.clear()
|
||||
|
||||
def __del__(self):
|
||||
self.releaseDevices()
|
||||
def __del__(self):
|
||||
if not self._initialized:
|
||||
return None
|
||||
self.releaseDevices()
|
||||
|
||||
|
||||
|
@ -9,19 +9,30 @@ from core import debug
|
||||
class driver():
|
||||
def __init__(self):
|
||||
self.volume = None
|
||||
self._initialized = False
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
def shutdown(self):
|
||||
if not self._initialized:
|
||||
return
|
||||
self.cancel()
|
||||
def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
|
||||
if not self._initialized:
|
||||
return
|
||||
if interrupt:
|
||||
self.cancel()
|
||||
def playSoundFile(self, filePath, interrupt = True):
|
||||
if not self._initialized:
|
||||
return
|
||||
if interrupt:
|
||||
self.cancel()
|
||||
def cancel(self):
|
||||
pass
|
||||
if not self._initialized:
|
||||
return
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
if not self._initialized:
|
||||
return
|
||||
def setVolume(self, volume):
|
||||
if not self._initialized:
|
||||
return
|
||||
self.volume = volume
|
||||
|
@ -14,6 +14,7 @@ class driver():
|
||||
self.soundType = ''
|
||||
self.soundFileCommand = ''
|
||||
self.frequenceCommand = ''
|
||||
self._initialized = False
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.soundFileCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericPlayFileCommand')
|
||||
@ -22,9 +23,14 @@ class driver():
|
||||
self.soundFileCommand = 'play -q -v fenrirVolume fenrirSoundFile'
|
||||
if self.frequenceCommand == '':
|
||||
self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
|
||||
self._initialized = True
|
||||
def shutdown(self):
|
||||
if not self._initialized:
|
||||
return
|
||||
self.cancel()
|
||||
def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
|
||||
if not self._initialized:
|
||||
return
|
||||
if interrupt:
|
||||
self.cancel()
|
||||
popenFrequenceCommand = self.frequenceCommand.replace('fenrirVolume', str(self.volume + adjustVolume ))
|
||||
@ -33,6 +39,8 @@ class driver():
|
||||
self.proc = subprocess.Popen(popenFrequenceCommand, shell=True)
|
||||
self.soundType = 'frequence'
|
||||
def playSoundFile(self, filePath, interrupt = True):
|
||||
if not self._initialized:
|
||||
return
|
||||
if interrupt:
|
||||
self.cancel()
|
||||
popenSoundFileCommand = self.soundFileCommand.replace('fenrirVolume', str(self.volume ))
|
||||
@ -40,6 +48,8 @@ class driver():
|
||||
self.proc = subprocess.Popen(popenSoundFileCommand, shell=True)
|
||||
self.soundType = 'file'
|
||||
def cancel(self):
|
||||
if not self._initialized:
|
||||
return
|
||||
if self.soundType == '':
|
||||
return
|
||||
if self.soundType == 'file':
|
||||
@ -48,6 +58,9 @@ class driver():
|
||||
self.proc.kill()
|
||||
self.soundType = ''
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
if not self._initialized:
|
||||
return
|
||||
def setVolume(self, volume):
|
||||
if not self._initialized:
|
||||
return
|
||||
self.volume = volume
|
||||
|
@ -5,32 +5,35 @@
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
import gi
|
||||
import time, threading
|
||||
from gi.repository import GLib
|
||||
|
||||
|
||||
_gstreamerAvailable = False
|
||||
try:
|
||||
import gi
|
||||
from gi.repository import GLib
|
||||
gi.require_version('Gst', '1.0')
|
||||
from gi.repository import Gst
|
||||
except:
|
||||
_gstreamerAvailable, args = Gst.init_check(None)
|
||||
except Exception as e:
|
||||
_gstreamerAvailable = False
|
||||
else:
|
||||
_gstreamerAvailable, args = Gst.init_check(None)
|
||||
_availableError = str(e)
|
||||
|
||||
class driver:
|
||||
def __init__(self):
|
||||
self._initialized = False
|
||||
self._source = None
|
||||
self._sink = None
|
||||
self.volume = 1
|
||||
self._initialized = False
|
||||
|
||||
def initialize(self, environment):
|
||||
if self._initialized:
|
||||
return
|
||||
global _gstreamerAvailable
|
||||
if not _gstreamerAvailable:
|
||||
self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available',debug.debugLevel.ERROR)
|
||||
return
|
||||
self.env = environment
|
||||
global _gstreamerAvailable
|
||||
self._initialized = _gstreamerAvailable
|
||||
if not self._initialized:
|
||||
global _availableError
|
||||
self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available ' + _availableError,debug.debugLevel.ERROR)
|
||||
return
|
||||
self._player = Gst.ElementFactory.make('playbin', 'player')
|
||||
bus = self._player.get_bus()
|
||||
bus.add_signal_watch()
|
||||
@ -46,21 +49,19 @@ class driver:
|
||||
self._pipeline.add(self._source)
|
||||
self._pipeline.add(self._sink)
|
||||
self._source.link(self._sink)
|
||||
|
||||
self._initialized = True
|
||||
self.mainloop = GLib.MainLoop()
|
||||
self.thread = threading.Thread(target=self.mainloop.run)
|
||||
self.thread.start()
|
||||
|
||||
def shutdown(self):
|
||||
global _gstreamerAvailable
|
||||
if not _gstreamerAvailable:
|
||||
if not self._initialized:
|
||||
return
|
||||
self.cancel()
|
||||
self.mainloop.quit()
|
||||
self._initialized = False
|
||||
_gstreamerAvailable = False
|
||||
|
||||
def _onPlayerMessage(self, bus, message):
|
||||
if not self._initialized:
|
||||
return
|
||||
if message.type == Gst.MessageType.EOS:
|
||||
self._player.set_state(Gst.State.NULL)
|
||||
elif message.type == Gst.MessageType.ERROR:
|
||||
@ -69,6 +70,8 @@ class driver:
|
||||
self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPlayerMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
|
||||
|
||||
def _onPipelineMessage(self, bus, message):
|
||||
if not self._initialized:
|
||||
return
|
||||
if message.type == Gst.MessageType.EOS:
|
||||
self._pipeline.set_state(Gst.State.NULL)
|
||||
elif message.type == Gst.MessageType.ERROR:
|
||||
@ -77,15 +80,21 @@ class driver:
|
||||
self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPipelineMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
|
||||
|
||||
def _onTimeout(self, element):
|
||||
if not self._initialized:
|
||||
return
|
||||
element.set_state(Gst.State.NULL)
|
||||
|
||||
def playSoundFile(self, fileName, interrupt=True):
|
||||
if not self._initialized:
|
||||
return
|
||||
if interrupt:
|
||||
self.cancel()
|
||||
self._player.set_property('uri', 'file://%s' % fileName)
|
||||
self._player.set_state(Gst.State.PLAYING)
|
||||
|
||||
def playFrequence(self, frequence, duration, adjustVolume, interrupt=True):
|
||||
if not self._initialized:
|
||||
return
|
||||
if interrupt:
|
||||
self.cancel()
|
||||
self._source.set_property('volume', tone.volume)
|
||||
@ -96,8 +105,7 @@ class driver:
|
||||
GLib.timeout_add(duration, self._onTimeout, self._pipeline)
|
||||
|
||||
def cancel(self, element=None):
|
||||
global _gstreamerAvailable
|
||||
if not _gstreamerAvailable:
|
||||
if not self._initialized:
|
||||
return
|
||||
if element:
|
||||
element.set_state(Gst.State.NULL)
|
||||
@ -105,6 +113,8 @@ class driver:
|
||||
self._player.set_state(Gst.State.NULL)
|
||||
self._pipeline.set_state(Gst.State.NULL)
|
||||
def setVolume(self, volume):
|
||||
if not self._initialized:
|
||||
return
|
||||
self.volume = volume
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user