[ST Edge] Bug Report on Event Injection

I think I have found a bug in the code for injecting a capability command. I am creating events using Driver.inject_capability_command

https://developer-preview.smartthings.com/edge-device-drivers/driver.html?highlight=inject_capability_command#Driver.inject_capability_command

This call asks you to provide a command table. This table can include args and positional_args with the args being key/value pairs. This can be seen here in the docs near the bottom:

https://developer-preview.smartthings.com/edge-device-drivers/capabilities.html?highlight=positional_args

Here is some sample code:

driver:inject_capability_command(device, {
    capability = 'my_capability',
    command = 'my_command',
    args = { my_arg_key = my_arg_value },
    positional_args = { my_arg_value }
})

When I receive this event in the capability handler the args are empty, and the named args have been placed in the positional_args

{
    "capability":"my_capability",
    "positional_args":{
        "my_arg_key":"my_arg_value
    },
    "args":[],
    "command":"my_command"
}
2 Likes

Bug reports for Edge are usually reported in the following thread. You might get a quicker response there.

SmartThings Edge Developer Beta | Known Issues and Bug Tracking

2 Likes

Thank you for reporting this, @blueyetisoftware
Does the behavior you described happen for all the capabilities that receive an argument in the command?

2 Likes

Yes. I see this whenever I send args with this injection call.

Ok, I will review this and create a report for the engineering team. I’ll let you know once I get an update.

1 Like

I read that as saying that capability commands have positional arguments, but as the capability definition also includes a name for each argument they add that in for you because they are nice like that.

From what I can see from the code, it looks like args starts off as the positional arguments and gets renamed to positional_args, and then args is generated for you. So I think you are confusing things by giving it the intended end product.

You can see the code in st/capabilities/init.lua - there is a function to validate and normalize the command.

In summary, if you just do args = { my_arg_value } I rather suspect it will all come out in the wash.

I’m curious how they know what name to give this value if that is the case

In st.capabilities when the command is validated, the argument definition is got based on the arg position:

local arg_def = self.arg_list[arg_idx]

I made some tests, and I was able to inject a command for SwitchLevel using the following:

local command = {}
command["capability"] = "switchLevel"
command["component"] = "main"
command["command"] = "setLevel"
command["args"] = {50}
driver:inject_capability_command(device, command)

Note: I separated it for testing purposes but you should be able to use your own method.

Thanks @nayelyz . How does it decide what name to give the 50 when it ends up in args? Is it based on the order the args are added to the capability when it is defined?

Based on the code, yes, the arg definition (name, schema, etc.) is gotten when the validator goes through the elements in “args”.
Are you using a capability with a command with more than one argument?
I checked with the colorControl capability and the setColor command which receives a COLOR_MAP argument and there I defined the internal names, for example:

  local command = {}
  command["capability"] = "colorControl"
  command["component"] = "main"
  command["command"] = "setColor"
  command["args"] = {{hue=10,saturation=30}}

I see, you have a table inside of a table. :+1:

Thanks for looking into this.