littlecraft / phony

Easy to use bluetooth hands free telephony, with python
Other
86 stars 17 forks source link

Raspberry Pi phony Exception #5

Closed mutac closed 7 years ago

mutac commented 7 years ago

Originally posted as a Pull Request, moved to Issues: @PCGamer88

Hello,

I would like to call my Raspberry Pi with phony with my mobile phone. I have installed it as described in the manual, but unfortunately I get the following output with an error message when running the script. " Traceback (most recent call last): File "phone.py", line 93, in Service.run () File "phone.py", line 43, in run Phony.headset.HandsFreeHeadset (bus, adapter, hfp, audio) as hs: File "/usr/local/lib/python2.7/dist-packages/phony/headset.py", line 34, in init Self._bus = bus_provider.session_bus () File "/usr/local/lib/python2.7/dist-packages/phony/base/ipc.py", line 20, in session_bus Return dbus.SessionBus (mainloop = main_loop) File "/usr/lib/python2.7/dist-packages/dbus/dbus.py", line 211, in new Mainloop = mainloop) File "/usr/lib/python2.7/dist-packages/dbus/dbus.py", line 100, in new Bus = BusConnection . new __ (subclass, bus_type, mainloop = mainloop) File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 122, in new Bus = cls._new_for_bus (address_or_type, mainloop = mainloop) Dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus daemon without a $ DISPLAY for X11 " What does this error message mean and how can I fix it? I'm not familiar with Linux, but I'm starting with Python.

Sorry for my english.

I am happy about your answers.

Best regards Philipp

mutac commented 7 years ago

Typically, dbus programs operate in the presence of a UI (i.e. X11). If you want to run phony (or any other dbus based program) without having an X11 session open, like on an embedded Raspberry Pi, you can start an ad-hoc session with dbus-launch. This sets up a dbus session, and produces an environment variable DBUS_SESSION_BUS_ADDRESS, which can then be given to phony so that it knows how to communicate with the other services on the bus (like ofono and bluez).

The example program (cranky) needs to do this so that it can run on the raspi as a service (without x11)

The cranky service bash script does this

#!/bin/bash

# Set up dbus session and export DBUS_SESSION_BUS_ADDRESS env var
eval `dbus-launch --auto-syntax`

python $@ - <<END
from phony.examples.cranky.main import ApplicationMain
main = ApplicationMain()
main.run()
END

Then, the cranky main program does something like this

    session_bus_path = os.environ.get('DBUS_SESSION_BUS_ADDRESS')
    bus = phony.base.ipc.BusProvider(session_bus_path)

    with phony.bluetooth.adapters.Bluez5(bus) as adapter, \
         phony.bluetooth.profiles.handsfree.Ofono(bus) as hfp, \
         phony.audio.alsa.Alsa(config.audio_card_index) as audio, \
         phony.headset.HandsFreeHeadset(bus, adapter, hfp, audio) as hs:
PCGamer88 commented 7 years ago

Thank you for your answer. Is this possible without cranky so only with the code of the here stands https://github.com/littlecraft/phony? How would the script have to be rebuilt it works there?

mutac commented 7 years ago

Sure, you can certainly get the example working using the same technique as is used by the cranky program.

The example snippets of code above show the basic technique. The only thing that you'd need to do differently is import and call your python module from the bash script, rather than phony.examples.cranky.main. Then just make sure that you are passing the result of os.environ.get('DBUS_SESSION_BUS_ADDRESS') to phony.base.ipc.BusProvider(...) in your code.

PCGamer88 commented 7 years ago

Is it also possible to do something similar in the corresponding Python script using import os? So I do not need a shell script? I have adjusted the example with import os, unfortunately still comes the error :( Should not synonymous so go or is there a mistake in it?

`import gobject import phony.headset import phony.base.ipc import phony.base.log import phony.audio.alsa import phony.bluetooth.adapters import phony.bluetooth.profiles.handsfree import os

class ExampleHeadsetService:
_hs = None _call_in_progress = False

def device_connected(self): print 'Device connected!'

def incoming_call(self, call): print 'Incoming call: %s' % call if self._call_in_progress: self._hs.deflect_call_to_voicemail()

def call_began(self, call): print 'Call began: %s' % call self._call_in_progress = True

def call_ended(self, call): print 'Call ended: %s' % call self._call_in_progress = False

def run(self): """ Starts phony service which manages device pairing and setting up of hands-free profile services. This function never returns. """ session_bus_path = os.environ.get('DBUS_SESSION_BUS_ADDRESS')
bus = phony.base.ipc.BusProvider(session_bus_path)

# -1 find the first audio card that provides
# audio input and output mixers.
audio_card_index = 1

with phony.bluetooth.adapters.Bluez5(bus) as adapter, \
     phony.bluetooth.profiles.handsfree.Ofono(bus) as hfp, \
     phony.audio.alsa.Alsa(card_index=audio_card_index) as audio, \
     phony.headset.HandsFreeHeadset(bus, adapter, hfp, audio) as hs:

  # Register to receive some bluetooth events
  hs.on_device_connected(self.device_connected)
  hs.on_incoming_call(self.incoming_call)
  hs.on_call_began(self.call_began)
  hs.on_call_ended(self.call_ended)

  hs.start('MyBluetoothHeadset', pincode='1234')
  hs.enable_pairability(timeout=30)

  self._hs = hs

  # Wait forever
  gobject.MainLoop().run

def voice_dial(self): self._hs.initiate_call()

def dial_number(self, phone_number): self._hs.dial(phone_number)

def answer(self): self._hs.answer_call()

def hangup(self): self._hs.hangup()

if name == 'main': phony.base.log.send_to_stdout()

os.system("eval dbus-launch --auto-syntax") service = ExampleHeadsetService() service.run()`

mutac commented 7 years ago

You don't necessarily have to use a shell script to start your program.

I don't believe that using os.system to invoke dbus-launch will work here. The dbus session needs to be kept alive for as long as your program is running. So, there are two problems with using os.system: 1) it invokes the command in a separate child shell environment, which will not affect the environment of your program (which is the parent). 2) As soon as the os.system call exits, the dbus session will probably be closed.

You could try something like this from the command line (I haven't tried it, but it may do the trick):

$ dbus-launch python your-program.py

Or, an alternative would be to add the eval dbus-launch --auto-syntax command to the bottom of your ~/.bashrc file. This will then run automatically when you log in to your raspi. Note, however, that your program will only run after you have logged in (i.e. its not suitable if you ever intend to run your program as a service that starts up on boot).

Here's some more info. https://stackoverflow.com/questions/22346424/x11-dependency-compile-dbus-without-x11-starting-only-shell-c-applications-r

PCGamer88 commented 7 years ago

Thank you, the problem I have successfully solved :) But now follows a new problem :(

" $ dbus-launch python phone.py 2017-06-21 17:32:49.332 phony.headset.HandsFreeHeadset INFO -> HandsFreeHeadset.start() 2017-06-21 17:32:49.333 phony.headset.HandsFreeHeadset INFO -> HandsFreeHeadset.enable() 2017-06-21 17:32:49.334 phony.headset.HandsFreeHeadset DEBUG Running: rfkill unblock bluetooth 2017-06-21 17:32:49.404 phony.headset.HandsFreeHeadset INFO <- HandsFreeHeadset.enable() 2017-06-21 17:32:49.405 phony.audio.alsa.Alsa DEBUG -> Alsa.start() 2017-06-21 17:32:49.406 phony.audio.alsa.Alsa DEBUG Audio card name: hw:1 2017-06-21 17:32:49.406 phony.audio.alsa.Alsa DEBUG Speaker mixer capabilities: [u'Playback Mute'] 2017-06-21 17:32:49.407 phony.audio.alsa.Alsa DEBUG Speaker playback volume: [17, 17] 2017-06-21 17:32:49.407 phony.audio.alsa.Alsa DEBUG Speaker playback mute: [0, 0] 2017-06-21 17:32:49.407 phony.audio.alsa.Alsa DEBUG Microphone mixer capabilities: [u'Playback Mute', u'Joined Playback Mute', u'Capture Mute', u'Joined Capture Mute'] 2017-06-21 17:32:49.408 phony.audio.alsa.Alsa DEBUG Microphone playback mute: [1] 2017-06-21 17:32:49.408 phony.audio.alsa.Alsa DEBUG Microphone capture enabled: [1] 2017-06-21 17:32:49.409 phony.audio.alsa.Alsa DEBUG Microphone playback volume: [100] 2017-06-21 17:32:49.409 phony.audio.alsa.Alsa DEBUG Microphone capture volume: [0] 2017-06-21 17:32:49.410 phony.audio.alsa.Alsa DEBUG <- Alsa.start() 2017-06-21 17:32:49.410 phony.headset.HandsFreeHeadset INFO -> HandsFreeHeadset.mute_microphone() 2017-06-21 17:32:49.411 phony.audio.alsa.Alsa DEBUG Alsa.mute_microphone() 2017-06-21 17:32:49.412 phony.headset.HandsFreeHeadset INFO <- HandsFreeHeadset.mute_microphone() 2017-06-21 17:32:49.413 phony.headset.HandsFreeHeadset INFO -> HandsFreeHeadset.mute_speaker() 2017-06-21 17:32:49.413 phony.audio.alsa.Alsa DEBUG Alsa.mute_speaker() 2017-06-21 17:32:49.415 phony.headset.HandsFreeHeadset INFO <- HandsFreeHeadset.mute_speaker() 2017-06-21 17:32:49.416 phony.bluetooth.profiles.handsfree.ofono.Ofono DEBUG -> Ofono.start() 2017-06-21 17:32:49.420 phony.bluetooth.profiles.handsfree.ofono.Ofono DEBUG <- Ofono.start() 2017-06-21 17:32:49.421 phony.headset.HandsFreeHeadset INFO <- HandsFreeHeadset.start() 2017-06-21 17:32:49.421 phony.headset.HandsFreeHeadset INFO -> HandsFreeHeadset.stop() 2017-06-21 17:32:49.422 phony.headset.HandsFreeHeadset INFO <- HandsFreeHeadset.stop() Traceback (most recent call last): File "phone.py", line 95, in service.run() File "phone.py", line 53, in run hs.start('MyBluetoothHeadset', pincode='1234') File "/usr/local/lib/python2.7/dist-packages/phony/base/log.py", line 112, in call_wrapper return method(*args, *kwargs) File "/usr/local/lib/python2.7/dist-packages/phony/headset.py", line 60, in start self._hfp.start() File "/usr/local/lib/python2.7/dist-packages/phony/base/log.py", line 112, in call_wrapper return method(args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/phony/bluetooth/profiles/handsfree/ofono.py", line 29, in start self._bus.get_object(self.SERVICE_NAME, '/'), File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 241, in get_object follow_name_owner_changes=follow_name_owner_changes) File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 248, in init self._named_service = conn.activate_name_owner(bus_name) File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 180, in activate_name_owner self.start_service_by_name(bus_name) File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 278, in start_service_by_name 'su', (bus_name, flags))) File "/usr/lib/python2.7/dist-packages/dbus/connection.py", line 651, in call_blocking message, timeout) dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.ofono was not provided by any .service files "

What can this be?

mutac commented 7 years ago

It looks like ofono is either not installed correctly or is not running. You will need to have ofonod, and pulseaudio running in the background.

I'd really recommend trying to install the cranky example, or at least looking at it's setup scripts that are run as part of its installation. In particular, pulseaudio needs to be set up specifically to be able to run as root (in system mode). It also sets up the appropriate user and group permissions, which may not be on by default on the pi. See scripts and deploy within the cranky example. It can take a bit of work to get the pulseaudio and ofono properly set up in the pi, unfortunately.

PCGamer88 commented 7 years ago

I have phony step by step installed after tutorial. Unfortunately, the same error still occurs :( How and where do I have to configure Ofono?

I still notice, after I have run the script lights up to my USB sound adapter a red LED. I use LogiLink USB soundcard with Virtual 7.1 Soundeffekt LogiLink (http://www.logilink.eu/showproduct/UA0078.htm). So the script must have something a bit pushed or? Unfortunately, the LED remains red even after a reboot and no sounds work anymore ... How can I get the red LED off?

mutac commented 7 years ago

There is some documentation here (See the HFP section), for configuring pulseaudio to use ofono as its backend for hands-free bluetooth:

https://freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Bluetooth/

When installing phony, an attempt is made to do the necessary configuration, but that may or may not have succeeded on your system.

You can also tell if ofono is running by issuing something like the following command:

ps aux | grep ofonod

If ofono is running you should see something like /usr/sbin/ofonod appear in the output.

And, if you're considering running everything on a raspberry pi without an active window session, you may need to configure pulseaudio to run as root, and to start up as soon as the raspberry pi boots up. The example, cranky, uses this configuration, and attempts to do some of the necessary configuration if it is installed. Otherwise, here is a bit of information about how that might be set up:

https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/

-Matt