COAP endpoints on IKEA Trådfri

Written by vidarlo on 20170401 in english and hardware and software with 18 comments.

So, I’m talking to the Trådfri GW. It turns out that my initial research was correct. It is talking coaps. I used californium.tools/ to talk to it, requesting coaps://10.0.3.25/.well-known/core. It actually seems to implement the standard rather well 🙂 I had to use -psk and enter the security key, printed on a label under the gw itself.
UPDATE: Leave PSK identity blank.

==[ CoAP Response ]============================================
MID : 115
Token : 170a801bb0362002
Type : ACK
Status : 2.05
Options: {"Content-Format":"application/link-format"}
Payload: 560 Bytes
---------------------------------------------------------------
<//15001/65536>;ct=0;obs,<//15001/65538>;ct=0;obs,<//15001/65537>;ct=0;obs,<//15004/139121>;ct=0;obs,<//15005/139121>;ct=0;obs,<//15005/139121/203361>;ct=0;obs,<//15005/139121/221937>;ct=0;obs,<//15005/139121/217246>;ct=0;obs,<//15005/139121/202872>;ct=0;obs,<//15001>;ct=0;obs,<//15001/reset>;ct=0,<//status>;ct=0;obs,<//15005>;ct=0;obs,<//15004>;ct=0;obs,<//15004/add>;ct=0,<//15004/remove>;ct=0,<//15006>;ct=0;obs,<//15011/15012>;ct=0;obs,<//15011/9034>;ct=0,<//15011/9030>;ct=0,<//15011/9031>;ct=0,<//15011/9063>;ct=0,<//15011/9033>;ct=0,<//15010>;ct=0;obs
===============================================================
Time elapsed (ms): 1251

Querying each of the endpoints yielded the following:

/15001/65536


{"9054":0,"9001":"Remote","5750":0,"9002":1490983329,"9020":1490985746,"9003":65536,"15009":[{"9003":0}],"9019":0,"3":{"1":"TRADFRI remote control","0":"IKEA of Sweden","2":"","3":"1.1.1.1-5.7.2.0","6":3,"9":100}}

This is obviously the remote control unit.

/15001/65538

{"9054":0,"9001":"K","5750":2,"9002":1490992930,"9020":1491052948,"9003":65538,"9019":0,"3":{"1":"TRADFRI bulb E27 WS opal 980lm","0":"IKEA of Sweden","2":"","3":"1.1.1.1-5.7.2.0","6":1},"3311":[{"9003":0}]}

This is one of the bulbs. I believe it is the one named “K” in the IKEA app… 🙂

/15001/65537

{"9054":0,"9001":"LR","5750":2,"9002":1490983446,"9020":1491055861,"9003":65537,"9019":1,"3":{"1":"TRADFRI bulb E27 WS opal 980lm","0":"IKEA of Sweden","2":"","3":"1.1.1.1-5.7.2.0","6":1},"3311":[{"5850":1,"5851":254,"5707":0,"5708":0,"5709":33135,"5710":27211,"9003":0,"5711":0,"5706":"efd275"}]}

Another of the bulbs – I currently have two. This is obviously the one in the living room – LR. This is powered on, whilst the other one has main power removed. The powered on one (this) returns more data than the one that is powered down.

/15004/139121


{"9001":"TRADFRI group","9039":203361,"9002":1490983341,"9003":139121,"5850":0,"5851":0,"9018":{"15002":{"9003":[65536,65537,65538]}}}

I have defined one group, containing both bulbs. The 9003 array contains the devices in this group (remote control and two bulbs).

/15011/15012

This is information about ntp server.

{"9023":"pool.ntp.org","9059":1491062713,"9060":"2017-04-01T16:05:13.055176Z","9062":0,"9061":0,"9066":0,"9029":"1.0.0004","9054":0,"9055":0,"9069":0,"9071":1}

You can change to your own ntp-server by issuing a set request, with pool.ntp.org replaced by your own. Quite neat actually.

/139121/221937


{"9001":"RELAX","9002":1490983341,"9003":221937,"9057":1,"9068":1,"15013":[{"5850":1,"5851":25,"5707":0,"5708":0,"5709":33135,"5710":27211,"9003":65537,"5711":0,"5706":"efd275"},{"9003":65538}]}

This is one of the presets for mood lightning in the app. Reddish with low intensity.

Oookay, that’s enough about the endpoints. The rest is mostly a continuation. Let’s go back to the kitchen light, which I’ve now powered on, put to max level and bright white (highest color temperature). As expected it now replies with more data:

{"9054":0,"9001":"K","5750":2,"9002":1490992930,"9020":1491052948,"9003":65538,"9019":1,"3":{"1":"TRADFRI bulb E27 WS opal 980lm","0":"IKEA of Sweden","2":"","3":"1.1.1.1-5.7.2.0","6":1},"3311":[{"5850":1,"5851":254,"5707":0,"5708":0,"5709":24930,"5710":24694,"9003":0,"5711":250,"5706":"f5faf6"}]}

Dimmed to minimum:

{"9054":0,"9001":"K","5750":2,"9002":1490992930,"9020":1491052948,"9003":65538,"9019":1,"3":{"1":"TRADFRI bulb E27 WS opal 980lm","0":"IKEA of Sweden","2":"","3":"1.1.1.1-5.7.2.0","6":1},"3311":[{"5850":1,"5851":12,"5707":0,"5708":0,"5709":24930,"5710":24694,"9003":0,"5711":250,"5706":"f5faf6"}]}

Here, the parameter 5851 changed from 254 to 12. This is likely to be the light level output. Let’s try again, with the bulb set to 50%:

{"5850":1,"5851":127,"5707":0,"5708":0,"5709":24930,"5710":24694,"9003":0,"5711":250,"5706":"f5faf6"}

Yep, 5851 is the dimming level.

And now, repeat with different colour temperature (middle setting from app):

{"5850":1,"5851":127,"5707":0,"5708":0,"5709":30140,"5710":26909,"9003":0,"5711":0,"5706":"f1e0b5"}

The intensity is still 127, but three other parameters, 5709-5711. In addition 5706 changed – which it did not for the previous changes. Let’s try a put, changing the 127 to 254:

java -jar cf-client-1.1.0-APSHOT.jar -psk PUT coaps://10.0.3.25//15001/65538 '{"9054":0,"9001":"K","5750":2,"9002":1490992930,"9020":1491052948,"9003":65538,"9019":1,"3":{"1":"TRADFRI bulb E27 WS opal 980lm","0":"IKEA of Sweden","2":"","3":"1.1.1.1-5.7.2.0","6":1},"3311":[{"5850":1,"5851":254,"5707":0,"5708":0,"5709":30140,"5710":26909,"9003":0,"5711":0,"5706":"f1e0b5"}]}'
[...]
==[ CoAP Response ]============================================
MID : 190
Token : 4bde3ee89d815913
Type : ACK
Status : 2.04
Options: {}
Payload: 0 Bytes
===============================================================
Time elapsed (ms): 1487

Yup, promptly dimmed up. Sending only the 3311 did nothing – it appears I have to send the entire thing back to the bulb for some reason.

That’s it for now. Some pointers on how to talk to the lights.

Update: There’s some discussion at ha-bridge’s github about this topic. Also note the first comment – I didn’t include this information, but yes – the PSK identity should be left blank, and the key is the one printed on the label of the gw.

18 Responses to “COAP endpoints on IKEA Trådfri

  1. Hi, great work, I was just about to get down to trying to work this out. I’d got as far noticing it was CoAP and DTLS but no further yet (https://gist.github.com/hardillb/4ce9fc493b792806e39f7fae4b7c28a7). CoAP is new to me so finding out it’s somewhat self describing is really useful.

    I’m was trying to reproduce this and I was hitting a problem until I tried leaving the PSK identity empty, so just thought I’d leave a note for anybody else who finds this.

    Thanks

  2. Hi, great work, I tried following your steps but I’m not sure how to use the cf-client.

    I tried following command.
    java -jar cf-client-1.0.1.jar -psk DISCOVER coaps://MY.TRADFRI.IP/.well-known/core

    I’m sure the tool should ask for IDENTITY and SECRET but I after a minute I only get “Request timed out”.
    The IP I enter is definitely correct so I’m doing something wrong but what?

  3. It does indeed sound as Ikea if have choosen to base their implementation on OMA (Open Mobile Alliance) and Eclipse recommended standard of those three logical components; LwM2M (Lightweight M2M) protocol stack with CoAP and DTLS layers .

    “Lightweight M2M (LWM2M) is a system standard in the Open Mobile Alliance. It includes DTLS, CoAP, Block, Observe, SenML and Resource Directory and weaves them into a device-server interface along with an Object structure.”

    http://openmobilealliance.org/data-models-for-the-internet-of-things/
    https://connect2.io/open-mobile-alliance-lightweightm2m-oma-lwm2m/
    http://openmobilealliance.org/constrained-application-protocol-coap-is-iots-modern-protocol/
    http://openmobilealliance.org/data-models-for-the-internet-of-things/
    https://connect2.io/open-mobile-alliance-lightweightm2m-oma-lwm2m/
    https://iot.eclipse.org/standards/
    https://eclipse.org/community/eclipse_newsletter/2014/february/article2.php
    https://www.eclipsecon.org/na2014/sites/default/files/slides/Eclipsecon%20NA14%20-%20One%20protocol%20to%20rule%20them%20all-%20(1).pdf

    The Wakaama project (from Eclipse) covers the LWM2M Protocol, CoAP, and DTLS layers of the LwM2M protocol stack for all three logical components. Wakaama is not a library but files to be built with an application. The Eclipse Wakaama project provides a C portable framework for building LWM2M clients and/or servers. The source code of Wakaama is available from the project webpage. It is written in C and designed to be portable on POSIX compliant systems.

    [*] http://www.eclipse.org/wakaama/

    You can also build the “dtls” branch of libcoap from:

    https://github.com/obgm/libcoap/tree/dtls

    Californium is another CoAP client from Eclipse (programmed in Java) which also supports DTLS

    https://eclipse.org/californium/
    https://github.com/cetic/6lbr/wiki/Example-:-Dtls-Coap-Server
    https://people.inf.ethz.ch/mkovatsc/resources/californium/cf-dtls-thesis.pdf

    And the Eclipse Leshan project provides a Java implementation of LwM2M, allowing to build LwM2M servers and clients. The source code of Leshan is available from the project webpage.

    http://www.eclipse.org/leshan/

  4. Btw – if needed, it is pretty easy to decrypt the traffic from the ikea app to the bridge using wireshark…

    Preferences -> Protocols -> DTLS -> preshared key (This must be entered as hex) also: im using wireshark 2.3.0~rc0

  5. https://community.home-assistant.io/t/ikea-tradfri-gateway-zigbee-very-basic-working-implementation/14788/19

    pautomate from the Home Assistant community put together a very simple implementation for his Raspberry Pi. (“Taking no credit of all the hard work others have put in and just put my code here if you want to play around”):

    First installed the libcoap-library as such:

    apt-get install libtool

    git clone –recursive https://github.com/obgm/libcoap.git
    cd libcoap
    git checkout dtls
    git submodule update –init –recursive
    ./autogen.sh
    ./configure –disable-documentation –disable-shared
    make
    sudo make install

    pautomate put together a very simple Python-script that execute by running shell_commands:

    https://github.com/ggravlingen/home-assistant/blob/master/extraconfig/python_code/ikea.py

    You then run the code by invoking:

    python ikea.py “65537” “100” “Yellow”

    Or, from within Home assistant as a shell command:

    ikealight_off: ‘/usr/bin/python3 /home/homeassistant/.homeassistant/extraconfig/python_code/ikea.py “65537” “0” “Yellow”‘

  6. FYI, looks like ha-bridge issue 570 have become a collective point for links and notes about progress around different integrations and implementations

    https://github.com/bwssytems/ha-bridge/issues/570

    Some of the new links to code implementations in different programming languages include:

    https://github.com/stenehall/homebridge-ikea

    https://gist.github.com/hvanderlaan/3d8e11869f86ba94d9d6df1c815af3aa

    https://github.com/ggravlingen/home-assistant/blob/master/extraconfig/python_code/ikea.py

    https://gist.github.com/r41d/65be2c7a111ac6c32f24d762ba38612c

    https://community.home-assistant.io/t/ikea-tradfri-gateway-zigbee-very-basic-working-implementation/14788/20

    r41d found an intersting class in the Android App, after decompliling with apktool, it is located in

    com/ikea/tradfri/lighting/ipso/IPSOObjects.java.

    Here’s his upload: http://sprunge.us/CCQF

  7. Home Assistant developers ( ggravlingen / pautomate, balloob & turbokongen ) looks to be making great progress with their collaberation on a Python class to communicate with the Ikea Trådfri Gateway, and also extracted that code from the platform into a standalone Python library

    https://github.com/ggravlingen/python-openikeatradfri

    More discussion on that in the Home Assistant Community forum

    https://community.home-assistant.io/t/ikea-tradfri-gateway-zigbee-very-basic-working-implementation/14788/

  8. Jaime Jiménez (from the company Ericsson) who is an active member of the IPSO Alliance’s working group, especially the Semantic WG that published the IPSO Smart Object Guidelines, posted this great teardown of the Ikea Trådfri implementation:

    http://jaimejim.github.io/tradfri/

    He also shared a couple of links to related articles he posted earlier:

    http://jaimejim.github.io/lwm2m-yang/

    http://jaimejim.github.io/coap-functionality-lwm2m/

    Also checkout the IoTSI Workshop as a reference:

    https://www.iab.org/activities/workshops/iotsi/

    Interestingly enough Michael Koster (who is the main author of these IPSO Objects) posted a comment to Jaime’s post staying: “Great move on IKEA’s part here. Too bad we hadn’t published the IPSO lighting objects yet. Maybe we can talk them into registering the new identifiers with OMNA.”.

    He referenses another that good framework written by Michael Koster (the main author of the data models and IPSO Objects that Ikea Trådfri uses):

    https://github.com/connectIOT/iottoolkit/

  9. Any clue what incantation Java is missing when it goes “java.io.FileNotFoundException: certs/trustStore.jks” ? Been ages since I messed with the crypto-stuff in Java.

  10. Thank you very much for your word!

    Today (oh no, it’s after midnight already… So it was yesterday) I found the new Tradfri RGB-Bulb in an IKEA-Store in Heerlen (Netherlands). I got this information:

    {“9001″:”TRADFRI bulb E27 CWS opal 600lm”,”9002″:1503174416,”9020″:1503174416,”9003″:65541,”9054″:0,”5750″:2,”9019″:1,”3″:{“0″:”IKEA of Sweden”,”1″:”TRADFRI bulb E27 CWS opal 600lm”,”2″:””,”3″:”1.3.002″,”6″:1}

    The colours that can be choosen by the remote control are very limited (only 8 different colours available?!?), so I treid to set the colours by command line. And I did it:

    Parameter 5709 defines the colorX-value, Parameter 5710 the colorY-value within the CIE 1931 Color Space, where colorX is given by x * 65536 within the range 0 to 65279 (colorY the same way). Some examples:

    green:
    coap-client -m put -u “Client_identity” -k “” -e ‘{ “3311”: [{“5850″:1,”5851″:100,”5708″:0,”5707″:0,”5709″:19055,”5710″:38666,”5711″:0,”9003”:0}] }’ “coaps://192.168.178.62:5684/15001/”

    rot:
    coap-client -m put -u “Client_identity” -k “” -e ‘{ “3311”: [{“5850″:1,”5851″:100,”5708″:0,”5707″:0,”5709″:45875,”5710″:18350,”5711″:0,”9003”:0}] }’ “coaps://192.168.178.62:5684/15001/65541”

    gelb:
    coap-client -m put -u “Client_identity” -k “” -e ‘{ “3311”: [{“5850″:1,”5851″:100,”5708″:0,”5707″:0,”5709″:36045,”5710″:32768,”5711″:0,”9003”:0}] }’ “coaps://192.168.178.62:5684/15001/65541”

    Hope that helps as soon as the RGB-Bulbs are available!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.