Wi-FI Remote for MI TV using ESP8266

Xiaomi-Mi-TV-4A-32-inch

I got an MI Smart TV and was pretty much interested in including that in my Home Automation system (OpenHAB). It is supposed to be controlled so that it can be turned on or off based on profile and scene. Although the TV does support MI TV remote over Wi-Fi, it is not able to turn on the TV when it is off. The easiest way to do so is to replicate the remote to an ESP8266 board is having an IR LED and Wi-Fi. By using it everything that can be controlled by a physical remote, can be achieved. I thought of using the API calls from the Wi-Fi remote by caching them using Charles proxy and later calling the same end-points from my OpenHAB system, but it turned out only a few API endpoints are being discovered by Charles proxy. I don’t know why is this happening, but right now I am just stuck with the automated IR remote. It works, and the TV can be controlled from OpenHAB, and it uses MQTT. Although it can be used to use every key of the remote using MQTT, it doesn’t seem that useful as they will add delay. I will be posting the details about it on a video, but I have posted the ESP8266/ m sketch and the codes of the remote in this post.

Decoding the remote

To decode the remote I used an Arduino UNO module with an IR receiver TSOP1738. The connection is pretty simple and doesn’t need any other components apart from the receiver. I used Arduino-IRremote library by Rafi Khan to decode the remote. I used simple example code IRrecvDumpV2.ino provided in the library to get the coded w.r.t pressed button. And it works like a charm. Below are the codes for the remote buttons and if you want you can use them directly,

On/Off:

5E7DB3DC (32 bits)

Timing[23]: +1050, - 550 + 600, - 600 + 600, -1450 + 600, -1450 + 600, - 550 + 600, -1450 + 600, - 600 + 600, -1450 + 600, - 600 + 550, -1500 + 550, -1450 + 600

unsigned int rawData[23] = {1050,550, 600,600, 600,1450, 600,1450, 600,550, 600,1450, 600,600, 600,1450, 600,600, 550,1500, 550,1450, 600};

UP:

6212287 (32 bits)

Timing[23]: +1050, - 550 + 600, -1200 + 550, - 600 + 600, - 900 + 550, -1200 + 600, - 550 + 600, - 600 + 600, - 850 + 600, - 900 + 600, -1150 + 600, -1450 + 600

unsigned int rawData[23] = {1050,550, 600,1200, 550,600, 600,900, 550,1200, 600,550, 600,600, 600,850, 600,900, 600,1150, 600,1450, 600};

Down: 

DE3AA631 (32 bits) 

Timing[23]: +1000, - 600 + 600, -1150 + 600, - 600 + 600, - 850 + 600, -1150 + 600, - 600 + 600, - 600 + 600, - 850 + 600, -1150 + 600, -1150 + 600, - 600 + 600 

unsigned int rawData[23] = {1000,600, 600,1150, 600,600, 600,850, 600,1150, 600,600, 600,600, 600,850, 600,1150, 600,1150, 600,600, 600};

Enter:

76A77416 (32 bits) 

Timing[23]: +1000, - 600 + 600, -1150 + 600, - 600 + 550, - 900 + 600, -1150 + 600, - 600 + 600, - 550 + 600, -1450 + 600, - 900 + 550, - 600 + 600, -1450 + 600 

unsigned int rawData[23] = {1000,600, 600,1150, 600,600, 550,900, 600,1150, 600,600, 600,550, 600,1450, 600,900, 550,600, 600,1450, 600};

Right:

69893291 (32 bits) 

Timing[23]: +1050, - 550 + 600, -1150 + 600, - 600 + 600, - 850 + 600, -1200 + 600, - 550 + 600, - 600 + 600, -1450 + 600, - 550 + 600, - 600 + 600, -1150 + 600 

unsigned int rawData[23] = {1050,550, 600,1150, 600,600, 600,850, 600,1200, 600,550, 600,600, 600,1450, 600,550, 600,600, 600,1150, 600};

Left: 

EA58E625 (32 bits) 

Timing[23]: +1050, - 550 + 600, -1200 + 550, - 600 + 600, - 900 + 550, -1200 + 600, - 550 + 600, - 600 + 600, -1150 + 600, -1450 + 600, - 850 + 600, - 900 + 600 

unsigned int rawData[23] = {1050,550, 600,1200, 550,600, 600,900, 550,1200, 600,550, 600,600, 600,1150, 600,1450, 600,850, 600,900, 600};

Menu:

F574DC41 (32 bits) 

Timing[23]: +1000, - 600 + 600, -1150 + 600, - 600 + 600, - 850 + 600, -1200 + 550, - 600 + 600, - 600 + 600, - 850 + 600, - 600 + 600, -1150 + 600, -1150 + 600 

unsigned int rawData[23] = {1000,600, 600,1150, 600,600, 600,850, 600,1200, 550,600, 600,600, 600,850, 600,600, 600,1150, 600,1150, 600};

Back:

EB58E7B6 (32 bits) 

Timing[23]: +1000, - 600 + 600, -1150 + 600, - 600 + 600, - 850 + 600, -1150 + 600, - 600 + 600, - 600 + 550, - 900 + 600, -1450 + 600, -1150 + 600, - 850 + 600 

unsigned int rawData[23] = {1000,600, 600,1150, 600,600, 600,850, 600,1150, 600,600, 600,600, 550,900, 600,1450, 600,1150, 600,850, 600};

Home:

F874E0F8 (32 bits) 

Timing[23]: +1000, - 600 + 600, -1150 + 600, - 600 + 600, - 850 + 600, -1200 + 550, - 600 + 600, - 600 + 600, -1150 + 600, - 600 + 550, - 900 + 600, -1150 + 600 

unsigned int rawData[23] = {1000,600, 600,1150, 600,600, 600,850, 600,1200, 550,600, 600,600, 600,1150, 600,600, 550,900, 600,1150, 600};

Vol Up:

8753BA5C (32 bits) 

Timing[23]: +1000, - 600 + 600, -1150 + 600, - 600 + 600, - 850 + 600, -1150 + 600, - 600 + 600, - 600 + 550, -1450 + 600, -1200 + 550, - 600 + 600, - 600 + 600 

unsigned int rawData[23] = {1000,600, 600,1150, 600,600, 600,850, 600,1150, 600,600, 600,600, 550,1450, 600,1200, 550,600, 600,600, 600};

Vol Down:

8453B5A5 (32 bits) 

Timing[23]: +1050, - 550 + 600, -1150 + 600, - 600 + 600, - 850 + 600, -1200 + 550, - 600 + 600, - 600 + 600, -1450 + 550, -1450 + 600, - 600 + 600, - 850 + 600 

unsigned int rawData[23] = {1050,550, 600,1150, 600,600, 600,850, 600,1200, 550,600, 600,600, 600,1450, 550,1450, 600,600, 600,850, 600};

After getting the byte streams for each button, I used those with an ESP8266. An IR LED is used with the ESP8266 to act as an remote. The OpenHAB server communicates to the ESP8266 using MQTT .  The code is pretty simple and use copule of libraries like the pubsubclient and IRremoteESP8266.

ESP8266 Sketch
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>

// Update these with values


const char* ssid = "___SSID_______";
const char* password = "___PWD_____";
const char* mqtt_server = "192.168.0.7";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

IPAddress ip(192, 168, 0, 163); 
IPAddress gateway_dns(192, 168, 0, 1);
//Ir Remote Parameters
int khz = 38;
const uint16_t kIrLed = 4;  // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRsend irsend(kIrLed);

uint16_t onButton[23] = {1050,550, 600,600, 600,1450, 600,1450, 600,550, 600,1450, 600,600, 600,1450, 600,600, 550,1500, 550,1450, 600}; //AnalysIR Batch Export (IRremote) - RAW
   

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.config(ip, gateway_dns, gateway_dns); 
  
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    if(strcmp(topic,"home/hall/tv/power")==0){
      Serial.println("On");
      irsend.sendRaw(onButton, 23, khz);
    }
    digitalWrite(status_led, HIGH);
    
  } else {
    if(strcmp(topic,"home/hall/tv/power")==0){
      Serial.println("Off");
      irsend.sendRaw(onButton, 23, khz);
    }
    digitalWrite(status_led, LOW);
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "lens_5kchta2dWhdRS2AQz0TeTuhplPE";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
     // client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("home/hall/tv/power");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(status_led, OUTPUT); 
  pinMode(input_pin, INPUT_PULLUP);
  pinMode(load1, OUTPUT); 
  pinMode(load2, OUTPUT); 
  pinMode(load3, OUTPUT); 
  pinMode(load4, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}
boolean lastStaus=false;
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

 

Related posts

Leave a Comment