<article-heading title="Media center remote: Kodi integration" is-published="true" updated-date="2021-09-04" /> <p class="article-description"> After integrating the <a data-article="media-center-remote/infrared-receiver">infrared receiver</a>, the nest activity for the <a data-article="media-center-remote">media center remote</a> is adding automations for reacting to infrared signals by dispatching JSON-RPC calls to Kodi. </p> <p>The goals of this stage are to:</p> <ul> <li>Use a HTTP Request integration to POST to a JSON-RPC endpoint on Kodi.</li> <li>Send different RPC calls depending on the incoming infrared signal received.</li> </ul> <h2>Kodi RPC endpoint</h2> <p> The <a href="https://kodi.wiki/view/JSON-RPC_API/v12">Kodi JSON-RPC API</a> supports a huge variety of method calls, notifications and batch requests. The <code class="inline">Input.ExecuteAction</code> method is the best way to simulate actions from a remote controller. </p> <p>For example, this call simulates pressing "down" on a remote controller:</p> <pre class="prettyprint" v-pre="v-pre"> <code class="lang-sh">curl --request POST \ --url http://kodi-instance:8080/jsonrpc \ --header 'Content-Type: application/json' \ --data '{ "jsonrpc": "2.0", "method": "Input.ExecuteAction", "params": { "action": "down" }, "id": "0" }'</code> </pre> <h2>ESPHome configuration</h2> <p> Highlighting the differences from before, this configuration: </p> <ol> <li>Runs an automation when an "lg" infrared signal is received that updates a "command_for_kodi" sensor to track the command to be sent to Kodi</li> <li>Runs an automation when the "command_for_kodi" is updated, which dispatches a JSON-RPC command to Kodi</li> </ol> <h3><code class="inline">media-center-remote.yaml</code></h3> <pre class="prettyprint" v-pre="v-pre"> <code class="lang-yaml"># ... http_request: useragent: esphome/device timeout: 10s text_sensor: # This platform sensor gets updated when a signal is decoded that # should be used to trigger a JSON-RPC call on Kodi. - platform: template id: command_for_kodi internal: true # Do not expose to Home Assistant on_value: - http_request.post: url: !secret kodi_http_request_url headers: Content-Type: application/json # Using a lambda to generate this body, as the yaml doesn't support nested JSON json: |- root["jsonrpc"] = "2.0"; root["id"] = 0; root["method"] = "Input.ExecuteAction"; JsonObject& params = root.createNestedObject("params"); params["action"] = x; remote_receiver: pin: number: GPIO2 inverted: true # The Car MP3 remote controller signals can be interpreted as LG codes, # so let's just pretend it's an LG remote controller. dump: - lg on_lg: # In this lambda, x is an LGData. x.data is a uint32_t that identifies the button pressed. - lambda: |- switch (x.data) { // ... case 0x00FF22DD: // 03 id(command_for_kodi).publish_state("left"); break; case 0x00FF02FD: // 04 id(command_for_kodi).publish_state("select"); break; case 0x00FFC23D: // 05 id(command_for_kodi).publish_state("right"); break; // ... }</code> </pre> <h3>Log output</h3> <p> Powering up the device and pressing buttons on the remote controller yields logs similar to the following: </p> <pre class="prettyprint" v-pre="v-pre"><code>... [22:32:05][D][text_sensor:015]: 'Command for Kodi': Sending state 'left' [22:32:05][D][http_request:074]: HTTP Request completed; URL: http://kodi-instance:8080/jsonrpc; Code: 200 [22:32:06][D][text_sensor:015]: 'Command for Kodi': Sending state 'right' [22:32:06][D][http_request:074]: HTTP Request completed; URL: http://kodi-instance:8080/jsonrpc; Code: 200</code></pre> <h2>Next steps</h2> <p> Controlling Kodi is good, but we can go one step further and control the television in Stage 3: <a data-article="media-center-remote/television-integration">Television integration</a>. </p> <p> This article is part of the <a data-article="media-center-remote">Media center remote</a> set. If you have any feedback or questions related to this article, please reply to <a href="https://twitter.com/TassSinclair/status/1434156531663048707">my post on Twitter</a>. </p>