发送UDP数据包时出现问题(轻微,无限制) [英] Problems with sending UDP packets (milight, limitlessled)

查看:245
本文介绍了发送UDP数据包时出现问题(轻微,无限制)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编写一个菜单栏应用程序来通过Mac控制我的灯光. 我使用的是 milight(无限,easybulbs ...)系统. 他们有一个开放的系统,您可以通过UDP发送命令.

I trying to write a menubar app to get control over my lights via Mac. I'm using the system of milight (limitless, easybulbs...). They have an open system were you can send commands via UDP.

我能够通过python中的 python-limitless 库来控制灯光,因此我知道IP和端口等网络连接是正确的.

I'm able to control my lights via python-limitless library in python, so I know the networking thing such as IP and port is right.

所以我认为我从未使用过的UDP东西有什么错. 我正在尝试使用 SwiftSocket 库发送命令,但没有任何反应,我一直在尝试从2天开始.

So I think I do anything wrong with this UDP stuff I never worked with. I'm trying to use SwiftSocket library to send my commands but nothing happens, I've been trying it since 2 days.

以下是我要尝试的内容:

Here ist what I'm trying:

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))
}

当我将其与python库的复杂性进行比较时,我确定我忘记了一些重要的东西.我尚未与网络合作,所以请宽容我.

When I compare this with the complexity of the pythonlibrary I'm sure I forget something important. I haven't worked with networks yet so be lenient with me.

感谢和问候.

推荐答案

我有点迟了,但我希望它能为您提供帮助:

I'm a bit late, but I hope it can help you :

在发送lighton请求之前,您必须发送第一个请求以获取wifi桥接会话.您还需要根据您的请求计算Milight所谓的校验和".

Before sending your lighton request you have to send a first request to get, the wifi bridge session. You also need to compute what Milight called the "checksum" based on your request.

您还要确保您拥有哪种灯泡,是WW灯泡还是CW灯泡?我因为发送了错误的请求而停留了好几天.

You also make sure about what kind of bulb you have, is it WW bulb or CW? I was stuck for severals days because I was sending wrong request..

我做了一个实现,它在php中,但是您可以在Objective-C中以相同的方式使用它.

I made an implementation, It's in php but you can use it same way in Objective-C.

查看: https://github.com/winosaure/MilightAPI

更新:

根据无限制的文档"( http://www.limitlessled.com/dev/)这就是请求的构成方式:

According to limitlessled "documentation" (http://www.limitlessled.com/dev/) this is how a request is composed :

UDP十六进制发送格式:80 00 00 00 11 {WifiBridgeSessionID1} {WifiBridgeSessionID2} 00 {SequenceNumber} 00 {COMMAND} {ZONE NUMBER} 00 {校验和}

UDP Hex Send Format: 80 00 00 00 11 {WifiBridgeSessionID1} {WifiBridgeSessionID2} 00 {SequenceNumber} 00 {COMMAND} {ZONE NUMBER} 00 {Checksum}

这就是为什么必须首先获得wifibridge会话,然后才需要计算校验和的原因.

This is why you must get wifibridge session first then you need to calculate the checksum.

让我举一个关于如何打开灯的例子.

Let me take one example about how to turn on the light.

文档说:

31 00 00 08 04 01 00 00 00 =点亮

31 00 00 08 04 01 00 00 00 = Light ON

31 00 00 08 04 01 00 00 00请参考上面的{COMMAND}.

31 00 00 08 04 01 00 00 00 refer to {COMMAND} above.

到目前为止,完整请求必须为:

So far the full request must be :

80 00 00 00 11 {WifiBridgeSessionID1} {WifiBridgeSessionID2} 00 {SequenceNumber} 00 31 00 00 08 04 01 00 00 00 {ZONE NUMBER} 00 {Checksum}

现在让我们开始Wifibridge会话.该文件说:

Now let's get the Wifibridge session. The documention says :

获取WifiBridgeSessionID1和WifiBridgeSessionID2发送此 命令UDP.

to get the WifiBridgeSessionID1 and WifiBridgeSessionID2 send this command 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的地址

SEND hex bytes: 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 <-- Send this to the ip address of the wifi bridge v6

这就是为什么我这样做:

That's why I'm doing this:

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网桥session1指的是响应的第20个字节,WifiBridge Session2将指的是第21个字节的响应(别忘了我们从0开始计数,因此您必须采用"response [19]"和"response [20]").

Once you send a UDP request with this command, you will get a result. The Wifi Bridge session1 refers to the 20th byte of the response and WifiBridge Session2 will refer to the 21th byte response (Don't forget that we start to count from 0, so you must take something like "response[19]" and "response[20]").

比方说,发送此请求后,我得到此响应:

Let's say, after sending this request I get this response :

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

So my "WifiBridgesession1" is 0x05 and "Wifibridgesession2" is 0x00

所以现在我们打开"灯的请求是:

So now our request to "turn on" the light is :

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}

So now we need to find out {SequenceNumber} {Zone Number} and {Checksum}

什么是序列号"?

医生说:

顺序字节仅有助于使命令保持正确的顺序, 它有助于忽略已经收到的重复数据包.增量 每个新命令的此字节加1.

Sequential byte just helps with keeping commands in the correct order, and it helps to ignore duplicate packets already received. increment this byte for each new command by 1.

因此放置您想要的内容,并为每个请求将此值增加到1. (我个人总是发送0x01).

So put what you want and increase this value to 1 for each request. (Personnally I always send 0x01).

区域编号"指的是同步灯光的区域.

"Zone number" refers to which zone you synchronized your light.

{ZONE NUMBER}的有效列表0x00全部0x01 Zone1 0x02 Zone2 0x03 Zone3 0x04 Zone4

Valid List for {ZONE NUMBER} 0x00 All 0x01 Zone1 0x02 Zone2 0x03 Zone3 0x04 Zone4

比方说,我们的区域"为0x01.

Let's say, our "zone" is 0x01.

快完成了.我们现在只需要计算校验和"即可.

Almost done. we just need now to calculate the "checksum".

医生说:

取命令的9个字节和区域的1个字节,然后加上0 =校验和=(校验和& 0xFF)例如SUM((31 00 00 08 04 01 00 00 00)(命令)01(区域)00)= 3F(chksum)

take the 9 bytes of the command, and 1 byte of the zone, and add the 0 = the checksum = (checksum & 0xFF) e.g. SUM((31 00 00 08 04 01 00 00 00)(command) 01(zone) 00) = 3F(chksum)

因此,我们的命令的校验和为: 31 + 00 + 00 + 08 + 04 + 01 + 00 + 00 + 00 + 01 + 00 = 0x54

So the checksum for our command is : 31+00+00+08+04+01+00+00+00+01+00 = 0x54

我将命令的所有字节(打开)+ 0x01添加为区域+ 0x00

I add all byte of the command (turn on) + 0x01 for the zone + 0x00

所以现在我们拥有了一切,打开灯的全部要求是:

So now we have everything and the full request to turn on the light is :

80 00 00 00 11 05 00 00 01 00 31 00 00 08 04 01 00 00 00 01 00 54

80 00 00 00 11 05 00 00 01 00 31 00 00 08 04 01 00 00 00 01 00 54

就是这样.

注意:不要仅仅复制并粘贴请求,我基于示例计算了该值,根据您要计算的内容,每次打开灯的请求都会更改.

Note : Do not just copy and paste the request, I calculated the value based on example, the request to turn on the light will change each time, based on what you will calculate.

也许您已经注意到我写了"00 31 00 00 08 04 01 00 00 00"来执行打开"命令,这仅适用于CW灯泡.该文档未指定... WW灯泡的相同命令是00 31 00 00 07 03 01 00 00 00 因此,WW灯泡的完整命令为:

Maybe you got noticed that I wrote "00 31 00 00 08 04 01 00 00 00" to do the "turn on" command, this will work only for CW bulb. The doc does not specify that... The same Command for WW bulb is 00 31 00 00 07 03 01 00 00 00 So the full command for WW bulb will be :

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表示暖白".但是由于我不是"LED灯泡"的专家,所以我无法解释更多,我也不知道为什么我们都需要为两者编写不同的请求.

What is the difference between CW and WW bulb? I can tell that CW refers to "Cold White" and WW to "Warm White". But as I am not an expert in "led bulb" I cannot explain more, I don't know why we need to write a different request for both, either.

无论如何,我希望我足够清楚. 让我知道一切如何运作.

Anyway I wish I was clear enough. Let me know how things are working.

这篇关于发送UDP数据包时出现问题(轻微,无限制)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆