Ikea Tradfri 2 button remote control API rules Json coding help

G’day all,

I am chasing a little help with converting a simple rule that I have made using sharptools to the Smartthings rules API so that it will run locally. I have never coded and I’m trying to teach myself using whatever resources I can but unfortunately I haven’t been able to find any examples to help me with this one. I will be wanting to expand on this rule but my first goal is just trying to get the basics to work and then play around with it.

The basics of the rule is to turn my kitchen lights on or off whenever I press either of the 2 buttons on an ikea tradfri 2 button remote. I would run this with just a normal automation except I also have a routine that if I hold the button then 1 light comes on dimly (for first thing in the morning so I don’t wake the family) and if I just use the on/off control in the smartthings app then once this routine has been run then the lights are out of sync and pressing a button turns one light off and the other light on.

What I am trying to achieve is:

if:
button 1 or button 2 is pressed
and:
light 1 is on
then:
turn light 1 and light 2 off
else:
turn light 1 and light 2 on

I found an example code here Rules | SmartThings Developers (last code at the bottom of the page) that I copied as the template for my rule and I replaced the device ID for the button and lights. I haven’t worked out how to write the code for button 1 OR button 2 so I’m just using button 1 as the trigger. I tried posting the request but I am getting a 422 unprocessable entity error saying the request was well formed but was unable to be followed due to semantic errors when I try posting from postman.

This is the code that i have written

{
    "name": "Kitchen Light Button",
    "actions": [
        {
            "if": {
                "equals": {
                    "left": {
                        "string": "pushed"
                    },
                    "right": {
                        "device": {
                            "devices": [
                                "8d67fa9d-1301-4f3a-9ae5-89018fee29e9"
                            ],
                            "component": "main",
                            "capabilities": "Button",
                            "attribute": "button1",
                            "trigger": "Always"
                        }
                    }
                },
                "then": [
                    {
                        "if": {
                            "equals": {
                                "left": {
                                    "device": {
                                        "devices": [
                                            "cdc4574a-34b6-48a2-b5f4-862c90e08ce9"
                                        ],
                                        "component": "main",
                                        "capability": "switch",
                                        "attribute": "switch",
                                        "trigger": "Never"
                                    }
                                },
                                "right": {
                                    "string": "on"
                                }
                            },
                            "then": [
                                {
                                    "command": {
                                        "devices": [
                                            "cdc4574a-34b6-48a2-b5f4-862c90e08ce9",
                                            "3ebeda22-a75d-42f2-b873-c29c5878a602"
                                        ],
                                        "commands": [
                                            {
                                                "component": "main",
                                                "capability": "switch",
                                                "command": "off",
                                                "arguments": []
                                            }
                                        ]
                                    }
                                }
                            ],
                            "else": [
                                {
                                    "command": {
                                        "devices": [
                                            "cdc4574a-34b6-48a2-b5f4-862c90e08ce9",
                                            "3ebeda22-a75d-42f2-b873-c29c5878a602"
                                        ],
                                        "commands": [
                                            {
                                                "component": "main",
                                                "capability": "switch",
                                                "command": "on",
                                                "arguments": []
                                            }
                                        ]
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        }
    ]
}

and here is the device information for the tradfri 2 button remote

{
    "deviceId": "8d67fa9d-1301-4f3a-9ae5-89018fee29e9",
    "name": "two-buttons-battery",
    "label": "Testing IKEA Remote Control",
    "manufacturerName": "SmartThingsCommunity",
    "presentationId": "ffec9b59-549b-3375-8d67-91b6896488eb",
    "deviceManufacturerCode": "IKEA of Sweden",
    "locationId": "248cca1b-5aa0-435b-b850-3b291b49474e",
    "roomId": "8b6ac263-31dd-44e5-b1ef-414674e9ea8b",
    "components": [
        {
            "id": "main",
            "label": "main",
            "capabilities": [
                {
                    "id": "battery",
                    "version": 1
                },
                {
                    "id": "firmwareUpdate",
                    "version": 1
                },
                {
                    "id": "refresh",
                    "version": 1
                },
                {
                    "id": "universevoice35900.log",
                    "version": 1
                }
            ],
            "categories": [
                {
                    "name": "RemoteController",
                    "categoryType": "manufacturer"
                }
            ]
        },
        {
            "id": "button1",
            "label": "button1",
            "capabilities": [
                {
                    "id": "button",
                    "version": 1
                }
            ],
            "categories": [
                {
                    "name": "RemoteController",
                    "categoryType": "manufacturer"
                }
            ]
        },
        {
            "id": "button2",
            "label": "button2",
            "capabilities": [
                {
                    "id": "button",
                    "version": 1
                }
            ],
            "categories": [
                {
                    "name": "RemoteController",
                    "categoryType": "manufacturer"
                }
            ]
        }
    ],
    "createTime": "2023-07-25T03:23:16.996Z",
    "parentDeviceId": "59c79abb-70a4-4bbc-8f51-609bb758031d",
    "profile": {
        "id": "e7d8d1be-99d8-38ed-a63d-d39c0b42f73c"
    },
    "zigbee": {
        "eui": "842E14FFFEFEA759",
        "networkId": "0FA3",
        "driverId": "ad9f537d-e2d9-4354-8673-471a5306fad8",
        "executingLocally": true,
        "hubId": "59c79abb-70a4-4bbc-8f51-609bb758031d",
        "provisioningState": "PROVISIONED"
    },
    "type": "ZIGBEE",
    "restrictionTier": 0,
    "allowed": null
}

I really appreciate any help as I’m totally new to this and just trying to get my head around the basics so I can work my way up from here.

I notice the need to fix following:

Change button1 definition

“component”: “button1”,
“capability”: “button”,
“attribute”: “button”,
“trigger”: “Always”

Delete arguments definition from switch commands

“commands”: [
{
“component”: “main”,
“capability”: “switch”,
“command”: “on”,
}
]

“commands”: [
{
“component”: “main”,
“capability”: “switch”,
“command”: “off”,
}
]

hey, thanks heaps for the reply. I made the changes you suggested and still get the same error. does it matter that the remote is installed on smartthings with a custom driver and that I’m using a bearer token that I generated a few weeks ago?

I don’t know
Can you use remote if you make normal routine using SmartThings App?

I have Ikea on/off switch E1743 using stock driver
I run the command

smartthings devices:health device-id

button2 component
──────────────────────────────────────────────────────
 Capability  Attribute              Value
 button      button                 "pushed"
 button      numberOfButtons        1
 button      supportedButtonValues  ["pushed","held"]
──────────────────────────────────────────────────────


main component
───────────────────────────────────────────────────────────
 Capability      Attribute               Value
 button          button                  "pushed"
 button          numberOfButtons         2
 button          supportedButtonValues
 battery         battery                 74 %
 firmwareUpdate  lastUpdateStatusReason
 firmwareUpdate  availableVersion        "22010631"
 firmwareUpdate  lastUpdateStatus
 firmwareUpdate  state                   "normalOperation"
 firmwareUpdate  currentVersion          "22010631"
 firmwareUpdate  lastUpdateTime
───────────────────────────────────────────────────────────


button1 component
──────────────────────────────────────────────────────
 Capability  Attribute              Value
 button      button                 "pushed"
 button      numberOfButtons        1
 button      supportedButtonValues  ["pushed","held"]
──────────────────────────────────────────────────────

If you run the same command then what you get

I just copied your rule, made the changes @TapioX indicated, changed the IDs to my own, and it works correctly.

Just being a custom driver shouldn’t make a difference in itself, and unless you have deleted the token it will last for about fifty years or something like that.

Can you copy and paste the error that you get?

Legends, thanks heaps for all the replies. I got it to send the request. it didn’t like that I had “capabilities” instead of “capability” and then it didn’t like that I had “button” as the capability but I deleted the command and re wrote it again and it seemed to like that for some reason.

now it’s time to play with the code to try to add button2 as starter.

oh also, as the tradfri buttons have a hold command as well, would I put the actions I want when the button is held into this rule or write a separate rule for that.

The button attribute does not have a standby state so if you single press a button the attribute will remain pushed until such time as you do something different like a long press which will change it to held (in SmartThings held tends to represent a completed long press rather than the button being held down). So you are OK with pushed and held for a single button in one routine as long as the button is the only thing triggering the routine.

Where things gets more complicated is with more than one button in the same Rule (or where the button isn’t the only trigger) as you can’t just test for the status of each button. You need to know if a button and/or which button was pressed. In webCoRE you could explicitly check for a button being pushed and when I wrote my Rules years ago I repeatedly bemoaned the absence of that functionality which forced me to stick to one button per Rule.

It turns out that there was probably a solution there all along in the form of the hopelessly undocumented operand. I’ve never tried it as my Rules are fine as they are, but …

            "operand": {
              "device": {
                "devices": [
                  "{{button1-id}}"
                ],
                "component": "main",
                "capability": "button",
                "attribute": "button"
              }
            }

… should be true if the current event the Rule is handling is the button being pressed, and false otherwise. Like I say (and let’s credit @nayelyz here as she showed operand in use and it isn’t her fault it took me about two years to finally grasp what it was doing), I haven’t tested it myself but it seems it should be useful.

Awesome, thanks mate. I do remember seeing that thread where @nayelyz showed the operand command. Tbh the whole thing is hopelessly undocumented and especially hard for me to learn considering the only coding I have done was drawing shapes with the turtle on a commodore 64 back in primary school. Plus I’m teaching myself the google script editor which seems far easier to use for basic stuff. You really shouldn’t have to be a full stack developer to get a set of lights to turn on and off and change colour temperature when you hold a button down.

I’ll have a play around with it tomorrow and see how I go.

Thanks again for the replies and help

I should clarify that there are definitely cases where two buttons in the same Rule are not an issue. If for example you had (in pseudo-code):

if 
  any of button1 and button2 are pushed
then 
  do something

then indeed something would be done if button1 or button2 is pushed and it would be absolutely fine as long as the button in use could only be pushed. Things break down quickly if it can also be held.