Hey Chris @merck. I have now some questions about implementing actions in my HS plugin.
Main problem for me is that the plugin should work with any device supported by BB and SBB. And I guess there’s a lot. And they all have different functionality. So the plugin should be generic enough to support them all.
Currently I do get the list of actions for the device and create control buttons fro each action. Which should work for actions without arguments (Open/Close etc.)
So my questions are:
Is it possible to get a list of required arguments for each action? Is it available via API? Or do you have a document?
How do I get the confirmation after I execute the action (in generic manner)? I know that I use /v2/devices/{device_id}/state - but which field do I use? Same questions - Is it available via API? Or do you have a document?
Similar to above, do you have a list of state replies for all possible devices? SO I can display the state info in HS?
Seeing a 204 response should be good enough. If you want to get the state of the device though, you can request the device’s state endpoint. If you’d prefer the state to be pushed to you, and you can listen for UDP packets, you could use BPUP.
For our own integrations (Alexa, Google Home, SmartThings. All cloud-to-cloud.) we send the action request, check for 204, then wait for state to be pushed to our backend, at which point we forward the state on.
I think a lot of the local integrations are polling for state in a loop.
Interesting, hadn’t thought of that. For now, GET actions/<action_name> is unused. Perhaps if we populated that with a type and accepted input, that’d make the API a bit more “discoverable”?
The type would be easy, I’d just need to think if there’s a straightforward way to convey accepted inputs for all possible actions in JSON. I’m open to suggestions.
Another question. User reported that his fan has 6 speeds (in the app), but the API returns “SetSpeed”, “IncreaseSpeed”, “DecreaseSpeed”. So it looks like the app artificially creates 6 buttons, but internally it uses “SetSpeed”?
Is it possible to get the app button setup to duplicate it in HomeSeer? How do I know that I need to create 6 buttons for Speed? Most fans have only three speeds.
So “command” is a shortcut for “action” and includes arguments?
API provides function to get the command, but I don’t see how I can execute the command. Or can I?
I’d say “Action” is more a shortcut for “Command”. For example, the user records 6 speed buttons, which create 6 commands. If we didn’t have the Actions API, an integration would have to 1) find out the list of command IDs 2) request each one in turn and 3) store in memory this table of available commands.
Additionally, this table would potentially have to be rebuilt pretty often, say if a user later recorded a “Speed 7” button.
The Actions API just takes care of this for you. It collapses available commands into available actions, so you can get all you need in one request. (GET device has an array of actions, looks like the docs are wrong! They show just a sub-endpoint hash)
Confused (may be because it’s 1:35 am)
So. The user says he has 6 buttond for speeds (pic. 1).
In my code I get the list of available actions (pic .2).
So the action is “SetSpeed” and I guess it takes argument from 1 to 6.
So “Speed 1” command is the shortcut for SetSpeed(1) action?
Actions represent a user’s intent, but do not nessisarly map one-to-one onto the commands that are sent to a device.
Bond Bridges operate by translating actions into “commands”. While actions are in a user’s language, commands are in the device’s remote control’s language.
Yes, but I hesitate to call it a shortcut because you’d have to request the whole table of commands to find the action/argument you’re looking for. You then have to store the dictionary of IDs and action/argument pairs, which may be invalidated by the user recording a new command or deleting a command.
Our mobile apps use the Commands API (they use the individual commands to build the panel), but our Google Home, Alexa, and SmartThings integrations use the Actions API (they just need to be aware of available actions). I’d suggest anyone building their own integration to use the Actions API as well, because it requires much fewer GETs to find out what you need to know about a device.
The user’s device has a power off Command, as well as 6 speed Commands. There’s no power on Command.
But the user does have a TurnOn Action. This action uses one of the speed commands (that of the last-seen speed) to turn the fan on. So, by using the Actions API you don’t need to think about this relationship between SetSpeed and PowerOff.
The user has a ToggleLight Command (just named “Light”). When the user presses this button, it will always transmit the toggle signal, just like the remote.
We expose two Actions: TurnLightOn and TurnLightOff. And we allow users to customize what happens when an unexpected action comes in. Say the Bond Bridge thinks the light is off, but the user asks it to “TurnLightOff” (and, again, we can only toggle the light). There’s two potentially correct behaviors:
The Bond is wrong about the light being off, it’s on and the Bond should send the signal, turning it off.
The light is really off but the user may not be around to see that it’s off, or the user is, for example, wanting to turn off all lights in their home. In this case, the Bond should ignore the action and do nothing.
The way we handle these two possible behaviors is with the trust_state property, documented here. Situation 1) is the behavior with a disabled trust_state (the default). Situation 2) is the behavior with an enabled trust_state. The commands API doesn’t take these kinds of things into consideration.
Now I seem to have better understanding.
So actions are convenience wrappers for commands.
Still I don’t get - if I call SetSpeed(5) - and there’s no corresponding command?
You’ll get a response with a status of 400 (Bad Request) with an error message in the body describing the error, in this case it’s something like “invalid argument”. EDIT: actually, for this one, if the argument is above max_speed it gets set to max_speed.
In fact, if you base your driver on the Commands API, your driver will not work with the SBB devices. The Actions API is the higher level portable API.