Smartthings and WebCoRE performance question(s)

Hi all,

Firstly, this will be my first post as I’m new to Smartthings, WebCoRE and the smartthings community, so thank you all for welcoming me and thank you all for helping me so much already.
I’ll just add that if I’ve posted this on the wrong place, any admins please feel free to relocate it in the right place.

So, on to the point of my past…

I’m a software engineer and well versed in all things programming so I realise I have a head start when it comes to programming automations and pistons. But as a programmer I find myself wondering how things work behind the scenes so that I can program with an eye on performance, and ease of managing automations.

Therefore I have a few questions, discussion points and comparisons to try and build my own list of ‘best practices’ that may or may not equate to industry standards.

1: lots of small pistons Vs fewer large pistons

Based on previous experience of similar situations in other languages I’ve taken the decision to try and have 1 piston for each input device, which would ‘listen’ to all of the relevent events on that device.
That being said, there is scope to reduce the size (and complexity) of a piston by separating event listeners into multiple ones.

The real question here is, which is best:
A) loads of small pistons, each with code for a particular event listener for a specific device - could be difficult to manage or cross-talk with other events/devices, but should theoretically allow for better performance as fewer lines of code are loaded for each event listener triggered
B) a piston for each device which contains all event listeners for that one device - which I’m leaning towards - probably likely to be the best balance of performance Vs ease of management
C) a piston for each room, floor or function type comprising lots of devices and event listeners in each - performance will likely be bad but should be easier to manage

I wonder if anybody has ever looked at the performance comparison of lots of small pistons vs a few large pistons?

2: polling devices for current States Vs storing current States in global variables [Solved]

In planning and programming my first few automations I’ve found that expected operations can, and do rely on the current state of some other devices.
For instance (simplest example), when clicking a button next to a light - if the light is on, turn it off, if it’s off, turn it on. (I know in this example I could simply ‘toggle’ the light, but this is just a simple example)
My assumptions based on other languages (which I may be completely wrong about) is that it will take longer to ask for the current state of a device (as the request would travel over the internet) Vs asking for the current value of a Boolean variable (which would exist in the same place the piston code).

The real question here is, which is best:
A) within pistons, poll the device for the current state when it’s needed - likely to be slower
B) have a global variable to store the current state of each device, and add pistons to keep those variable matching those device States - will increase the number of pistons needed to keep the variables up to date. And possibly likely to have performance issues from having a lot more event listeners
C) have a global variable to store the current States of a selection of devices (those which we need to poll) - likely to be the best balance between performance of individual pistons Vs overall performance

I wonder if anybody has ever looked at the performance comparison of polling device States Vs polling global variables, and updating those variables?

[Update]
Following @ogiewon s and others comments, I’ve taken the decision to change my pistons to poll/all the current states of the devices themselves instead of sitting the current states in a variable.
It’s been identified that there should be no performance difference between polling the device Vs polling a variable. In fact a benefit of polling the device is that status will be correct even if it is changed by something else (as a posed to variables being cached on piston execution).
[Update end]

3: using scenes Vs using pistons to set multiple device changes

I’ve initially set up scenes, and pistons are deciding which scene to activate based on several queries.
As I said I’m not long into my experience of using smartthings, but one thing I’m aware of is that activating a scene doesn’t seem to allow a gradual change in brightness (yes I realise some light bulbs have that built in but not all bulbs).

This leads me to feel I need to use pistons to change multiple devices, especially where gradual switch on/off is important.
That’s great for automated activations (from timers and device s such as pushing a button), but I still would like the ability to activate these changes via voice (I have Google assistant all around the house). If I can activate a piston from a Google routine (I know I can activate a smartthings scene in this way), that would be great. If I can’t activate a piston from Google routine, I’ll have to also set up a scene and put up with instant on/off when activated via voice.

Does anybody know if a piston can be activated from Google home routines?

4: power outage recovery

So, this last item is around outages. I’ll say that we rarely get power outages, or internet outages. But, my wife is a real technophobe so if something happens that isn’t as expected compared to non-smart operations, it will be noticed.
The main issue that needs to be addressed is light bulbs in the bedroom. If we have a power cut in the middle of the night, we can’t have all the lights go on with no quick or easy way to switch them back off again.
Of course the best and most desired option is that the lights don’t come on at all.
But I appreciate smartthings has no idea that there’s a power cut until the bulb is repowered, and communicates with smartthings so there may be a delay before the light is switched back off.
This of course will also really on the internet connection being re-established.

So here’s my question. I know that webCoRE is executed in the cloud (relying on the internet being re-established), but does anybody know if something exists that would run on the smartthings hub to return bulbs to their original States (or at least turn off the bulbs in the bedrooms)?

So, that’s my (long) first post to the community, I hope that all of my points and questions make sense, if not please feel free to ask.
If anybody has any suggestions or recommendations, please share. And if any of my assumptions are wrong, please correct me.

And once again, thank you all for your help, and welcoming me to the smartthings community.

1 Like

Welcome! :sunglasses: interesting questions, and it sounds like you’ve done a lot of initial research, which is good

In the future, I’d suggest creating multiple threads, one for each question, as quite a few of your questions don’t really have much to do with the others and it makes it easier for people using the forum in the future, and just for those trying to follow any one topic discussion. In particular, your fourth question is an entirely separate topic, and while there’s been quite a bit done on that already, it ends up not really belonging in this thread. So you might want to start a new thread at least for that.

Webcore has their own forum where most of the experts hang out, so you might try asking questions there as well.

As far as whether a piston can be activated by voice, see the following community FAQ:

FAQ: How to Run Scenes and Automations (New V3 App) (2021)

One more thing about power outages. If you use hue bulbs with a hue bridge, Hue already provide a method for managing power outages for each individual bulb. It works well, and solves the problem very neatly. so if you haven’t bought your devices yet, that certainly an option. You can either have the lights come on to their previous setting (which means if they were off when the power went out they will stay off) or to a default. And it works locally with the Hue Bridge.

But that only works for hue bulbs on a hue Bridge. Smartthings itself doesn’t offer anything similar for other brands.

As always, the first rule of home automation applies: “the model number matters.“ :wink:

You might get more mileage over in the webCoRE forum, but …

  1. ‘Best’ is subjective, but I’d suggest you think in terms of what events trigger a piston and whether they can occur in a short space of time. Every event triggers a new piston instance. By default, pistons wait for (up to) ten seconds for existing instances to finish. That can get messy fast.

  2. Bear in mind that piston instances cache the values of global variables on start up, and only write any changes on exit.

You aren’t actually polling devices anyway, you are just reading the device object from SmartThings. It is very quick.

Can I just check that you are aware that each piston is implemented as a SmartApp executing in the SmartThings cloud?

  1. At the moment you really have to improvise using virtual switches.

  2. Very little runs on the hub at the moment. If you have lights that power on after an outage then they should tell SmartThings about it. You’ll have to handle it.

I’d actually suggest avoiding using webCoRE as much as possible. It is a legacy product on SmartThings and its days are numbered.

3 Likes

^This. Stick to the Automations in the mobile app until we have a good alternative to Webcore that uses the new APIs and not soon to be deprecated Groovy.

1 Like

I’m with Graham here - Depends on what your piston is doing. Personally I find it challenging to get ‘all things a device triggers on’ in one piston without getting into recursion hell. SO most cases I build small task based pistons.

In most cases, just do what you’re going to do - not worth trying to poll with caveats Graham mentions. Webcore also has some optimization built into itself where if you turn on a light that’s already on - it realizes this and doesn’t send repeated retriggers.

Nope - virtual switches are your answer.

Most people who care about this sort of thing use a ‘canary’ bulb that they always keep ‘off’ in a closet or some out of the way place. They periodically check it’s state and if it’s on they know there’s been a power cut and everything got messed up. Most tools/scripts/pistons in this space are all variants on that theme. On timer - check state of bulb if on, turn off bulb, run recovery procedure/piston.

That said - you will NEVER catch the ‘all the lights came on in the middle of the night’ in the bedroom scenario fast enough for your spouse. So make sure you design around that one (In my case all items in my bedroom are either switches or smartbulbs that have the ability to be set to default ‘off’, I think Both Hue and Osram can be set this way.)

A true canary bulb doesn’t have to be polled: it sends a message when it turns back on after a power outage. But as always the first rule of home automation applies: the model number matters. Some models do this, some don’t. There is a discussion of specific brands in the following thread (The topic title is a clickable link):

[RELEASE] SmartBulb Power Outage handler

The hue solution is much more elegant, runs locally, but only works with Hue bulbs connected through a hue bridge.

I may be mistaken, but I thought Osram only had that feature when they were used with their own gateway, not when they were used with smartthings. But maybe I’m wrong.

You definitely need their bridge and app for part of it @JDRoberts - because it requires a default on power on setting / feature that the older firmware doesn’t support. What I’m unclear on is if you use their hub to set it and then their app to set the default, if it retains the setting as a device default when joining a different network or if the disjoin / rejoin action kills that setting. I don’t have an Osram to check, unfortunately. And yeah - the Hue solution is pretty elegant.

1 Like

The best thing about the Hue solution is you don’t need a dedicated canary bulb. You get to set the power restore behavior for every Hue bulb you use in the regular way. So if you want to have the bulbs stay off in the baby’s room but come on in the hallway so it will wake up a parent who can go do whatever they need to do when there’s been a power outage, you can do that.

As I’ve mentioned before, at my house we have some medical monitoring equipment that has to be checked after a power outage/restore, so I do have a bulb that will turn on and wake me up in that scenario, because that’s what I want. Choice is good. :sunglasses:

2 Likes

All webCORE code runs in the SmartThings cloud. Thus, all data about your devices is already on the same server that the Pistons run on. The ST hub is currently mostly just a bridge to bring data from your Zigbee and Z-wave devices (as well as a few LAN connected devices like Philips Hue and Sonos) to the ST Cloud servers.

1 Like

Thanks @ogiewon (and others for your answers too)

Can I just ask then, does smartthings basically store the current state of any device?
This meaning that if I ask “is bulb 1 on?” It actually just checks it’s ‘local’ storage and doesn’t communicate with the bulb to find out the answer?

Or (as I’d assumed)
It talks to the device to find it’s current state?
This meaning that if I ask “is bulb 1 on?” It will ask over the internet to my home network, to my smartthings hub, (and potentially to the bulb) asking for it’s state, which the answer is then returned along the opposite route.

Obviously, if it operates as per my second example, it would be far quicker (but perhaps not observable by the naked eye) to have that value stored in a variable.

But if (as I think you’re saying) smartthings stores the state of each device and returns that instead of actually asking the physical device, it will have no performance difference than storing the info in my own variable.
In fact, in this case storing the state in my own variable will have a detrimental effect on performance due to the increased need for scripts that would update my variables.

Thanks @orangebucket

You mention:
“Bear in mind that piston instances cache the values of global variables on start up, and only write any changes on exit.”

I did read this yes, and I’ve already come across a situation caused by two buttons affecting the same devices which need to act differently depending on what’s already been done, if both buttons are clicked simultaneously it has some strange effects (although it’s unlikely both will be clicked at the same time, I have a motto: “expect, and program for the possible, not the probable”.

Might I ask: if variables are cached at the point a piston is loaded, and changes written on exit - does the same occur for current device states, or will asking for the current device state always be correct to the physical device?

For example

Using variables:

Light is off and variable say it’s off
Piston starts
Do some stuff
Another piston or user action turns on the light and updates the variable
This piston asks " is the light on?" Answer is ‘no’ because the variable we’re checking is cached

Asking for the device state directly:

Light is off
Piston starts
Do some stuff
Another piston or user action turns on the light
This piston asks " is the light on?" Answer is ‘yes’ because the current device states are not cached in the same way as variables

It will generally be correct to what SmartThings believes the correct value of the device is. There may be some devices, for example those that have to be polled for their state, where SmartThings isn’t yet aware of changes made on the device itself. It isn’t going to trigger any polling or anything, it just considers what ST already knows.

I say generally because there is a big gotcha. Consider a condition like:

Bathroom Light switch is on

The way that is evaluated is that the piston first looks to see what the event was that caused the piston to be executed. If the piston is running because it was notified of a new value of the Bathroom Light switch attribute, that attribute value carried in the event will be used in the condition. Only if that is not the case will it look to see what the current value actually is. This applies regardless of how delayed the event is or how long the piston has been running, even if it has been in a wait for hours.

You’ll often see the construct

If
  Bathroom Light switch changes to on
  And
  Bathroom Light switch is on
Then

The second bit doesn’t achieve anything. If changes to on is true, so is is on.

@orangebucket that is really helpful, thanks for your update :grin:

In particular, my question related to light bulbs. Essentially I want to do one thing if another bulb is on and a different thing if the bulb is off

So, for clarity here is an example of what I’m trying to achieve. I’ll now that this is working using variables for the current bulb state, but it has the issue when both ‘buttons’ are pressed together:

I have

  • two bedside lights (lamp 1, lamp 2)
  • Two bedside buttons (button 1, button 2)
  • One ceiling light

When I press button 1:

If lamp 1 is off and lamp 2 is off
Turn lamp 1 on to 50% brightness

If lamp 1 is off and lamp 2 is on
Turn lamp 1 on to 100%
Turn lamp 2 up to 100%
Turn on the ceiling light to 100%

If lamp 1 is on and lamp 2 is off
Turn off lamp 1

If lamp 1 is on and lamp 2 is on
Turn lamp 1 off
Turn lamp 2 down to 50%
Turn off ceiling light

The same (but in reverse) would happen for button 2

So, as you can see, using variables if the second button is pressed before the first button completes processing, it can end up with a lamp on that it thinks is off or a lamp off it thinks is on.

If however the pistons can be queued (only run the piston of button 2 once the piston for button 1 has completed and exited), or if the queries of the current light state are correct even if they’re updated outside the piston, this issue won’t occur.

Thanks @JDRoberts and others that have mentioned Hue bulbs and hubs in regards to the power failure recovery part of my question.

I did make a conscious decision not to go with Hue branded products for 2 main reasons
1, cost - for my first automations I need to buy a starter kit or sorts. With all the bulbs and switches I need, this will soon add up
2, fewer hubs - I’d like to try and keep the number of smart hubs I use to a bare minimum so I opted for the SmartThings hub simply because it offered the advanced actions capability and will talk to many different manufacturers tech (including Hue)

I’m not adverse to using Hue products at all, but I would like to try and stay away from using the hue bridge/hu, resulting in all devices would communicate with my smartthings hub.

I do realise this may cause some issues (such as not having the native hue power failure restore).

What I may have to do in the future is replace the bulbs in rooms where lights coming on in the middle of the night may be a problem, with more expensive bulbs that natively support a set power restore state.

Yes. The ‘current’ value of each device’s Attribute data is stored in the AWS cloud.

Correct.

Correct. Your webCoRE variables end up being stored in the same AWS server database as all of the “Device” data from the physical devices in your home. No need to duplicate this data as it is readily available for every device.

1 Like

Thanks @ogiewon
That is great to know.

I’ll update my original post, and make this change to my pistons :grin:

1 Like

One more thing, as others have already mentioned… SmartThings has stated publicly that their legacy Groovy-based platform will be retired sometime in 2021. Since webCoRE is 100% dependent on Groovy, one should be fairly safe to assume that webCoRE only has at most 7 months left in its current state on the ST platform. If webCoRE is very important to you, it will still available on another platform, that runs webCoRE Pistons locally on that hub, with no need for the internet to be up and running. So, this may be one way to preserve one’s hard work in developing webCoRE Pistons if running them on ST ceases to be an option in the future. Hopefully there will be a webCoRE-like replacement for SmartThings in the future, once the Groovy platform is shut down.

If you plan to stay on the ST platform for a long time, I would encourage you to use the newer ST Automations and Scenes to try to achieve your goals. These should continue to function, and are being improved by the ST team.

Thanks @ogiewon

I take onboard the impending demise of webCoRE in its current form and accept there will be changes to my automations/pistons to come.

As I understand it, if/when webCoRE stops working, the automations that I’ve already set up will not stop as they are run/stored by ST Cloud.

I would happily use the standard automations in the new ST app but I need to consider the following:
1, needs to be easy to manage basic edits and updates, without having to start from scratch if for instance the trigger device is replaced
2, performance isn’t impacted too much. I.e. if having lots of automations exist in the system (for different combinations of values/devices states/times of day) - going from non smart to smart devices, a delay between cause and effect will be noticeable and potentially annoying.

My particular reason for choosing smartthings was that lots of devices will talk to (or at least through) the ST hub, where alternatives seemed to have limitations to manufacturers and/or device types.

At this point I would only assume that true for Rules API stuff. I wouldn’t assume this to be true for anything running in Groovy after the platform shift. If they kill off the Groovy IDE then we have no reason to believe the code will still be running - when the code running your automations stops the automations stop too.

2 Likes