<article-heading
title="SYMFONISK Kodi remote"
is-published="true"
updated-date="2020-04-10"
/>
<p class="article-description">
IKEA's SYMFONISK and TRÅDFRI smart home products use Zigbee, so it's easy to integrate them into a
home automation solution with a supported Zigbee hub.
</p>
<p>
You can pair all of the devices to a TRÅDFRI gateway and connect that to Home Assistant, or use a custom hub
such as the CC2531 Zigbee sniffer acting as a Zigbee coordinator.
I already have the CC2531 Zigbee coordinator set up and connected to my Home Assistant, so after purchasing a
SYMFONISK sound remote I was ready to go.
</p>
<section class="hero">
<gallery-video src="/content/articles/symfonisk-kodi-remote/symfonisk-kodi-remote.mp4" type="video/mp4">
An example video from <a href="https://twitter.com/TassSinclair/status/1208686861507420161">my Twitter
post</a>
</gallery-video>
</section>
<h2>Interaction flow</h2>
<section class="hero">
<figure>
<img src="/content/articles/symfonisk-kodi-remote/data-flow-diagram.png"
alt="A diagram showing how a single message from the SYMFONISK remote is delivered by Home Assistant and forwarded to Kodi." />
</figure>
</section>
<h2>Devices</h2>
<section class="gallery previews-medium">
<figure>
<img src="/content/articles/symfonisk-kodi-remote/symfonisk-sound-remote.jpg" />
<figcaption>
SYMFONISK sound remote
<br /><a href="https://www.ikea.com/au/en/catalog/products/40370481/">from IKEA</a>
</figcaption>
</figure>
<figure>
<img src="/content/articles/symfonisk-kodi-remote/cc2531.jpg" />
<figcaption>
CC2531 Zigbee sniffer (coordinator)
<br /><a href="https://www.aliexpress.com/wholesale?catId=400103">from
Ali Express</a>
</figcaption>
</figure>
<figure>
<img src="/content/articles/symfonisk-kodi-remote/raspberry-pi-3-model-a-plus.jpg" />
<figcaption>
Raspberry Pi 3 Model A+ (Home Assistant host)
<br /><a href="https://www.raspberrypi.org/products/raspberry-pi-3-model-a-plus/">from Element
14</a>
</figcaption>
</figure>
<figure>
<img src="/content/articles/symfonisk-kodi-remote/raspberry-pi-3-model-b-plus.jpg" />
<figcaption>
Raspberry Pi 3 Model B+ (Kodi host)
<br /><a href="https://www.raspberrypi.org/products/raspberry-pi-3-model-b-plus/">from Element
14</a>
</figcaption>
</figure>
</section>
<p>
Which are set up as follows:
</p>
<ul>
<li>CC2531 sniffer running <a href="https://www.zigbee2mqtt.io/getting_started/flashing_the_cc2531.html">Zigbee2mqtt
CC2531
firmware</a></li>
<li>Raspberry Pi 3 Model A+ running <a href="https://www.home-assistant.io/">Home Assistant</a> and <a
href="https://www.zigbee2mqtt.io/">Zigbee2mqtt</a></li>
<li>Raspberry Pi 3 Model B+ running <a href="https://libreelec.tv/">LibreELEC</a>, which is a distribution
of <a href="https://kodi.tv/">Kodi</a> designed for Raspberry Pis</li>
</ul>
<h2>Payloads</h2>
<ul>
<li>SYMFONISK sound remote to CC2531 coordinator uses Zigbee messaging over Zigbee radio
<div>
<em>The structure of this payload is outside the scope of this blog post</em>
</div>
</li>
<li>CC2531 coordinator to Home Assistant uses JSON messages over local MQTT, for example:
<div>
<dl class="inline">
<dt>topic</dt>
<dd>
<code class="inline">zigbee2mqtt/ikea_symfonisk_dial_74d44a</code>
</dd>
</dl>
<dl class="inline">
<dt>payload</dt>
<dd>
<code
class="prettyprint lang-json inline">{"linkquality": 76, "rate": 195, "brightness": 209, "battery": 74, "action": "rotate_stop"}</code>
</dd>
</dl>
<em>Notice that the payload includes "brightness", this is calculated by the Zigbee2mqtt software and could
be interpreted as "volume".
</em>
</div>
</li>
<li>Home Assistant to Kodi uses JSON <abbr title="Remote Procedure Calls">RPC</abbr>s over HTTP (over WiFi),
for
example:
<div>
<dl class="inline">
<dt>header</dt>
<dd>
<code class="inline">POST http://kodi.local/jsonrpc?Application.SetVolume</code>
</dd>
</dl>
<dl class="inline">
<dt>body</dt>
<dd>
<code
class="prettyprint lang-json inline">[{"id": 1, "jsonrpc": "2.0", "method": "Application.SetVolume", "params": [50]}]</code>
</dd>
</dl>
</div>
</li>
</ul>
<h2>Connectivity</h2>
<h3>SYMFONISK sound remote to CC2531 controller</h3>
<p>
Syncing the remote to the controller is a similar process to syncing it with the TRÅDFRI gateway (holding down the
'sync' button on the remote for 10 seconds, nearby the controller).
</p>
<h3>Zigbee2mqtt processing</h3>
<p>
The remote is fairly chatty, so I took advantage of Zigbee2mqtt's debounce functionality to reduce the chatter,
making it easy to focus on important messages. In this case, I want to focus on unique "action" messages so I can
set the volume to a specific value when the remote has stopped rotating.
</p>
<pre class="prettyprint" v-pre="v-pre">$ cat ${ZIGBEE_2_MQTT}/configuration.yaml
<code class="lang-yaml">
homeassistant: true
permit_join: true
...
devices:
...
'0xccccccfffe74d44a':
friendly_name: ikea_symfonisk_remote_74d44a
debounce: 0.1
debounce_ignore:
- action
...</code></pre>
<h3>Home Assistant integration with Kodi</h3>
<p>
Kodi is registered in Home Assistant as a Media Player integration.
</p>
<pre class="prettyprint" v-pre="v-pre">$ cat ${HOME_ASSISTANT}/configuration.yaml
<code class="lang-yaml">
...
media_player:
- platform: kodi
host: kodi.local
port: 80
...</code>
</pre>
<h3>Home Assistant automation</h3>
<p>
I initially had problems with automating this process, as capturing each message as a device update triggered the
automation too
frequently
and flooded Kodi's RPC API. A better way around this was to limit the updates passed through from Zigbee2mqtt (see
above) and then trigger the automation from the MQTT message itself instead of the device as registered by Home
Assistant.
</p>
<p>
The automations process the following scenarios:
</p>
<ol>
<li>When a message comes through with the "
<code class="inline">play_pause</code>" action, it means that the remote has been pressed
once. Send a "
<code class="inline">media_play_pause</code>"
command to Kodi. This will pause playback for media that is playing, or continue playback for media that is
paused.</li>
<li>When a message comes through with the "
<code class="inline">rotate_stop</code>" action, it means that the remote was previously
being rotated and has now stopped. Check the "
<code class="inline">brightness</code>" attribute and send a
"
<code class="inline">volume_set</code>" command to Kodi. This will set the volume to an absolute value
between 0.00 (muted) and 1.00 (loudest).
</li>
</ol>
<pre class="prettyprint" v-pre="v-pre">$ cat /home/homeassistant/.homeassistant/automations.yaml
<code class="lang-yaml">
...
- id: kodi_play_pause
alias: Kodi play/pause
trigger:
- platform: mqtt
topic: zigbee2mqtt/ikea_symfonisk_remote_74d44a
condition:
- condition: template
value_template: '{{ trigger.payload_json.action == ''play_pause'' }}'
action:
- service: media_player.media_play_pause
data:
entity_id: media_player.kodi
- id: kodi_set_volume
alias: Kodi set volume
trigger:
- platform: mqtt
topic: zigbee2mqtt/ikea_symfonisk_remote_74d44a
condition:
- condition: template
value_template: '{{ trigger.payload_json.action == ''rotate_stop'' }}'
action:
- service: media_player.volume_set
data_template:
entity_id: media_player.kodi
volume_level: '{{ (trigger.payload_json.brightness / 255) | round(2) }}'
...</code></pre>
<h2>Wrap-up</h2>
<p>
There are other ways of using the SYMFONISK sound remote to control media players through Home Assistant. This
example sets volume when the remote is no longer rotating, but it is also possible to send incremental
<code class="inline">volume_up</code> and
<code class="inline">volume_down</code> commands while the remote is rotating (just be careful not to send too many
updates). It is also possible to capture double-press and triple-press events and associate them with other
automations.
</p>
<p>
If you have any feedback or questions related to this article, please reply to <a
href="https://twitter.com/TassSinclair/status/1213778061176344577">my post on Twitter</a>.
</p>
<p>
This article is part of the <a data-article="home-automation">Home automation</a> set.
</p>