Remote Receiver for KODI
 Page :   [ 1 ]    [ 2 ]    [ 3 ]    [ 4 ]    [ 5 ]  

Here is the code running on the ESP.  This takes the serial data from the "Arduino" and does something useful with it.  In this case it will form up some HTTP/JSON requests to send via WiFi to the KODI API.


// Uses the Arduino JSON library by Benoit Blanchon
// https://github.com/bblanchon/ArduinoJson

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>

#define SERVER_URL "http://YourKodiAddress/jsonrpc";

ESP8266WiFiMulti WiFiMulti;

SoftwareSerial mySerial(5, 4); // RX, TX

int serialData = 0;

int LED_PIN = 16;

void setup() {

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
    
  Serial.begin(9600);
  
  while (!Serial) {
    // wait serial port initialization
  }

  mySerial.begin(4800);

  WiFiMulti.addAP("YourAccessPoint", "YourWifiKey");

  delay(2000);

  while(!((WiFiMulti.run() == WL_CONNECTED))) {  

    digitalWrite(LED_PIN, HIGH);
    delay(500);
    digitalWrite(LED_PIN, LOW);
    delay(500);

  }

}



void loop() {

  if(((WiFiMulti.run() == WL_CONNECTED))) { 
    digitalWrite(LED_PIN, LOW);
  } else {
    digitalWrite(LED_PIN, HIGH);
  }

  if (mySerial.available() > 0){
    
    serialData = mySerial.read();
    sendCommand(serialData);
  
  }

  yield();

}



void sendCommand(int value){

  if ((serialData == 6) || (serialData == 7)){

    int playerid = getActivePlayerId();

    if (playerid > 0){
      if (serialData == 6){
        playerMethod("Player.PlayPause", playerid);
      }
      if (serialData == 7){
        playerMethod("Player.Stop", playerid);
      }
    }
  
  }


  if ((serialData >= 1) && (serialData <= 4)){

    if (isFullscreen()){
      
      if(notPlayTvAndHasMenu()){

        int playerid = getActivePlayerId();

        if (playerid > 0){

          if (serialData == 1){ // up
            seekMethod("bigforward", playerid);
          } 
          if (serialData == 2){ // down
            seekMethod("bigbackward", playerid);
          } 
          if (serialData == 3){ // left
            seekMethod("smallbackward", playerid);
          }          
          if (serialData == 4){ // right
            seekMethod("smallforward", playerid);
          }
  
        }
        
      }
      
    }

  }

  if ((serialData >= 1) && (serialData <= 7)){

    if (serialData == 1){ // up
      inputMethod("Input.Up");
    }
    if (serialData == 2){ // down
      inputMethod("Input.Down");
    }    
    if (serialData == 3){ // left
      inputMethod("Input.Left");
    }
    if (serialData == 4){ // right
      inputMethod("Input.Right");
    }
    if (serialData == 5){ // select
      inputMethod("Input.Select");
    }
    if (serialData == 7){ // back
      inputMethod("Input.Back");
    }

  }
  
}




int getActivePlayerId(){

  int ret = 0;

  String jsonString;

  StaticJsonBuffer<300> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  
  root["method"] = "Player.GetActivePlayers";
  root["id"] = millis();
  root["jsonrpc"] = "2.0";
  
  JsonObject& params = root.createNestedObject("params");

  root.printTo(jsonString);

  if((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    String url = SERVER_URL;
    url += "?request=";
    url += urlencode(jsonString);

    http.begin(url); 

    int httpCode = http.GET();

    if(httpCode > 0) {

      if(httpCode == HTTP_CODE_OK) {
      
        String payload = http.getString();
        
        StaticJsonBuffer<300> jsonResultBuffer;
        JsonObject& resultRoot = jsonResultBuffer.parseObject(payload);

        if (resultRoot.success()) {

          if (resultRoot.containsKey("result")){

            int counter[10];
            int arrayCount = resultRoot["result"].asArray().copyTo(counter);

            if (arrayCount > 0){

              for (int i = 0; i < arrayCount; ++i){

                JsonObject& resultObject = resultRoot["result"][i];

                if (resultObject.containsKey("playerid") && resultObject.containsKey("type")){

                  int playerid = resultObject["playerid"].as<int>();
                  String type = resultObject["type"].as<String>();

                  if ((playerid > 0) && (type == "video")){
                    ret = playerid;
                    break;
                  }
  
                }
                
              }
              
            }

          }

        }
                
      }
                
    }

    http.end();

  }

  return ret;

}



bool notPlayTvAndHasMenu(){

  bool ret = false;

  String jsonString;

  StaticJsonBuffer<300> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  
  root["method"] = "XBMC.GetInfoBooleans";
  root["id"] = millis();
  root["jsonrpc"] = "2.0";
  
  JsonObject& params = root.createNestedObject("params");
  JsonArray& properties = params.createNestedArray("booleans");
  properties.add("VideoPlayer.HasMenu");
  properties.add("Pvr.IsPlayingTv");

  root.printTo(jsonString);

  if((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    String url = SERVER_URL;
    url += "?request=";
    url += urlencode(jsonString);

    http.begin(url); 

    int httpCode = http.GET();

    if(httpCode > 0) {

      if(httpCode == HTTP_CODE_OK) {
      
        String payload = http.getString();
        
        StaticJsonBuffer<300> jsonResultBuffer;
        JsonObject& resultRoot = jsonResultBuffer.parseObject(payload);

        if (resultRoot.success()) {

          if (resultRoot.containsKey("result")){
    
            JsonObject& resultObject = resultRoot["result"];

            if (resultObject.containsKey("Pvr.IsPlayingTv") && resultObject.containsKey("VideoPlayer.HasMenu")){

              bool playTV = resultRoot["result"]["Pvr.IsPlayingTv"].as<bool>();
              bool hasMenu = resultRoot["result"]["VideoPlayer.HasMenu"].as<bool>();

              if ((!playTV) && (!hasMenu)){
                ret = true;
              }
  
            }

          }

        }
                
      }
                
    }

    http.end();

  }

  return ret;

}



bool isFullscreen(){

  bool ret = false;

  String jsonString;

  StaticJsonBuffer<300> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  
  root["method"] = "GUI.GetProperties";
  root["id"] = millis();
  root["jsonrpc"] = "2.0";
  
  JsonObject& params = root.createNestedObject("params");
  JsonArray& properties = params.createNestedArray("properties");
  properties.add("currentwindow");
  properties.add("fullscreen");

  root.printTo(jsonString);

  if((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    String url = SERVER_URL;
    url += "?request=";
    url += urlencode(jsonString);

    http.begin(url); 

    int httpCode = http.GET();

    if(httpCode > 0) {

      if(httpCode == HTTP_CODE_OK) {
      
        String payload = http.getString();

        StaticJsonBuffer<300> jsonResultBuffer;
        JsonObject& resultRoot = jsonResultBuffer.parseObject(payload);

        if (resultRoot.success()) {

          if (resultRoot.containsKey("result")){
    
            JsonObject& resultObject = resultRoot["result"];

            if (resultObject.containsKey("fullscreen")){
      
              ret = resultRoot["result"]["fullscreen"].as<bool>();
  
            }

          }

        }
                
      }
                
    }

    http.end();

  }

  return ret;

}



void seekMethod(String value, int playerid){

  String jsonString;

  StaticJsonBuffer<300> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  
  root["method"] = "Player.Seek";
  root["id"] = millis();
  root["jsonrpc"] = "2.0";
  
  JsonObject& params = root.createNestedObject("params");
  
  params["playerid"] = playerid;
  params["value"] = value;

  root.printTo(jsonString);

  if((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    String url = SERVER_URL;
    url += "?request=";
    url += urlencode(jsonString);

    http.begin(url); 

    int httpCode = http.GET();

    if(httpCode > 0) {

      if(httpCode == HTTP_CODE_OK) {
      
        String payload = http.getString();
                
      }
                
    }

    http.end();

  }

}



void inputMethod(String methodName){

  String jsonString;

  StaticJsonBuffer<300> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  
  root["method"] = methodName;
  root["id"] = millis();
  root["jsonrpc"] = "2.0";
  
  JsonObject& params = root.createNestedObject("params");
 
  root.printTo(jsonString);

  if((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    String url = SERVER_URL;
    url += "?request=";
    url += urlencode(jsonString);

    http.begin(url); 

    int httpCode = http.GET();

    if(httpCode > 0) {

      if(httpCode == HTTP_CODE_OK) {
      
        String payload = http.getString();
    
      }
                
    }

    http.end();

  }

  
}


 
void playerMethod(String methodName, int playerid){

  String jsonString;

  StaticJsonBuffer<300> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  
  root["method"] = methodName;
  root["id"] = millis();
  root["jsonrpc"] = "2.0";
  
  JsonObject& params = root.createNestedObject("params");
  
  params["playerid"] = playerid;

  root.printTo(jsonString);

  if((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    String url = SERVER_URL;
    url += "?request=";
    url += urlencode(jsonString);

    http.begin(url); 

    int httpCode = http.GET();

    if(httpCode > 0) {

      if(httpCode == HTTP_CODE_OK) {
      
        String payload = http.getString();
                
      }
                
    }

    http.end();

  }
  
}



String urlencode(String str)
{
  /*
  ESP8266 Hello World urlencode by Steve Nelson
  */  
    String encodedString="";
    char c;
    char code0;
    char code1;
    char code2;
    for (int i =0; i < str.length(); i++){
      c=str.charAt(i);
      if (c == ' '){
        encodedString+= '+';
      } else if (isalnum(c)){
        encodedString+=c;
      } else{
        code1=(c & 0xf)+'0';
        if ((c & 0xf) >9){
            code1=(c & 0xf) - 10 + 'A';
        }
        c=(c>>4)&0xf;
        code0=c+'0';
        if (c > 9){
            code0=c - 10 + 'A';
        }
        code2='\0';
        encodedString+='%';
        encodedString+=code0;
        encodedString+=code1;
        //encodedString+=code2;
      }
      yield();
    }
    return encodedString;
    
}

 

As you can see my needs for a remote are pretty simple.  I just watch videos so only need a few basic commands.  In the future I might flesh it out a bit and add some more functionality and clean up the code a little.

However for now I'm happy to have a "real" remote again! :)

 

(Page 5 of 5)