如何解决Python - 使用 Philips Hue Entertainment API通过 DTLS/PSK无法正确发送 XY 颜色值
https://github.com/EvillerBobUK/pyHue-BridgeLink-Example
需要您拥有 Philips Hue 硬件和各种 DTSL/PSK 软件包才能使示例工作
我正在用 Python 3 编写一个小程序,该程序在 RaspBerry Pi 上的 Ubuntu 中运行,以通过飞利浦 Hue 桥接器(版本 2)向智能灯发送指令。
该程序可在大多数模式下运行,除了一种(详情如下),所以我相信连接本身运行正常。我认为问题在于特定模式的数据报的构建 - 可能与根据文档在该模式下仅对 X 和 Y 浮点数使用 12 位分辨率的桥有关? - 但这是一个我真的不熟悉的领域,我就是看不出哪里出错了!
PH API 具有通过 https 发送指令的“标准”模式和使用 dtls/psk 通过 UDP 广播指令的“娱乐”模式。娱乐模式支持以 RGB 或 XY + 亮度发送数据,任一版本都相当于 3 x 16 位数据类型。 API 指南中的字节序是“Big-Endian(网络)”; BigEndian 和网络均已尝试并给出相同的结果。
RGB 以 0-254 之间的三个整数形式发送。
XY 作为 0.0-1.0 之间的两个浮点数发送。 API 文档似乎建议亮度应该作为 0-254 之间的整数发送,这不起作用。实验上,将它作为 0.0-1.0 之间的浮点数发送,按预期工作。
我正在使用从互联网某处抓取的一段代码来创建 DTS/PSK 连接和打包的结构(我真的在整个 DTLS/PSK/数据报方面苦苦挣扎),尽管它只是被使用如果我记得,代码中的RGB。根据我对 Philips Hue API 指南的理解,该结构以相同的方式构建和发送,只是更改了我所做的颜色空间标志和数据类型,所以理论上它应该可以工作?
如果我使用标准模式通过 https 发送指令 {"xy":[0.6915,0.3083],"bri":254}
,指示灯会按预期变成红色。
如果我使用娱乐模式通过 UDP 发送指令 [(3,255,0)],'RGB'
,指示灯会按预期变为红色,并且飞利浦 Hue API 调试 CLIP 工具会报告 "xy": [0.6915,0.3083]
。
如果我使用娱乐模式通过 UDP 发送指令 [(3,0.6915,0.3083,0.1)],'XYB'
,指示灯会变成非常白的蓝色,而飞利浦 Hue API 调试工具会报告 "xy": [0.2245,0.2065]
!
使用 0.0-1.0 之间的不同值似乎总是以某种淡蓝色结束。有一次,我运行了一个循环,它只是将数字推向各个方向并超出预期范围,这确实导致偶尔出现黄色、绿色和很少出现红色,但通常是当发送的值大大超出范围/负值时.这些深夜绝望的测试都没有被正确记录或指向我可以在结果中看到的任何类型的模式/逻辑!
对理解问题和解决问题的任何帮助将不胜感激!
class pyHue_BridgeLink:
def __init__(self,bridgename=False,config=False):
# self.broadcast is a class-level variable for holding the datagram packed struct.
self.broadcast = None
# put is the function that takes the instructions and turns them into a https put request,# which is then sent to the bridge for forwarding to the appropriate light.
def put(self,url,request,payload,sslverify=False):
return requests.put(f"{url}{request}",json=payload,verify=sslverify).json()
# prepare_broadcast is the function that takes the instructions and turns them into a datagram,# which is then sent to the bridge (by a call elsewhere to send_broadcast) for broadcasting to the
# entertainment light group.
# Datatype 'e' is,I believe,a 16bit float.
# Endian type > (BigEndian) and ! (network) have both been tried
def prepare_broadcast(self,states,colourspace='RGB'): #colourspace = 'RGB' or 'XYB'
if colourspace == 'XYB':
cs = 0x01
datatypes = ">BHeee"
else:
cs = 0x00
datatypes = ">BHHHH"
count = len(states)
self.broadcast = bytearray([0]*(16+count*9))
struct.pack_into(">9s2BB2BBB",self.broadcast,"HueStream".encode('ascii'),# Protocol Name (fixed)
0x01,0x00,# Version (=01.00)
0x00,# Sequence ID (ignored)
0x00,# Reserved (zeros)
cs,# Color Space (RGB=0x00,XYB=0x01)
0x00 # Reserved (zero)
)
for i in range(count): # Step through each set of instructions in "states"
struct.pack_into(datatypes,16 + i*9,# Type: Light
states[i][0],# Light ID
states[i][1],# Red/X
states[i][2],# Blue/Y
states[i][3] # Green/Brightness
)
# send_broadcast passes the prepared datagram held in self.broadcast to the socket
# for sending via DTLS/PSK which is,as far as I can establish,some kind of witchcraft.
def send_broadcast(self):
if self.sock:
self.sock.send(self.broadcast)
# prepare_and_send_broadcast is an intermediary function that,unsurprisingly,calls the
# prepare_broadcast command above then calls the send_broadcast command. There are cases where the
# self.broadcast packed struct will be sent at a different time to when it was prepared. This
# function is used when both need to happen at the same time.
def prepare_and_send_broadcast(self,colourspace='RGB'):
self.prepare_broadcast(states,colourspace)
self.send_broadcast()
示例用法
bl = pyHue_BridgeLink("BridgeOne")
# Using the standard API to send via https. This works correctly!
# Physical light turns red as expected.
# Philips Hue API Debug CLIP tool reports "xy": [0.6915,0.3083] as it should.
bl.put(bl.url,'lights/3/state',{"xy":[0.6915,"bri":254})
# Switching to Entertainment mode...
bl.enable_streaming()
# Using the entertainment API to stream RGB instructions via UDP. This works correctly!
# Physical light turns red as expected.
# Philips Hue API Debug CLIP tool reports "xy": [0.6915,0.3083] as it should.
bl.prepare_and_send_broadcast([(3,'RGB')
# Using the entertainment API to stream XY+Brightness instructions via UDP. This fails!
# Physical light turns a very whitish-blue.
# Philips Hue API Debug CLIP tool reports "xy": [0.2245,0.2065] which is very wrong.
bl.prepare_and_send_broadcast([(3,'XYB')
# Switching back out of Entertainment mode...
bl.disable_streaming()
https://github.com/EvillerBobUK/pyHue-BridgeLink-Example
需要您拥有 Philips Hue 硬件和各种 DTSL/PSK 软件包才能使示例工作
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。