You are not logged in.

#1 2018-10-30 16:01:28

maddingl
Member
Registered: 2018-02-18
Posts: 11

[SOLVED] bluetoothctl - detect that device is NOT reachable

I have a quite unusual question about bluetoothctl.

I have written a little deamon for i3blocks that runs with 'interval=persist' and automatically connects to my bluetooth keyboard. This is it:

~/.config/i3blocks/scripts/bluetooth-keyboard
#!/bin/bash

MAC_ADDRESS="90:7F:61:0F:C0:BA"

function connected {
    bluetoothctl info ${MAC_ADDRESS} | grep 'Connected: yes'
}

function rssi {
    hcitool rssi ${MAC_ADDRESS}
}

function in_reach {
    bluetoothctl devices | grep ${MAC_ADDRESS}
}

function connect {
    bluetoothctl connect ${MAC_ADDRESS} > /dev/null
}

while true; do
    if [[ $(rssi) ]]; then
        STRENGTH=$(rssi | awk '{ print $NF }')
        echo "$STRENGTH dB"
    else
        if [[ $(in_reach) ]]; then
             echo ...
             connect
             if [[ $(connected) ]]; then
                echo ":-)"
                sleep 1
                setxkbmap us-de
             else
                echo ":-("
                bluetoothctl power off > /dev/null
                sleep 1
                echo ...
                bluetoothctl power on > /dev/null
             fi
        else
            echo "not in reach"
            sleep 60
        fi
    fi
    sleep 1
done

At home, it all runs fine and connects to my keyboard automatically and sets my custom keyboardmap.
However, now I am at the university and my keyboard is definitely too far away to connect.
I expected it to go to the part with 'sleep 60'. But the output of 'bluetoothctl devices' is still the same as at home:

bluetoothctl devices
Device 90:7F:61:0F:C0:BA ThinkPad Compact Bluetooth Keyboard with TrackPoint
Device AE:E2:D3:40:CF:18 OfficeJet 5200 series

How can I properly detect when the device is not in reach, so my script isn't trying to connect all the time?

This might be of interest:

bluetoothctl info 90:7F:61:0F:C0:BA
Device 90:7F:61:0F:C0:BA (public)
	Name: ThinkPad Compact Bluetooth Keyboard with TrackPoint
	Alias: ThinkPad Compact Bluetooth Keyboard with TrackPoint
	Class: 0x00000540
	Icon: input-keyboard
	Paired: yes
	Trusted: yes
	Blocked: no
	Connected: no
	LegacyPairing: no
	UUID: Service Discovery Serve.. (00001000-0000-1000-8000-00805f9b34fb)
	UUID: Human Interface Device... (00001124-0000-1000-8000-00805f9b34fb)
	UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
	Modalias: usb:v17EFp6048d0312

Also, I read that hcitool is deprecated. What can I use as an alternative to monitor the signal strength?

Last edited by maddingl (2018-10-31 12:29:12)

Offline

#2 2018-10-31 00:06:41

damjan
Member
Registered: 2006-05-30
Posts: 462

Re: [SOLVED] bluetoothctl - detect that device is NOT reachable

afaik 'bluetoothctl devices' shows all known devices

$ bluetoothctl 
Agent registered

[bluetooth]# help
Menu main:
Available commands:
-------------------
advertise                                         Advertise Options Submenu
scan                                              Scan Options Submenu
gatt                                              Generic Attribute Submenu
list                                              List available controllers
show [ctrl]                                       Controller information
select <ctrl>                                     Select default controller
devices                                           List available devices
paired-devices                                    List paired devices
system-alias <name>                               Set controller alias
reset-alias                                       Reset controller alias
power <on/off>                                    Set controller power
pairable <on/off>                                 Set controller pairable mode
discoverable <on/off>                             Set controller discoverable mode
agent <on/off/capability>                         Enable/disable agent with given capability
default-agent                                     Set agent as the default one
advertise <on/off/type>                           Enable/disable advertising with given type
set-alias <alias>                                 Set device alias
scan <on/off>                                     Scan for devices
info [dev]                                        Device information
pair [dev]                                        Pair with device
trust [dev]                                       Trust device
untrust [dev]                                     Untrust device
block [dev]                                       Block device
unblock [dev]                                     Unblock device
remove <dev>                                      Remove device
connect <dev>                                     Connect device
disconnect [dev]                                  Disconnect device
menu <name>                                       Select submenu
version                                           Display version
quit                                              Quit program
exit                                              Quit program
help                                              Display help about this program
export                                            Print evironment variables

Offline

#3 2018-10-31 00:20:38

progandy
Member
Registered: 2012-05-17
Posts: 5,322

Re: [SOLVED] bluetoothctl - detect that device is NOT reachable

With bluetooth it is impossible to check if a device is in reach. Most devices are not "discoverable" by default. You have to set them into a pairing mode with some command or button press. They will react to specific connection requests from already paired devices, though. You will probably have to try connecting in some interval.


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' | alias ENGLISH='LANG=C.UTF-8 ' |

Offline

#4 2018-10-31 12:08:04

maddingl
Member
Registered: 2018-02-18
Posts: 11

Re: [SOLVED] bluetoothctl - detect that device is NOT reachable

Thank you for this information.
I decided to restructure a bit: I try to connect 10 times, and if that fails, the script exits. If I then know the keyboard is near again, I can just restart i3. I also made the waiting output a little bit prettier. This is the script now:

#!/bin/bash

MAC_ADDRESS="90:7F:61:0F:C0:BA"

function connected {
    bluetoothctl info ${MAC_ADDRESS} | grep 'Connected: yes'
}

function dots {
    while true; do
        echo " "
        sleep 1
        echo .
        sleep 1
        echo ..
        sleep 1
        echo ...
        sleep 1
    done
}

N_ATTEMPTS=10
COUNTER=${N_ATTEMPTS}

while true; do
    if [[ $(connected) ]]; then
        STRENGTH=$(hcitool rssi ${MAC_ADDRESS} | awk '{ print $NF }')
        echo "$STRENGTH dB"
    else
        if ! ps -p $! > /dev/null; then
            dots &
        fi
        bluetoothctl connect ${MAC_ADDRESS} > /dev/null
        kill $!
        if [[ $(connected) ]]; then
            echo "... :-)"
            sleep 1
            COUNTER=${N_ATTEMPTS}
            setxkbmap us-de
        else
            echo "... :-("
            bluetoothctl power off > /dev/null
            sleep 1
            ((COUNTER--))
            if [[ ${COUNTER} == 0 ]]; then
                echo " xx "
                exit 0
            fi
            dots &
            bluetoothctl power on > /dev/null
        fi
    fi
    sleep 1
done

Offline

Board footer

Powered by FluxBB