BLE gatttool 交互式 shell 脚本

BLE gatttool interactive shell script

我使用 gatttool 与 BLE 设备建立了连接。首先,我使用 sudo gatttool -t random -b FF:3C:8F:22:C9:C8 -Iconnect 连接到设备。之后我用 char-read-uuid 2d30c082-f39f-4ce6-923f-3484ea480596 读取特定特征的值。

我想做的是使整个过程自动化并将后一个命令(查询值)放入循环中,理想情况下将每个值保存(附加)到文本文件中。我试过类似

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

但这无济于事,因为我什至无法连接到设备(理想情况下,第一个和第二个命令之间应该有一些延迟)。同样在连接之后,交互模式被启用并且 shell 命令在那里不起作用。如果能提供有关如何解决此问题的任何线索,我将不胜感激。

如果 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)。

的确,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]