Can't set state with API

Hello,

I’m currently evaluating if nymea is the best backend for my project.
I need my own client so I started to play around with the API. With Postman I am able to connect to the Websocket at ws://nymea.local:4444

To power up a lightbulb I do the following:

  1. get the thingId from the call:

    {
        "id": 1,
        "method": "Devices.GetConfiguredDevices"
    }
    
  2. with the thingId get the actionTypeId and the paramTypesId for the name “power”:

    {
        "id": 2,
        "method": "Integrations.GetActionTypes",
        "params": {
            "thingClassId": ${thingId}
        }
    }
    
  3. use all the IDs to execute the action:

    {
        "id": 3,
        "method":  "Integrations.ExecuteAction",
        "params": {
            "thingId": ${thingId},
            "actionTypeId": ${actionTypeId},
            "o:params": [
                {
                "paramTypeId": ${paramTypesId},
                "value": true
                }
            ]
        }
    }
    

When I send the execution I get a successful response but nothing happens. I can check the State with “Integrations.GetStateValues” and the value don’t change to true :disappointed_relieved:

I am able to change the Value with the official Nymea-App so it should be possible.

So my questions are:

  1. Is it normal that the ${paramTypesId} and the ${actionTypeId} are the same?
  2. Do I miss something?
  3. Is this the best way to trigger an action?

Best Kim

Hi @kim, welcome to nymea

So a few notes to begin with: The “Devices” namespace is deprecated. You should use only the “Integrations” namespace instead. It provides everything the Devices namespace has.

Now for your questions:

  1. For states it is the same, yes. So in this case everything is fine with them being the same.
  2. It does look ok. Although I can’t tell for sure without having more informations.
  3. Generally it’s fine what you’re doing. You probably want to enable ThingManager and Thing debug logs in nymea. Use nymea:app → System settings → Developer tools → Debug interface to enable the debug interface. Then you can use the debug webinterface to enable/disable certain logs and watch the logs there. Watch those logs while triggering your action, it will probably give additional information on what’s happening.

Hope that helps.

Hey thanks for the fast answer,

so I’ve activated that awesome debug window. It looks like nymea interprets my value as false all the time. When I turn the lightbulb on with the app, I can turn it off when I send this:

{
“id”: 3,
“method”: “Integrations.ExecuteAction”,
“params”: {
“thingId”: “37d9a2ca-29d4-49f8-b29e-f72e60f0522a”,
“actionTypeId”: “19d82a60-0009-4cff-966d-3b1c4fe358e1”,
“o:params”: [
{
“paramTypeId”: “19d82a60-0009-4cff-966d-3b1c4fe358e1”,
“value”: true
}
]
}
}

I can type anything in value like:

true
“true”
1
“someRandomChars”

Everything gets interpreted as false. Do I have to do something before I can set the value? Is it maybe a null pointer all the time because I forgot to do anything?

Something I noticed, when I send a thingId that doesn’t exist I get a thing error but the status is still a success is this how it should happen?

{
    "id": 3,
    "params": {
        "thingError": "ThingErrorThingNotFound"
    },
    "status": "success"
}

Best Kim

So I found the mistake. It should be “params” not “o:params” why are there an “o:” or an “r:” in front of some entries in the API documentation? Nymea was able to trigger the right action but the value was always invalid.

oh, I see. Two things:

First, the outer “success” field indicates whether nymea would understand the API call. If it returns "status": "error" in the topmost JSON object this would mean that you’ve given invalid json or you you’ve sent something that does not follow the API (i.e. a missing mandatory field or so). The fact that it would say true for success, does not necessarily imply that nymea did something useful with your call. In a client app you’d basically first check the success field which should always be true unless you’ve made a programming mistake and should fix your code (asserting might be a good idea here). Next thing you’d pass the params object up to higher layers and evaluate the “thingError” which could indicate some runtime error. For example, ExecuteAction wouldn’t work because of a hardware/connectivity failure with the actual thing, or maybe because the combination of params doesn’t make sense, and you should indicate to the user what happened.

Then, for the “o:” etc: As described here: json-rpc · documentation there are optional and read-only properties in the API. If the introspection (api doc) puts an o: in front of a property it means that you don’t have to provide this property for it to be a valid API call. r: would mean it’s a read-only property. Which means a Get call would return that property but in a Set call you can’t give it as it can’t be changed. (Also watch out for “d:” which means deprecated - there’s newer replacement for it.). Those modifiers are only in the JSONRC.Introspect call (the API is generated from that) but they’re not included in other communication.