The new IKEA Dirigera hub

Hello there dear community!

IKEA has recently launched DIRIGERA – the Matter ready hub for smart products. It will replace TRÅDFRI.

I got mine yesterday and I just realized it’s too new to already be supported by an add-on in OpenHAB.

I have no experience in writing add-ons so I’ll have to pass but I’m sure someone will eventually initiate the development of an add-on for it. Meanwhile I’ll figure out how to integrate it in my home automation as the product app is more about remote control. :grinning:

Cheers!

1 Like

There appears to be no published API. There are a couple of github repos who are reverse engineering the API but they are pretty basic right now and brittle. It will probably be some time before enough is discovered to build an add-on for OH.

2 Likes

Shameless advertising for my repo: DirigeraClient
It’s not feature-complete yet, but many things are already working. Feel free to support me by providing your Dirigera setup with the provided dump application. I am confident that we will be able to implement all relevant devices soon.

4 Likes

Shame that no one shared the technical findings on the APIs. Unfortunately, the ikea apps are protected with SSL certificate pinning, so it is not that easy reverse-enginering it, but I put some effort to bypass it and record some ‘conversations’ between mobile app and the dirigera device.

It looks like you have to authenticate first using oauth and request the bearer token (JWT) (that need physical interaction with the device (push the button)). Then having the bearer token you can discover devices (IDs) and request some actions. Then I guess with the initial token you can re-request the bearer token (as it expires). [Edited to add - actually I didn’t notice that at first, but token is generated for 10 years, so no need to renew it]
Attached are recorded requests to interact with a lamp and blinds.

Sadly I can implement it in python, but not in java… well… I probably could, but it would be a very dirty implementation :), so I will leave it to the experts. I don’t think it is a major challenge.

[Burp dump] (http://luna.athae.net/dirigera.burp)

1 Like

Welcome to the community @landi

It sounds promising indeed! Let’s hope someone with java skills it ready to pick it up from here :grinning: Thanks for the initiative.

Cheers!

This is quick and dirty Linux bash script to show how easy it is to control devices when you obtain your JWT token. Works for me as I have only 3 blinds and a lamp: (requires httpie v 3.2.1)

To use this script obtain JWT token and discover hub IP, device IDs (and what they can receive) using Dirigera dump script by @Tamagotchi and modify below bash script to your liking:

#!/bin/bash
###
## Proof of concept script to control IKEA devices via the Dirigera home hub using obtained JWT token and httpie (version >= 3.2.1 as it supports bearer token authentication)
## Created by Landi (landi@athae.net) 2023
###

TOKEN="eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjY1MjNiOTliZTg0MjQ3NjZhYjJmZWFkYjg2MTAyYzlmNjFlMzIwM2ViMWRjZjMzMTg1NTVkYWFlY2I0MmM2OGEifQ.eyJpc3MiOiJkZTExYzEwZS03ZWFmLTRmNGQtYjRiNy05NTE1ZGY2Y2Y0YzkiLCJ0eXBlIjoiYWNjZXNzIiwiYXVkIjoiaG9tZXNtYXJ0LmxvY2FsIiwic3ViIjoiNGNmZDY4ZTQtMWRlNS00YzdhLTlkMzItYTZlYzc2NzA0NDRhIiwiaWF0IjoxNjcyODU5NTAxLCJleHAiOjE5ODg0MzU1MDF9.QbLJwoVpmBeWJdiVmoro3jvEpGrjuw3TmI7Gsc0RjY_A5bdeW4QbjtzjiJP9t0iCmEY4Wd6KIepRAMJihKgeXg";
DEBUG=0; # set up to 1 to view request/response
DIRIGERA_IP = "172.21.12.97"

case $1 in
   "blind-antek"):
   	DEVICE="ce7f737f-2d91-4c52-ba11-859b1a63898b_1" && DTYPE="BLINDS";
   	;;
   "blind-bedroom"):
   	DEVICE="5071a875-d8f5-4f24-93dd-a85f74351314_1" && DTYPE="BLINDS";
   	;;
   "blind-balcony"):
   	DEVICE="73a87432-4afa-4ba1-93ec-d32c4f1dec69_1" && DTYPE="BLINDS";
   	;;
   "sink-lamp"):
   	DEVICE="dcb18886-6468-4959-ae6f-477ef094d193_1" && DTYPE="LAMP";
   	;;
   *): 	ERROR=1;
   	;;
esac

case $2 in
   "on"|"ON"|"down"|"DOWN"):
   	if [ $DTYPE == "LAMP" ]; then COMMAND='[{"attributes":{"isOn":true}}]'; elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsState":"down"}}]'; else ERROR=1; fi
   	;;
   "off"|"OFF"|"up"|"UP"):
   	if [ $DTYPE == "LAMP" ]; then COMMAND='[{"attributes":{"isOn":false}}]'; elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsState":"up"}}]'; else ERROR=1; fi
   	;;
   "dim"|"DIM"|"level"):
   	if [ $DTYPE == "LAMP" ]; then if [ $3 -gt 0 ] && [ $3 -le 100 ]; then COMMAND='[{"attributes":{"lightLevel":'$3'}}]'; else ERROR=1; fi; elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsTargetLevel":'$3'}}]'; else ERROR=1; fi
   	;;
   "colortemp"):
   	if [ $DTYPE == "LAMP" ]; then if [ $3 -ge 2700 ] && [ $3 -le 5000 ]; then COMMAND='[{"attributes":{"colorTemperature":'$3'}}]'; else ERROR=1; fi; else ERROR=1; fi
   	;;
   *): ERROR=1;
   	;;
esac

if [ $ERROR -eq 1 ]; then echo "usage $0 devicename <on>|<off>|<up>|<down>|<level> 1-100|<colortemp> 2700-5000"; exit 1; fi
if [ $DEBUG -eq 1 ]; then ARGUMENTS='--verbose --all'; else ARGUMENTS='-qq'; fi
echo "$COMMAND" | https $ARGUMENTS --verify=no -A bearer -a $TOKEN PATCH $DIRIGERA_IP:8443/v1/devices/$DEVICE 
3 Likes

Great work @landi !

Works excellent as described. Worth to mention is that I had to install httpie using pip (e.g. pip install httpie followed by pip install httpie-jwt-auth) on my debian LXC in ProxMox. (The ‘apt-get’ installed version returned error http: error: argument --auth-type/-A: invalid choice: 'bearer' (choose from 'basic', 'digest'))

Eventually I’ll go for the MQTT version once there’s a usage instruction. :grinning:

1 Like

I’m glad to hear someone found this script useful :slight_smile: It’s a quick ‘hack’ (until ‘official’ binding is released) to help people use the dirigera-connected devices. Instead of using pip you can also add official httpie repositories to upgrade to the latest version of httpie.
In fact you don’t have to use httpie - just any https client - I just like to use httpie because it gives you a nice output of what request had been sent and the response received.

But anyways - It’s nice to know that it was helpful - do not hesitate if you have any questions/problems. I will try to help

@landi , thank you very much for your exploration of Dirigera and script!!

After getting the IDs from the dump I used your script in my OpenHAB on RPi, combined with the exec binding, to command my blinds to go fully up or down. Works beautifully, after installing httpie through the method described by @RRoe .

thanks for your script.
if you don’t want to install httpie, you can exchange the last 2 lines with these the following ones:

if [ “$DEBUG” == “1” ]; then ARGUMENTS=‘–verbose’; else ARGUMENTS=“–silent”; fi
curl -X PATCH https://$DIRIGERA_IP:8443/v1/devices/$DEVICE -H “Authorization: Bearer $TOKEN” -H “Content-Type: application/json” -d “$COMMAND” --insecure “$ARGUMENTS”

This is using the default curl instead of httpie (due to wider availability, in e.g. the openhab docker container).


To use the script inside the default OpenHab container:

  1. install exec binding
  2. put the script (mine is called dirigera.sh) in /opt/openhab/conf/scripts/dirigera.sh (on the docker host machine).
  3. create e.g. exec.things with the following thing (example)
Thing exec:command:dirigeraYourCommand [command="$OPENHAB_CONF/scripts/dirigera.sh <your_devicename> %2$s", timeout=10, autorun=false]
  1. don’t forget to whitelist the command in misc/exec.whitelist (%2$s contains parameter(s) e.g. on/off)
$OPENHAB_CONF/scripts/dirigera.sh <your_devicename> %2$s
  1. use the thing in your item definition according to the exec binding example, e.g. exec.items
Switch yourCommandSwitch
Switch yourCommandSwitch_Run {channel="exec:command:dirigeraYourCommand:run", autoupdate="false"}
String yourCommandSwitch_Args {channel="exec:command:dirigeraYourCommand:input"}
  1. setup rules to pass the on/off arguments (in my case a power outlet) to the script in your e.g. exec.rules
rule "Setup Parameters"
when
        Item yourCommandSwitch changed
then
        if(yourCommandSwitch.state == ON){
                yourCommandSwitch_Args.sendCommand("on")
        } else {
                yourCommandSwitch_Args.sendCommand("off")
        }
end

rule "Start execution"
when
        Item yourCommandSwitch_Args received command
then
        if(yourCommandSwitch_Run != ON){
                yourCommandSwitch_Run.sendCommand(ON)
                logInfo(logName, "Script execution started")
        } else {
                logInfo(logName, "Script execution already in progress, therefore skipping this execution")
        }
end
  1. use it in your sitemap and have fun (e.g. exec.sitemap):
Switch item=yourCommandSwitch

Is there any news about the Dirigera implementation ?

1 Like

Hi Landi
I would really like to get IKEA DIRIGERA up and running on my OpenHab, but unfortunately my skills are non existing when it comes to handling scripts - so do you have the opportunity to make a slightly more detailed description of what you have done.
Thanx in advance.
/Torben

Hi there Torben,

Of course I will try to help you. I assume you are running OpenHab on Linux, so all you have to do is:

Download httpie or modify the script to use curl (you can find instructions in the previous posts)

Save my script to some location on your Linux host (in a filename let’s say dirigera.sh"). Don’t forget to add execution rights to this script

chmod a+x dirigera.sh

Download dirigera-client-dump.jar from here: Releases · dvdgeisler/DirigeraClient · GitHub
read the pre-requirements on: GitHub - dvdgeisler/DirigeraClient: Dirigera Client API: Java written client API to interface IKEA's new smarthome hub DIRIGERA

Set up your router to give dirigera a static IP address (let’s say it will be 10.10.3.33 - change it to your configuration in below scripts)

Now you need to open a Linux terminal and run downloaded .jar file:

java -jar dirigera-client-dump.jar --dirigera.hostname=10.10.3.33 --dirigera.port=8443

then you will have to press the button on the dirigera device to issue a token. When pressed (after a few seconds) it will dump all your devices from dirigera and save the access token. Do not close the terminal, but press ctrl+c to exit the execution of the dump program.

Now you can display your token:

cat dirigera_access_token

Copy this long string and replace the value of TOKEN in my script.

Now look at the output from the dump program in linux terminal. Especially look for customName - if you find your device name, look for the first “id” value a few lines above the customName - this is the device id for your device. Replace the id with your value for any device in my script and try to control it.

Example output:

"id" : "dcb15556-6468-4959-ae6f-47766094d193_1",
"type" : "light",
"deviceType" : "light",
"createdAt" : "2022-12-09T19:44:07.000Z",
"isReachable" : true,
"lastSeen" : "2023-08-11T01:12:02.000Z",
"attributes" : {
  "customName" : "Table lamp",
  "model" : "NYMANE PENDANT",
  "manufacturer" : "IKEA of Sweden",
  "firmwareVersion" : "2.3.087",
  "hardwareVersion" : "1",
  "serialNumber" : "50325FFFFE6660DE",
  "productCode" : "LED1805E22EU",
  "isOn" : false,
  "startupOnOff" : "startOn",
  "lightLevel" : 33,
  "colorTemperature" : 2202,
  "colorTemperatureMin" : 4000,
  "colorTemperatureMax" : 2202,
  "colorMode" : "temperature",
  "identifyStarted" : "2000-01-01T00:00:00.000Z",
  "identifyPeriod" : 0,
  "permittingJoin" : false,
  "otaStatus" : "upToDate",
  "otaState" : "readyToCheck",
  "otaProgress" : 0,
  "otaPolicy" : "autoUpdate",
  "otaScheduleStart" : "00:00",
  "otaScheduleEnd" : "00:00"
},
"capabilities" : {
  "canSend" : [ ],
  "canReceive" : [ "customName", "isOn", "lightLevel", "colorTemperature" ]
},

Other useful information is “canReceive” - these are list of commands that devices can receive. In my script I use a few examples like “colorTemperature” for lights - modify it to match what the device can receive and you are good to test it by running the script from the command line

./dirigera.sh <device-name> <command>

If it works, you can add either a exec-binding thing in Openhab or you can just create the rule to execute the script like this:

executeCommandLine(Duration.ofSeconds(10),"/your/path/to/dirigera.sh","table-lamp","ON")

Thank you for implementing the IKEA Dirigera.
I had to make a few changes for my installation.
In the script, the spaces had to be removed from line 9:

DIRIGERA_IP="172.21.12.97"

When the script is called, the error message appears:

	/etc/openhab/scripts/dirigera.sh: Zeile 66: [: -eq: Einstelliger (unärer) Operator erwartet.

To avoid this, the following should be added to line 10:

	ERROR=0;

Example of calling in the terminal:

	$OPENHAB_CONF/scripts/dirigera.sh sink-lamp level 50

Example for calling in openHAB via the exec binding:

	executeCommandLine(Duration.ofSeconds(1), "/bin/bash", "-c", "$OPENHAB_CONF/scripts/dirigera.sh EG-Kueche-DL-1 level 50")

Since the formatting in post 9 doesn’t quite fit, here’s the correctly formatted one:

	if [ "$DEBUG" == "1" ]; then ARGUMENTS='-verbose'; else ARGUMENTS="-silent"; fi
	curl -X PATCH https://$DIRIGERA_IP:8443/v1/devices/$DEVICE -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$COMMAND" --insecure "$ARGUMENTS"

I hope this helps somewhat with setting up.

Here is my example of the GU10 lamp “TRADFRI” with the functions on/off, brightness and color temperature.
ITEMS:

//IKEA TRADFRI Artikelnummer 805.475.48

Switch			EA_EG_Kueche_Deckenlicht			"Deckenlicht [%s]"						<light>
Number			DIM_EG_Kueche_Deckenlicht			"Deckenlicht - Helligkeit [%d %%]"				<light>
Number			TEMP_EG_Kueche_Deckenlicht			"Deckenlicht - Farbtemperatur [%d K]"				<light>

RULES:

rule "211/2_EG_Kueche - Ein/Aus"
when
    Item EA_EG_Kueche_Deckenlicht changed
then
	if (EA_EG_Kueche_Deckenlicht.state == ON) {
		executeCommandLine(Duration.ofSeconds(1), "/bin/bash", "-c", "$OPENHAB_CONF/scripts/dirigera.sh EG-Kueche-DL-1 on")
	}
	else {
		executeCommandLine(Duration.ofSeconds(1), "/bin/bash", "-c", "$OPENHAB_CONF/scripts/dirigera.sh EG-Kueche-DL-1 off")
	}
end

rule "211/2_EG_Kueche - Helligkeit"
when
    Item DIM_EG_Kueche_Deckenlicht changed
then
	executeCommandLine(Duration.ofSeconds(1), "/bin/bash", "-c", "$OPENHAB_CONF/scripts/dirigera.sh EG-Kueche-DL-1 level " + DIM_EG_Kueche_Deckenlicht.state as Number)
end

rule "211/2_EG_Kueche - Farbtemperatur"
when
    Item TEMP_EG_Kueche_Deckenlicht changed
then
	executeCommandLine(Duration.ofSeconds(1), "/bin/bash", "-c", "$OPENHAB_CONF/scripts/dirigera.sh EG-Kueche-DL-1 colortemp " + TEMP_EG_Kueche_Deckenlicht.state as Number)
end

SITEMAP:

Frame label="IKEA TRADFRI Artikelnummer 805.475.48" {
	Switch item=EA_EG_Kueche_Deckenlicht
	Slider item=DIM_EG_Kueche_Deckenlicht				minValue=1 maxValue=100 step=1
	Slider item=TEMP_EG_Kueche_Deckenlicht				minValue=2202 maxValue=4000 step=2
}

SCRIPT:

#!/bin/bash
###
## Proof of concept script to control IKEA devices via the Dirigera home hub using obtained JWT token and httpie (version >= 3.2.1 as it supports bearer token authentication)
## Created by Landi (landi@athae.net) 2023
###

###
##Last 2 rows
##
## variant for httpie
## if [ $DEBUG -eq 1 ]; then ARGUMENTS='--verbose --all'; else ARGUMENTS='-qq'; fi
## echo "$COMMAND" | https $ARGUMENTS --verify=no -A bearer -a $TOKEN PATCH $DIRIGERA_IP:8443/v1/devices/$DEVICE
##
## variant for curl
## if [ "$DEBUG" == "1" ]; then ARGUMENTS='-verbose'; else ARGUMENTS="-silent"; fi
## curl -X PATCH https://$DIRIGERA_IP:8443/v1/devices/$DEVICE -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$COMMAND" --insecure "$ARGUMENTS"
###

TOKEN="<Your Token>";
ERROR=0;
DEBUG=0; # set up to 1 to view request/response
DIRIGERA_IP="<YOUR IP>"

case $1 in
   "blind-antek"):
   	DEVICE="ce7f737f-2d91-4c52-ba11-859b1a63898b_1" && DTYPE="BLINDS";
   	;;
   "blind-bedroom"):
   	DEVICE="5071a875-d8f5-4f24-93dd-a85f74351314_1" && DTYPE="BLINDS";
   	;;
   "blind-balcony"):
   	DEVICE="73a87432-4afa-4ba1-93ec-d32c4f1dec69_1" && DTYPE="BLINDS";
   	;;
   "sink-lamp"):
   	DEVICE="dcb18886-6468-4959-ae6f-477ef094d193_1" && DTYPE="LAMP";
   	;;
   "EG-Kueche-DL-1"):
   	DEVICE="238465ee-b0ae-44e1-a37c-cf3ca649db81_1" && DTYPE="TRADFRI_bulb";
   	;;
   *): 	ERROR=1;
   	;;
esac

case $2 in
   "on"|"ON"|"down"|"DOWN"):
   	if [ $DTYPE == "LAMP" ]; then COMMAND='[{"attributes":{"isOn":true}}]';
  	elif [ $DTYPE == "TRADFRI_bulb" ]; then COMMAND='[{"attributes":{"isOn":true}}]';
	elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsState":"down"}}]'; else ERROR=1; fi
   	;;
   "off"|"OFF"|"up"|"UP"):
   	if [ $DTYPE == "LAMP" ]; then COMMAND='[{"attributes":{"isOn":false}}]';
   	elif [ $DTYPE == "TRADFRI_bulb" ]; then COMMAND='[{"attributes":{"isOn":false}}]';
	elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsState":"up"}}]'; else ERROR=1; fi
   	;;
   "dim"|"DIM"|"level"):
   	if [ $DTYPE == "LAMP" ]; then if [ $3 -gt 0 ] && [ $3 -le 100 ]; then COMMAND='[{"attributes":{"lightLevel":'$3'}}]'; else ERROR=1; fi
   	elif [ $DTYPE == "TRADFRI_bulb" ]; then if [ $3 -gt 0 ] && [ $3 -le 100 ]; then COMMAND='[{"attributes":{"lightLevel":'$3'}}]'; else ERROR=1; fi
	elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsTargetLevel":'$3'}}]'; else ERROR=1; fi
   	;;
   "colortemp"):
   	if [ $DTYPE == "LAMP" ]; then if [ $3 -ge 2700 ] && [ $3 -le 5000 ]; then COMMAND='[{"attributes":{"colorTemperature":'$3'}}]'; else ERROR=1; fi
   	elif [ $DTYPE == "TRADFRI_bulb" ]; then if [ $3 -ge 2202 ] && [ $3 -le 4000 ]; then COMMAND='[{"attributes":{"colorTemperature":'$3'}}]'; else ERROR=1; fi; else ERROR=1; fi
   	;;
   *): ERROR=1;
   	;;
esac

if [ $ERROR -eq 1 ]; then echo "usage $0 devicename <on>|<off>|<up>|<down>|<level> 1-100|<colortemp> 2700-5000"; exit 1; fi
if [ "$DEBUG" == "1" ]; then ARGUMENTS='-verbose'; else ARGUMENTS="-silent"; fi
curl -X PATCH https://$DIRIGERA_IP:8443/v1/devices/$DEVICE -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$COMMAND" --insecure "$ARGUMENTS"
1 Like

Hey there,

thanks for all the work, i got this working with Bulbs and the myrvarv lightstrip.

i also did a little changes to the script so i can also switch/dim the lightgroups (chandelier with x lightbulbs etc.) via openhab if anyone wants to:

#!/bin/bash
###
## Proof of concept script to control IKEA devices via the Dirigera home hub using obtained JWT token and httpie (version >= 3.2.1 as it supports bearer token authentication)
## Created by Landi (landi@athae.net) 2023
###

###
##Last 2 rows
##
## variant for httpie
## if [ $DEBUG -eq 1 ]; then ARGUMENTS='--verbose --all'; else ARGUMENTS='-qq'; fi
## echo "$COMMAND" | https $ARGUMENTS --verify=no -A bearer -a $TOKEN PATCH $DIRIGERA_IP:8443/v1/devices/$DEVICE
##
## variant for curl
## if [ "$DEBUG" == "1" ]; then ARGUMENTS='-verbose'; else ARGUMENTS="-silent"; fi
## curl -X PATCH https://$DIRIGERA_IP:8443/v1/devices/$DEVICE -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$COMMAND" --insecure "$ARGUMENTS"
###

TOKEN="<YOUR TOKEN>";
ERROR=0;
DEBUG=0; # set up to 1 to view request/response
DIRIGERA_IP="YOUR IP";
API_LAMP="v1/devices"
API_GROUP="v1/devices/deviceSets"

case $1 in
   "decke-ez"):
   	DEVICE="abcb7221-8035-45a3-aab4-fc003351c007" && DTYPE="LIGHTING_GROUP" && API=$API_GROUP;
   	;;
   "decke-sz"):
   	DEVICE="da4162c6-1eab-4801-958a-d70a01834e37" && DTYPE="LIGHTING_GROUP" && API=$API_GROUP;
   	;;
   "decke-wz"):
   	DEVICE="05c87d91-c6d0-4637-9c18-fdb7f04cf786" && DTYPE="LIGHTING_GROUP" && API=$API_GROUP;
   	;;
   "wand-ez"):
   	DEVICE="9a363437-2548-4eb6-9a9f-da1eb853da12_1" && DTYPE="DRIVER" && API=$API_LAMP;
   	;;
   "fensterbank-ez"):
   	DEVICE="41d24131-bf00-48c7-bc51-8f52ba014e74_1" && DTYPE="TRADFRI_bulb" && API=$API_LAMP;
   	;;
    "wand-sz"):
   	DEVICE="1fa5d4b2-7b39-4c05-bc85-77fdbdec1a61_1" && DTYPE="DRIVER" && API=$API_LAMP;
   	;;
   *): 	ERROR=1;
   	;;
esac

case $2 in
   "on"|"ON"|"down"|"DOWN"):
   	if [ $DTYPE == "LAMP" ]; then COMMAND='[{"attributes":{"isOn":true}}]';
  	elif [ $DTYPE == "TRADFRI_bulb" ]; then COMMAND='[{"attributes":{"isOn":true}}]';
    elif [ $DTYPE == "DRIVER" ]; then COMMAND='[{"attributes":{"isOn":true}}]';
    elif [ $DTYPE == "LIGHTING_GROUP" ]; then COMMAND='[{"attributes":{"isOn":true}}]';
	elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsState":"down"}}]'; else ERROR=1; fi
   	;;
   "off"|"OFF"|"up"|"UP"):
   	if [ $DTYPE == "LAMP" ]; then COMMAND='[{"attributes":{"isOn":false}}]';
   	elif [ $DTYPE == "TRADFRI_bulb" ]; then COMMAND='[{"attributes":{"isOn":false}}]';
    elif [ $DTYPE == "DRIVER" ]; then COMMAND='[{"attributes":{"isOn":false}}]';
    elif [ $DTYPE == "LIGHTING_GROUP" ]; then COMMAND='[{"attributes":{"isOn":false}}]';
	elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsState":"up"}}]'; else ERROR=1; fi
   	;;
   "dim"|"DIM"|"level"):
   	if [ $DTYPE == "LAMP" ]; then if [ $3 -gt 0 ] && [ $3 -le 100 ]; then COMMAND='[{"attributes":{"lightLevel":'$3'}}]'; else ERROR=1; fi
   	elif [ $DTYPE == "TRADFRI_bulb" ]; then if [ $3 -gt 0 ] && [ $3 -le 100 ]; then COMMAND='[{"attributes":{"lightLevel":'$3'}}]'; else ERROR=1; fi
    elif [ $DTYPE == "DRIVER" ]; then if [ $3 -gt 0 ] && [ $3 -le 100 ]; then COMMAND='[{"attributes":{"lightLevel":'$3'}}]'; else ERROR=1; fi
    elif [ $DTYPE == "LIGHTING_GROUP" ]; then if [ $3 -gt 0 ] && [ $3 -le 100 ]; then COMMAND='[{"attributes":{"lightLevel":'$3'}}]'; else ERROR=1; fi
	elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsTargetLevel":'$3'}}]'; else ERROR=1; fi
   	;;
   "colortemp"):
   	if [ $DTYPE == "LAMP" ]; then if [ $3 -ge 2700 ] && [ $3 -le 5000 ]; then COMMAND='[{"attributes":{"colorTemperature":'$3'}}]'; else ERROR=1; fi
   	elif [ $DTYPE == "TRADFRI_bulb" ]; then if [ $3 -ge 2202 ] && [ $3 -le 4000 ]; then COMMAND='[{"attributes":{"colorTemperature":'$3'}}]'; else ERROR=1; fi; else ERROR=1; fi
   	;;
   *): ERROR=1;
   	;;
esac

if [ $ERROR -eq 1 ]; then echo "usage $0 devicename <on>|<off>|<up>|<down>|<level> 1-100|<colortemp> 2700-5000"; exit 1; fi
if [ "$DEBUG" == "1" ]; then ARGUMENTS='-verbose'; else ARGUMENTS="-silent"; fi
curl -X PATCH https://$DIRIGERA_IP:8443/$API/$DEVICE -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$COMMAND" --insecure "$ARGUMENTS"

Thanks to everyone. I just finished setting up my Jetström Lights. Since they can change temperature and color i had to extend the script a bit.
The light has two “colorMode”, “color” and “temperature”. If you send a command to change the temperature the Dirigera automatically changes to “templature”-mode and a color change (hue, saturation) changes to “color”-mode.
If you want to update/change to color, you have to send both colorHue and colorSaturation, otherwise you will get {“error”:“Error”,“message”:“"attributes" does not match any of the allowed types”}

In my script i hardcoded saturation to 1, according to the dump it should be something >= 0 and <= 1:

#!/bin/bash
###
## Proof of concept script to control IKEA devices via the Dirigera home hub using obtained JWT token and httpie (version >= 3.2.1 as it supports bearer token authentication)
## Created by Landi (landi@athae.net) 2023
###

TOKEN="<TOKEN>";
ERROR=0;
DEBUG=0; # set up to 1 to view request/response
DIRIGERA_IP="<IP>"

case $1 in
   "officelamp1"):
        DEVICE="2cc6eee8-7668-4838-8ca6-1980526ba7ef_1" && DTYPE="LAMP";
        ;;
   "officelamp2"):
        DEVICE="38026f12-8347-4292-a916-0fa81a1628d3_1" && DTYPE="LAMP";
        ;;
   *):  ERROR=1;
        ;;
esac

case $2 in
   "on"|"ON"|"down"|"DOWN"):
        if [ $DTYPE == "LAMP" ]; then COMMAND='[{"attributes":{"isOn":true}}]'; elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsState":"down"}}]'; else ERROR=1; fi
        ;;
   "off"|"OFF"|"up"|"UP"):
        if [ $DTYPE == "LAMP" ]; then COMMAND='[{"attributes":{"isOn":false}}]'; elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsState":"up"}}]'; else ERROR=1; fi
        ;;
   "dim"|"DIM"|"level"):
        if [ $DTYPE == "LAMP" ]; then if [ $3 -gt 0 ] && [ $3 -le 100 ]; then COMMAND='[{"attributes":{"lightLevel":'$3'}}]'; else ERROR=1; fi; elif [ $DTYPE == "BLINDS" ]; then COMMAND='[{"attributes":{"blindsTargetLevel":'$3'}}]'; else ERROR=1; fi
        ;;
   "colortemp"):
        if [ $DTYPE == "LAMP" ]; then if [ $3 -ge 2202 ] && [ $3 -le 4000 ]; then COMMAND='[{"attributes":{"colorTemperature":'$3'}}]'; else ERROR=1; fi; else ERROR=1; fi
        ;;
   "colorhue"):
        if [ $DTYPE == "LAMP" ]; then if [ $3 -ge 0 ] && [ $3 -le 359 ]; then COMMAND='[{"attributes":{"colorHue":'$3',"colorSaturation":1}}]'; else ERROR=1; fi; else ERROR=1; fi
        ;;
   *): ERROR=1;
        ;;
esac

if [ $ERROR -eq 1 ]; then echo "usage $0 devicename <on>|<off>|<up>|<down>|<level> 1-100|<colortemp> 2700-5000"; exit 1; fi
#if [ $DEBUG -eq 1 ]; then ARGUMENTS='--verbose --all'; else ARGUMENTS='-qq'; fi
#echo "$COMMAND" | https $ARGUMENTS --verify=no -A bearer -a $TOKEN PATCH $DIRIGERA_IP:8443/v1/devices/$DEVICE
if [ "$DEBUG" == "1" ]; then ARGUMENTS="–verbose"; else ARGUMENTS="–silent"; fi
curl -X PATCH https://$DIRIGERA_IP:8443/v1/devices/$DEVICE -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$COMMAND" --insecure "$ARGUMENTS"
1 Like