Problems with sending UDP packets (milight, limitlessled)

流过昼夜 提交于 2019-12-24 10:50:01

问题


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.

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.

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

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.

thanks and greetings.


回答1:


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

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.

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..

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

Check it out : https://github.com/winosaure/MilightAPI

UPDATE :

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

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

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.

The documentation says that :

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

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}

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

to get the WifiBridgeSessionID1 and WifiBridgeSessionID2 send this command UDP.

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

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

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}

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

What is a "Sequence Number"?

The doc says :

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.

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.

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

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

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

The doc says :

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)

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

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

That's it.

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.

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

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.



来源:https://stackoverflow.com/questions/42535502/problems-with-sending-udp-packets-milight-limitlessled

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!