我尝试编写一个菜单栏应用程序,通过Mac控制我的灯光。 我正在使用milight (limitless, easybulbs...)的系统。 他们有一个开放的系统你可以通过UDP发送命令。
我可以通过python中的python-limitless库控制我的灯光,所以我知道IP和端口等网络连接是正确的。
所以我认为我从未使用过的UDP内容有任何问题。 我正在尝试使用SwiftSocket库来发送我的命令,但没有任何反应,我已经尝试了2天。
这是我正在尝试的事情:
let host = "192.168.2.102"
let port = 5987
var client: UDPClient!
@IBAction func lightOn(_ sender: NSButton) {
let bridgeon: [UInt8] = [0x31, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01]
let rgbwon: [UInt8] = [0x31, 0x00, 0x00, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0]
print("Licht an")
print(client.send(data: bridgeon))
sleep(1)
print(client.send(data: rgbwon))
sleep(1)
}
@IBAction func lightOff(_ sender: NSButton) {
print("Licht aus")
}
override func viewDidLoad() {
super.viewDidLoad()
client = UDPClient(address: host, port: Int32(port))
}
当我将它与pythonlibrary的复杂性进行比较时,我确信我会忘记一些重要的东西。我还没有和网络合作,所以对我很宽容。
谢谢和问候。答案 0 :(得分:3)
我有点晚了,但我希望它可以帮助你:
在发送您的lighton请求之前,您必须发送第一个请求来获取WiFi桥接会话。你还需要计算Milight所谓的"校验和"根据您的要求。
你还要确定你有什么样的灯泡,是WW灯泡还是CW?我被困了好几天因为我发错了请求..
我做了一个实现,它在php中,但你可以在Objective-C中使用它。
检查出来:https://github.com/winosaure/MilightAPI
更新:
根据无限制的"文件" (http://www.limitlessled.com/dev/)这就是请求的组成方式:
UDP十六进制发送格式:80 00 00 00 11 {WifiBridgeSessionID1} {WifiBridgeSessionID2} 00 {SequenceNumber} 00 {COMMAND} {ZONE NUMBER} 00 {Checksum}
这就是为什么你必须首先获得wifibridge会话,然后你需要计算校验和。
让我举一个关于如何打开灯的例子。
文档说:
31 00 00 08 04 01 00 00 00 =亮灯
31 00 00 08 04 01 00 00 00参考上面的{COMMAND}。
到目前为止,完整的请求必须是:
80 00 00 00 11 {WifiBridgeSessionID1} {WifiBridgeSessionID2} 00 {SequenceNumber} 00 31 00 00 08 04 01 00 00 00 {ZONE NUMBER} 00 {Checksum}
现在让我们来看看Wifibridge会议。该文件说:
获取WifiBridgeSessionID1和WifiBridgeSessionID2发送此信息 命令UDP。
发送十六进制字节:20 00 00 00 16 02 62 3A D5 ED A3 01 AE 08 2D 46 61 41 A7 F6 DC AF(D3 E6)00 00 1E< - 将此发送至ip wifi桥v6的地址
这就是我这样做的原因:
private function getWifiBridgeSession()
{
$command = array (
0x20,0x00, 0x00,
0x00, 0x16, 0x02,
0x62, 0x3A, 0xD5,
0xED, 0xA3, 0x01,
0xAE, 0x08, 0x2D,
0x46, 0x61, 0x41,
0xA7, 0xF6, 0xDC,
0xAF, 0xD3, 0xE6,
0x00, 0x00, 0x1E);
return $this->sendCommand($command);
}
使用此命令发送UDP请求后,您将获得结果。 Wifi Bridge session1指的是响应的第20个字节,WifiBridge Session2将引用第21个字节的响应(不要忘记我们从0开始计数,所以你必须采取类似"响应[19] ]"和"回复[20]")。
让我们说,在发送此请求后,我得到了回复:
28 00 00 00 11 00 02 AC CF 23 F5 7A D4 69 F0 3C 23 00 01 05 00
所以我的" WifiBridgesession1"是0x05和" Wifibridgesession2"是0x00
现在我们要求"打开"光是:
80 00 00 00 11 0x05 0x00 00 {SequenceNumber} 00 31 00 00 08 04 01 00 00 00 {ZONE NUMBER} 00 {Checksum}
所以现在我们需要找出{SequenceNumber} {Zone Number}和{Checksum}
什么是"序列号"?
医生说:
顺序字节只是帮助保持命令的正确顺序, 并且它有助于忽略已经收到的重复数据包。增量 每个新命令的此字节为1。
所以把你想要的东西放到每个请求的这个值为1。 (我个人总是发送0x01)。
"区号"指的是您同步灯光的区域。
{ZONE NUMBER}的有效列表0x00全部0x01 Zone1 0x02 Zone2 0x03 Zone3 0x04 Zone4
我们说"区域"是0x01。
几乎完成了。我们现在只需要计算"校验和"。
医生说:
取命令的9个字节和区域的1个字节,然后加0 =校验和=(校验和& 0xFF),例如SUM((31 00 00 08 04 01 00 00 00)(命令)01(区域)00)= 3F(chksum)
所以我们命令的校验和是: 31 + 00 + 00 + 08 + 04 + 01 + 00 + 00 + 00 + 01 + 00 = 0x54
我为区域+ 0x00
添加命令的所有字节(打开)+ 0x01所以现在我们已经拥有了所有内容,而打开灯光的完整请求是:
80 00 00 00 11 05 00 00 01 00 31 00 00 08 04 01 00 00 00 01 00 54
那就是它。
注意:不要只是复制并粘贴请求,我根据示例计算了值,打开灯的请求每次都会根据您计算的内容而改变。
也许你注意到我写了" 00 31 00 00 08 04 01 00 00 00"做"打开"命令,这只适用于CW灯泡。该文件没有具体说明...... WW灯泡的相同命令是00 31 00 00 07 03 01 00 00 00 所以WW灯泡的完整命令将是:
80 00 00 00 11 05 00 00 01 00 31 00 00 07 03 01 00 00 00 01 00 54
CW和WW灯泡有什么区别? 我可以说CW指的是"冷白"和WW到#34;暖白"。但由于我不是" led灯泡的专家。我无法解释更多,我也不知道为什么我们需要为两者写一个不同的请求。
无论如何,我希望我足够清楚。 让我知道事情是如何运作的。