Showing posts with label hal. Show all posts
Showing posts with label hal. Show all posts

Sunday, March 8, 2009

Using DBus on Xubuntu 8.04

This post is obsolete has been superseded by my 2012 dbus tutorial series.

DBus is a system that permits different applications to exchange information. Tutorial Reference Other Reference.
Sometimes, DBus crashes upon restart from a suspend or hibernation. These bash commands will help you figure out if it has crashed, and how to restart it.

$ps -e | grep `cat /var/run/dbus/pid` # Confirm if DBus is running by checking for the PID number in the list of live processes.
                                      # If DBus is running, this will return the process number. 
                                      # If not, it will return nothing.
$sudo rm /var/run/dbus/pid            # Remove the stale pid file so DBus can be restarted.
$sudo dbus-daemon                     # Start DBus again.


A python script uses DBus to see if the network connection is available by asking Network Manager:

#! /usr/bin/env python
import dbus
bus = dbus.SystemBus()
item = 'org.freedesktop.NetworkManager'
eth0_path = '/org/freedesktop/NetworkManager/Devices/eth0'
eth1_path = '/org/freedesktop/NetworkManager/Devices/eth1'
interface = 'org.freedesktop.NetworkManager.Devices'

# There are two possible network interfaces: eth0 (wired) and eth1 (wireless).
eth0 = dbus.Interface(bus.get_object(item, eth0_path), interface)
if eth0.getLinkActive(): print('The wired network is up') # getLinkActive() is a boolean, TRUE if the network link is active
eth1 = dbus.Interface(bus.get_object(item, eth1_path), interface)
if eth1.getLinkActive(): print('The wireless network is up')

This shell script does exactly the same thing, using the same DBus call:
# This shell script checks Network Manager if the network is up, using dbus as the communications medium.
# There are two possible network interfaces: eth0 (wired) and eth1 (wireless). Of course, you may need to alter these to meet your own circumstances.
# The basic format of dbus-send is: dbus-send --system --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/Devices/eth0 --print-reply org.freedesktop.NetworkManager.Devices.eth0.getLinkActive
DEST='org.freedesktop.NetworkManager'
PPATH='/org/freedesktop/NetworkManager/Devices'
DEVICE='org.freedesktop.NetworkManager.Devices'

result_eth0=`dbus-send --system --dest=$DEST $PPATH'/eth0' --print-reply $DEVICE'.eth0.getLinkActive'`
shaved_eth0=`echo $result_eth0 | cut -d ' ' -f8`
if [ $shaved_eth0 = 'true' ]; then echo 'The wired network is up'; fi

result_eth1=`dbus-send --system --dest=$DEST $PPATH'/eth1' --print-reply $DEVICE'.eth1.getLinkActive'`
shaved_eth1=`echo $result_eth1 | cut -d ' ' -f8`
if [ $shaved_eth1 = 'true' ]; then echo 'The wireless network is up'; fi


A Python script that queries Network Manager to get the list of wireless networks.

import dbus
item = 'org.freedesktop.NetworkManager'
path = '/org/freedesktop/NetworkManager'
interface = item + '.Device'

network_list = []
bus = dbus.SystemBus()

# Create a Network Manager interface and get the list of network devices
event = dbus.Interface(bus.get_object(item, path), interface)

# Create an interface for each device
# Query each interface to see if it's wireless
# Query each wireless interface for the networks it sees
for device in event.getDevices():
    device_interface = dbus.Interface(bus.get_object(item, device), interface)
    if device_interface.getType() == 2:  # 0 unknown, 1 wired, 2 wireless
        network_list.extend(device_interface.getNetworks())

# Reformat the network names in the list to be more readable
if network_list:
    for entry in network_list:
        #print entry    # String of path/to/network_name
        entry_list = entry.split('/')
        print entry_list[-1]  # String of network_name



A Python listener that catches the changes in wireless signal strength using both available methods.

import dbus, gobject
from dbus.mainloop.glib import DBusGMainLoop

def print_device_strength1(*args):  #Use the received signals
    signal_strength = args[1]
    print ('Signal Strength (Method 1): ' + str(signal_strength) + '%')

def print_device_strength2(*args, **kwargs):  #Use the received signals
    signal_strength = args[1]
    print ('Signal Strength (Method 2): ' + str(signal_strength) + '%')

DBusGMainLoop(set_as_default=True)    # Set up the event loop before connecting to the bus
bus_object = dbus.SystemBus()

# The variables you need. I used the shell command 'dbus-monitor --system' to find this information
sender = 'org.freedesktop.NetworkManager'
path = '/org/freedesktop/NetworkManager'
interface = sender
member = 'DeviceStrengthChanged'

# Method 1 - bus_object.proxy_object.connect_to_signal(method, action, filter, message_parts)
proxy_object = bus_object.get_object(sender, path)
proxy_object.connect_to_signal(member, print_device_strength1, dbus_interface = interface)

# Method 2 - bus_object.add_signal_receiver(action, [filters])
bus_object.add_signal_receiver(print_device_strength2, dbus_interface = interface, member_keyword = member)

# Start the loop
loop = gobject.MainLoop()
loop.run()




Thunar responds beautifully to D-Bus. Introspection is fully set up, so it's easy to use with the d-feet application. Useful for launching programs, opening folders and windows, and manipulating the trash. Launching a program by this method means that the the window manager launches the program, not the script or terminal, so the program can remain open after the script or terminal terminates.

#!/usr/bin/env python
import dbus
item = ('org.xfce.Thunar')
path = ('/org/xfce/FileManager')
interface = ('org.xfce.FileManager')
event = dbus.Interface(dbus.SessionBus().get_object(item, path), interface)

# These three lines at the end of the script open the file's 'properties' window
display = (':0')         # The current session screen
uri = ('/home/me/dbus_test.py')
event.DisplayFileProperties(uri, display)

# These three lines at the end of the script launch a new application
display = (':0')         # The current session screen
uri = ('/usr/bin/gftp-gtk')
event.Launch(uri, display)

# These four lines at the end of the script open a folder window and optionally select a file
display = (':0')         # The current session screen
uri = ('/home/me/.cron')
filename = ('anacrontab.daily')
event.DisplayFolderAndSelect(uri, filename, display)


A sample hal script.

#!/usr/bin/python
"""This python 2.5 script uses dbus to check if the lid switch is open.
Based on an original python script at http://schurger.org/wordpress/?p=49"""
import dbus

dest = 'org.freedesktop.Hal'
hal_path = '/org/freedesktop/Hal/Manager'
hal_interface = 'org.freedesktop.Hal.Manager'
udi_interface = 'org.freedesktop.Hal.Device'

# Get the list of possible input switches. The return is a list of paths.
bus = dbus.SystemBus()
hal = dbus.Interface(bus.get_object(dest, hal_path), hal_interface)
list_of_udi_paths = hal.FindDeviceByCapability('input.switch')

# Filter the list for the word 'lid'. Print the status for each one.
for udi_path in list_of_udi_paths:
    udi = dbus.Interface(bus.get_object(dest, udi_path), udi_interface)
    if udi.GetProperty('button.type') == "lid":
        # The button.state.value is FALSE if the lid is open.
        if udi.GetProperty('button.state.value'): print ('Lid is closed')
        else: print ('Lid is open') 
    else: print ('Problem: I could not find the lid switch. Sorry.')



Notes:

  • The D-feet application is very handy for exploring DBus, and figuring out how to communicate with it. It's available in the Ubuntu repositories.
  • More information on the destination/path/interface settings is available from each application's XML config files, found in the /etc/dbus-1/system.d and /session.d directories.
  • The system-tools-backends DBus interfaces look promising, with methods for network interfaces, time, users and groups, and more. But I couldn't get any of it to work. One hint suggested that the DBus message must be sent by root instead of user.
  • xfce4-terminal has a Launch method, seemingly for launching items in the terminal (source code). I can see how that would be handy, but I couldn't get it to work.