private static void SendMessage(HaierConfiguration haierConfiguration, NetworkStream networkStream, string command) { Console.WriteLine($"Send command: {command}"); IncreaseSequence(); string commandWithSeq = Commands.Request + Commands.Zero16 + Commands.Zero16 + //haierConfiguration.MacAddress.Replace(":", string.Empty) + ConvertMac(haierConfiguration.MacAddress) + Commands.Zero4 + Commands.Zero16 + OrderByte(Sequence) + Len4(command) + command; string message = commandWithSeq.Replace(" ", string.Empty); Console.WriteLine($"Send message: {message}"); networkStream.Write(Encoding.ASCII.GetBytes(message)); }
static async Task Main(string[] args) { Console.Title = "Haier Airco!"; Console.WriteLine("Started!"); HaierConfiguration haierConfiguration = JsonSerializer.Deserialize <HaierConfiguration>(File.ReadAllText("Haier.json")); if (string.IsNullOrWhiteSpace(haierConfiguration.IpAddress)) { Console.WriteLine("No settings found in Haier.json, scanning network for Haier Airco..."); List <dynamic> results = await NetworkScanner.GetAircoIPAddressesAsync(); Console.WriteLine("Please fill in one of the found airco's in Haier.json"); Console.WriteLine("Press a key to exit"); Console.ReadKey(intercept: true); return; } bool running = true; try { Console.WriteLine("Connecting.."); IPAddress ipAddress = IPAddress.Parse(haierConfiguration.IpAddress); IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, haierConfiguration.Port); using (Socket socket = new Socket(ipEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { // Client socket.Connect(ipEndpoint); // Server //socket.Bind(ipEndpoint); //socket.Listen(128); Console.WriteLine("Connected"); using (NetworkStream networkStream = new NetworkStream(socket, true)) { Console.WriteLine("Connected with NetworkStream"); Decoder decoder = Encoding.ASCII.GetDecoder(); bool initialized = false; while (running) { if (!initialized) { SendMessage(haierConfiguration, networkStream, Commands.Hello); SendMessage(haierConfiguration, networkStream, Commands.Init); SendMessage(haierConfiguration, networkStream, Commands.On); initialized = true; } byte[] buffer = new byte[1024]; int iRx = await networkStream.ReadAsync(buffer); if (iRx > 0) { char[] chars = new char[iRx]; int charLen = decoder.GetChars(buffer, 0, iRx, chars, 0); string recv = new string(chars); Console.WriteLine($"Received: {recv}"); } } networkStream.Close(); } socket.Close(); } } catch (Exception e) { Console.WriteLine(e); } Console.WriteLine("DONE!"); AsyncTcpClient asyncTcpClient = new AsyncTcpClient { IPAddress = IPAddress.Parse(haierConfiguration.IpAddress), Port = haierConfiguration.Port, ConnectTimeout = TimeSpan.FromSeconds(60), AutoReconnect = true, ClosedCallback = async(client, closedRemotely) => { Log($"ClosedCallback, closedRemotely: {closedRemotely}"); //Console.Beep(3000, 250); //Console.Beep(1000, 250); }, ConnectedCallback = async(client, isReconnected) => { Log("Haier AC Connected!"); //Console.Beep(1000, 250); //Console.Beep(3000, 250); }, ReceivedCallback = async(client, count) => { // Custom connection logic Log($"ReceivedCallback ({count} bytes)"); byte[] receivedBytes = client.ByteBuffer.Dequeue(count); //File.WriteAllBytes(@"E:\Haier.dat", receivedBytes); //Console.WriteLine(BitConverter.ToString(receivedBytes)); //Console.WriteLine(Encoding.ASCII.GetString(receivedBytes)); //Console.WriteLine(receivedBytes); if (IsState(receivedBytes)) { if (BitConverter.ToString(receivedBytes) != BitConverter.ToString(LastState)) { Log(Encoding.ASCII.GetString(receivedBytes)); Console.WriteLine(BitConverter.ToString(receivedBytes)); HaierResponse haierResponse = Parser.BytesToStruct <HaierResponse>(receivedBytes); Log($"_Temperature: {haierResponse.Temperature} [{haierResponse._Temperature}]"); Log($"_RoomTemperature: {haierResponse.RoomTemperature} [{haierResponse._RoomTemperature}] {ConvertToBinary(haierResponse._RoomTemperature)}"); Log($"FlowDown: {haierResponse.FlowDown}, FlowUp: {haierResponse.FlowUp}, FlowUpSmall: {haierResponse.FlowUpSmall}"); Log($"FlowUpDown (Swing): {haierResponse.FlowUpDown} [{haierResponse._FlowUpDown}] [{ConvertToBinary(haierResponse._FlowUpDown)}]"); Log($"FlowLeftRight: {haierResponse.FlowLeftRight} [{haierResponse._FlowLeftRight}] [{ConvertToBinary(haierResponse._FlowLeftRight)}]"); //Log($"MacAddress: {new string(haierResponse.MacAddress)}"); Log($"Quiet: {haierResponse.Quiet}"); Log($"PoweredOn: {haierResponse.PoweredOn}"); Log($"PowerMode: {haierResponse.PowerMode}"); Log($"Purify/Health: {haierResponse.PurifyHealth}, LightsOn: {haierResponse.LightsOn}"); Log($"TimerSleep: {haierResponse.TimerSleep}"); Log($"FanSpeed: {Enum.GetName(typeof(FanSpeed), haierResponse.FanSpeed)} [{ConvertToBinary(haierResponse._FanSpeedAndOperationMode)}]"); Log($"OperationMode: {Enum.GetName(typeof(OperationMode), haierResponse.OperationMode)}"); Console.Title = $"{(haierResponse.PoweredOn ? "✔" : "❌")} {haierResponse.RoomTemperature}° 🡆 {haierResponse.Temperature}° @ {Enum.GetName(typeof(FanSpeed), haierResponse.FanSpeed)} | Haier Airco! {DateTime.Now:HH:mm}"; if (LastResponse.MacAddress != null && (LastResponse.RoomTemperature != haierResponse.RoomTemperature || LastResponse.Temperature != haierResponse.Temperature || LastResponse.PoweredOn != haierResponse.PoweredOn)) { FlashWindow.Flash(count: 10); } if (!haierResponse.PoweredOn) { // This all doesn't work //Console.WriteLine("Turning AC on!"); //Parser.SetBit(ref haierResponse._PoweredOn, 0, true); // Set as request //haierResponse.Reserved0_39[2] = 39; //haierResponse.Reserved0_39[2] = 20; //byte[] responseBytes = Parser.StructToBytes(haierResponse); //await SendCommandAsync(client, responseBytes); //byte[] bytesToSend = Parser.HexStringToBytes( // Commands.Request + // Commands.Zero16 + // Commands.Zero16 + // $"{new string(haierResponse.MacAddress):X2}" + // Commands.Zero4 + // Commands.Zero16 + // // Sequence 1 // Parser.OrderByte(1) + // Parser.HexStringLength(Commands.On) + // Commands.On //); //await client.Send(bytesToSend); //await SendCommandAsync(client, bytesToSend); } ShowChangedBytes(LastState, receivedBytes); LastResponse = haierResponse; LastState = receivedBytes; } } //byte[] pollingCommand = Parser.HexStringToBytes(Commands.Polling); //await SendCommandAsync(client, pollingCommand); } }; asyncTcpClient.Message += AsyncTcpClient_Message; asyncTcpClient.MaxConnectTimeout = TimeSpan.FromSeconds(100); await asyncTcpClient.RunAsync(); Log("Finished!"); Console.ReadKey(intercept: true); }