Сценарий интерактивной оболочки BLE gatttool - PullRequest
0 голосов
/ 28 июня 2018

Я установил соединение с устройством BLE с помощью gatttool. Сначала я подключился к устройству с sudo gatttool -t random -b FF:3C:8F:22:C9:C8 -I и connect. После этого я читаю значение конкретной характеристики с char-read-uuid 2d30c082-f39f-4ce6-923f-3484ea480596.

Here is a view on the console

Что я хочу сделать, это автоматизировать весь процесс и поместить последнюю команду (запрос значения) в цикл, в идеале сохраняя каждое значение (добавление) в текстовый файл. Я пробовал что-то вроде

sudo gatttool -t random -b FF:3C:8F:22:C9:C8 -I <<EOF
connect
while[ 1 ]; do
char-read-uuid 2d30c082-f39f-4ce6-923f-3484ea480596 > output.txt
done
exit 1
EOF

но это не помогает, поскольку я даже не могу подключиться к устройству (в идеале должна быть некоторая задержка между первой и второй командой). Также после подключения включается интерактивный режим и команды оболочки там не работают. Буду признателен за подсказки, как решить эту проблему.

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Действительно, pexpect отлично работает здесь. Вы можете найти мое решение ниже. Код считывает значение определенного UUID, который содержит показания IMU (с плавающей точкой).

import pexpect
import struct
import time
import sys

IMU_MAC_ADDRESS = "FF:3C:8F:22:C9:C8"
UUID_DATA = "2d30c082-f39f-4ce6-923f-3484ea480596"

if __name__ == '__main__':
    gatt = pexpect.spawn("gatttool -t random -b " + IMU_MAC_ADDRESS + " -I")
    gatt.sendline("connect")
    gatt.expect("Connection successful")

    while(True):
        gatt.sendline("char-read-uuid " + UUID_DATA)
        gatt.expect("handle: 0x0011      value: ")
        gatt.expect(" \r\n")
        data = (gatt.before).decode('UTF-8').replace(" ", "").decode('hex')
        print(struct.unpack('f', data)[0]
0 голосов
/ 28 июня 2018

Если gattool записывает подсказки в стандартный вывод (и не подавляет их, учитывая файловые дескрипторы, отличные от TTY), рассмотрите что-то вроде:

#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*|4.0.*) echo "ERROR: bash 4.1 or newer required" >&2; exit 1;; esac

exec {output_fd}>output.txt

prompt_re='[>] '
capture_re='^handle:.*value:.*$'

wait_for_prompt() {
  IFS= read -r line || return
  while ! [[ $line =~ $prompt_re ]]; do
    [[ $line =~ $capture_re ]] && printf '%s\n' "$line" >&$output_fd
    IFS= read -r line || return
  done
}

wait_for_prompt
echo connect
while wait_for_prompt; do
  echo "char-read-uuid 2d30c082-f39f-4ce6-923f-3484ea480596"
done

... сохраняется как yourscript и вызывается с помощью socat как:

socat 'SYSTEM:sudo gatttool -t random -b FF:3C:8F:22:C9:C8 -I 2>&1' 'EXEC:./yourscript'

(при условии, что sudo настроен для работы без TTY; в противном случае вы можете переместить его на sudo socat).

...