2022-06-17

Weird behavior from either TcpClient or network

So I have two smartbulbs from Yeelight. I am trying to turn them on/off at the same time. You can achieve that by sending some TCP messages to them. This works completely fine from NodeJS with this little script:

const net = require("net")

send_to_lamp("192.168.178.83", '{"id": 1, "method": "set_power", "params": ["on", "sudden"]}\r\n', answ => console.log(answ))
send_to_lamp("192.168.178.84", '{"id": 1, "method": "set_power", "params": ["on", "sudden"]}\r\n', answ => console.log(answ))
console.log("sent")

function send_to_lamp(ip, body, callback) {
    var con = net.createConnection({port: 55443, host: ip}, () => {
            con.write(`asd\r\n`) // send two requests to wake up connection
            con.write(body)
    })
}

But now comes the weird behavior to play: When trying to do the exact same thing from C#, only the first bulb that is contacted reacts to the message. For example when executing this code:

using System.Net.Sockets;

Thread t1 = new Thread(con1);
t1.Start();
await Task.Delay(1000);
Thread t2 = new Thread(con2);
t2.Start();
await Task.Delay(5000);

async static void con1() {
    await TryConnect("192.168.178.83", "{\"id\": 1, \"method\": \"set_power\", \"params\": [\"on\", \"sudden\"]}\r\n");
}

async static void con2() {
    await TryConnect("192.168.178.84", "{\"id\": 1, \"method\": \"set_power\", \"params\": [\"on\", \"sudden\"]}\r\n");
}

static async Task TryConnect(String server, String message)
{
  try
  {
    using (var client = new TcpClient()){
        await client.ConnectAsync(server, 55443);
        using (var netstream = client.GetStream()) 
        using (var writer = new StreamWriter(netstream))
        using (var reader = new StreamReader(netstream))
        {
            writer.AutoFlush = true;
            netstream.ReadTimeout = 3000;
            await writer.WriteLineAsync(message);
            Console.WriteLine("sent {0}", message);
        }
    }
  }
  catch (ArgumentNullException e)
  {
    Console.WriteLine("ArgumentNullException: {0}", e);
  }
  catch (SocketException e)
  {
    Console.WriteLine("SocketException: {0}", e);
  }
}

Only the lamp with the IP 192.168.178.83 turns itself on. It even gets weirder. When just swapping the IP in the both con1/2 functions, so that the lamp with the IP 192.168.178.84 is called first, only it reacts and the lamp with the IP 192.168.178.83 does nothing. I tried several different methods of sending TCP messages from C# (using async, multi-threading, have a dedicated class for each TcpClient ...)

Anyone got an idea what I can try to get this to work?

Wireshark log during NodeJS script

Wireshark log during C# script

Disclaimer: I do not know much about TCP connections and how they should look in Wireshark, but just seen from the software side of things this really seams nonsensical.



No comments:

Post a Comment