无法向 BLE 设备 Philips Hue Bulb 发送命令连接中断

问题描述

我正在尝试使用 RaspBerry Pi 4B 打开/关闭蓝牙 Hue 灯泡并更改亮度。灯泡亮了,我已经使用 bluez 成功连接到它了。当我尝试运行“char-write-req 0x0027 01”将其打开时,我收到以下消息:

GLib-WARNING **: 22:53:34.807: 无效的文件描述符

我可以看到连接成功,但是每当我尝试向其写入值时,我都会收到此消息并断开连接。运行 bluetoothctl 5.50。我在这里看到了补丁对话:https://www.spinics.net/lists/linux-bluetooth/msg67617.html。但我不确定它是否适用,我什至不知道如何应用它。有人可以帮我吗!

编辑我放弃了 gatttool 并使用 bluetoothctl 连接到灯泡和菜单 gatt 向它发送命令。

我发现开关灯的特性是 932c32bd-0002-47a2-835a-a8d455b859dd(对于我的飞利浦 Hue A19)。连接到灯泡后,我可以选择此属性并使用“write 01”将其打开并使用“write 00”将其关闭。 亮度特性为932c32bd-0002-47a2-835a-a8d455b859dd。当我阅读时,它输出 'fe',这是 254 的十六进制。这是最高亮度设置,它已经设置为。我可以使用 'write ',其中值范围为 1-254 来更改亮度。

解决方法

acquire-write 中使用 bluetoothctl 通常不是正确的命令。 readwrite 正是您想要的。

开始 bluetoothctl 后,我希望这一系列命令是:

connect <Address of bulb>
menu gatt
select-attribute 932c32bd-0002-47a2-835a-a8d455b859dd
write 1
write 0

如果你想编写这个脚本,那么下面是一个 Python3 脚本,我希望它可以打开然后关闭灯泡。

from time import sleep
from pydbus import SystemBus

BLUEZ_SERVICE = 'org.bluez'
BLUEZ_DEV_IFACE = 'org.bluez.Device1'
BLUEZ_CHR_IFACE = 'org.bluez.GattCharacteristic1'


class Central:

    def __init__(self,address):
        self.bus = SystemBus()
        self.mngr = self.bus.get(BLUEZ_SERVICE,'/')
        self.dev_path = self._from_device_address(address)
        self.device = self.bus.get(BLUEZ_SERVICE,self.dev_path)
        self.chars = {}

    def _from_device_address(self,addr):
        """Look up D-Bus object path from device address"""
        mng_objs = self.mngr.GetManagedObjects()
        for path in mng_objs:
            dev_addr = mng_objs[path].get(BLUEZ_DEV_IFACE,{}).get('Address','')
            if addr.casefold() == dev_addr.casefold():
                return path

    def _get_device_chars(self):
        mng_objs = self.mngr.GetManagedObjects()
        for path in mng_objs:
            chr_uuid = mng_objs[path].get(BLUEZ_CHR_IFACE,{}).get('UUID')
            if path.startswith(self.dev_path) and chr_uuid:
                self.chars[chr_uuid] = self.bus.get(BLUEZ_SERVICE,path)


    def connect(self):
        """
        Connect to device.
        Wait for GATT services to be resolved before returning
        """
        self.device.Connect()
        while not self.device.ServicesResolved:
            sleep(0.5)
        self._get_device_chars()

    def disconnect(self):
        """Disconnect from device"""
        self.device.Disconnect()

    def char_write(self,uuid,value):
        """Write value to given GATT characteristic UUID"""
        if uuid.casefold() in self.chars:
            self.chars[uuid.casefold()].WriteValue(value,{})
        else:
            raise KeyError(f'UUID {uuid} not found')

    def char_read(self,uuid):
        """Read value of given GATT characteristic UUID"""
        if uuid.casefold() in self.chars:
            return self.chars[uuid.casefold()].ReadValue({})
        else:
            raise KeyError(f'UUID {uuid} not found')


device_address = '11:22:33:44:55:66'
light_state = '932c32bd-0002-47a2-835a-a8d455b859dd'


dev = Central(device_address )
dev.connect()
dev.char_write(light_state,[1])
sleep(5)
dev.char_write(light_state,[0])
print(dev.char_read(light_state ))
dev.disconnect()

由于我没有灯泡,上述内容未经测试。但应该很好地概述了所需的内容。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...