Creating Rules & Automations with commands + argument

I’m finally taking the plunge with the Rules API and creating my first rule. However, I’m getting this obtuse error and I can’t figure out what the problem is:

Error: Request failed with status code 422: {"requestId":"DAE87465-8814-4A89-8896-7CDD8B679B82","error":{"code":"ConstraintViolationError","message":"The 
    request is malformed.","details":[{"code":"BodyMalformedError","target":"Unknown target","message":"Malformed body on line 1","details":[]}]}}

Here is my rule:

{
  "name": "Test Web Requestor",
  "actions": [
    {
      "if": {
        "equals": {
          "left": {
            "device": {
              "devices": [
                "724861a2-2c0b-462b-84cc-0e3850920984"
              ],
              "component": "main",
              "capability": "presenceSensor",
              "attribute": "presence"
            }
          },
          "right": {
            "string": "present"
          }
        },
        "then": [
          {
            "command": {
              "devices": [
                "0a90aa3d-e0c3-47da-9922-c060368000ae"
              ],
              "commands": [
                {
                  "component": "main",
                  "capability": "partyvoice23922.webrequest",
                  "command": "POST",
                  "arguments": [
                    "http://192.168.1.104:1755/blah"
                  ]
                }
              ]
            }
          }
        ]
      }
    }
  ]
}

If anyone can point out my error, I’d be very appreciative!

I think you might need to write:

"string": "http://192.168.1.104:1755/blah"

I only have one Rule that uses an argument and I found I had to do that. I have absolutely no idea why.

Oh, and I really recommend YAML for Rules. You trade ridiculous amounts of brackets for ridiculous space based indentation but it is still an improvement

Update: I missed the braces because I was reading a YAML file where indentation replaces the braces.

2 Likes

You’re right, Graham. The “argument” property can receive an array of objects, therefore, you need to add that value inside one. Eg.

"commands": [
    {
        "component": "main",
        "capability": "partyvoice23922.webrequest",
        "command": "POST",
        "arguments": [{"string":"http://192.168.1.104:1755/blah"}]
    }
]

The value type depends on the one defined in the capability’s command (string, integer, etc.)

I think it gets confusing because when you look at the ‘Response samples’ in the API documentation you see things like:

"actions": [
"commands": [
    {
        "component": "main",
        "capability": "switchLevel",
        "command": "setLevel",
        "arguments": [
            80
        ]
}

I don’t know if that is correct but to be consistent with the string I’d expect it to be { "integer": 80 }.

EXACTLY what I was going to say, Graham! It was this documentation that I was looking at that caused me this wasted time. I couldn’t find any of the example rules in github using arguments, but that doesn’t mean there might be one buried somewhere I just didn’t see.

THANK-YOU both for giving me the solution!

1 Like

Thank you both for your comments.
I’ll report this because we need the value of { "integer": 80 } for the setLevel command argument as well.
Cheers! :smiley:

1 Like

@nayelyz:

On a related point, is this the right presentation json syntax for enabling an automation command+argument?:

{
    "dashboard": {
        "states": [],
        "actions": [],
        "basicPlus": []
    },
    "automation": {
        "conditions": [],
        "actions": [
            {
                "label": "POST",
                "displayType": "multiArgCommand",
                "multiArgCommand": {
                    "command": "POST",
                    "arguments": [
                        {
                            "label": "URL",
                            "displaytype": "textField",
                            "textField": {
                                "name": "url"
                            }
                        }
                    ]
                }
            },
            {
                "label": "GET",
                "displayType": "multiArgCommand",
                "multiArgCommand": {
                    "command": "GET",
                    "arguments": [
                        {
                            "label": "URL",
                            "displaytype": "textField",
                            "textField": {
                                "name": "url"
                            }
                        }
                    ]
                }
            }
        ]
    },
    "id": "partyvoice23922.webrequest",
    "version": 1
}

This doesn’t appear to be working at the moment; the POST and GET commands are listed in the automations app ‘Then’ menu, but if you try to tap on either of them (to provide the argument), nothing happens. So I’m guessing something is wrong with this too!

BTW, my rule above is working great!

Ok, please, allow me some time to review this and I’ll let you know. :smiley:

Silly question but is your rule for TTS?

TTS is all I’m using webcore for at the moment. I’ve been considering trying to use rules api to try to get off webcore but it’s a bit over my head.

I like the ability to store multiple phrases with webcore and then use the random syntax for TTS. It’s fun getting different voice announcements for when someone comes home :slight_smile:

Yes I have a TTS app that runs on a Raspberry Pi. I’ve recently moved the driver to Edge and can now also move off Webcore and use Rules to keep everything running locally.

My post wasn’t specifically for that but as you surmised, it will apply to that as well!

3 Likes

@nayelyz Hi - Regarding this topic, the last time I tried it, the multiArgCommand display type in a device presentation automations section didn’t appear to be working. Can you please tell me if it is functional now, and if so, do you have any examples of its use to can share? I want to be able to have a Rule that provides 2 string arguments to a command. (I currently have it working with one argument thanks to your previous help).

2 Likes

Hi, @TAustin.

The team mentioned this isn’t implemented yet as it requires several changes. But, they’re aware of the requirement and it’s in their roadmap (there’s no ETA).

Thanks, but then it needs to be removed from the published API documentation for creating capabilities!

1 Like

Yeah, I already reminded the team about this.
Thanks!

1 Like

Is it just a limitation of the presentation side of things? Could you update the capability to support receiving a second optional parameter (eg. ignore when it isn’t set) and leave the presentation as if it only supported a single argument – then tools which are aware of the expanded capability definition could still take advantage of the second argument?

A follow up to this old discussion regarding how to properly code command arguments inside a Rule. I’ve got a capability that takes 3 arguments and I cannot get it to work. I’ve successfully invoked the command from the RESTful API simply sending an array of 3 strings within the arguments array. But I can’t for the life of me get this to work in a Rule.

Are multiple command arguments working yet in Rules? I know they were broken in the mobile app routines at one point.

I’ve tried with and without specifying the argument names as defined in the capability, and tried passing them in three separate objects and within one object. But all I get are unhelpful errors from the CLI. I’ve even tried sending just the first argument and not the others, but still ‘invalid argument’ errors - presumably because the capability has three arguments defined.

The only example rule I could find on github was using the colorControl capability, but that passed two arguments within one map object.

I only seem to have ever used one argument. I think the format is supposed to be:

"arguments": [
    { "string": "argument1" },
    { "integer": 80 }
]

So an array of objects in position order with the type as the key, and I think the type is in JSON terminology, not capability terminology.

Finally got it to work. Thanks!

1 Like