WebCore command delay

@nh.schottfam
I use Global Variable device groups a lot for mass commands like lights off, doors and locks closed.
I have used the built in command delay, 1000 ms max, and had to modify it in the code to be longer as some devices require more than 1000 ms between commands. Blink, IBlinds and Switchbot would be good examples.
Changing the var is a bit of a pain as it moves on every WC update.

  1. Can the command delay be set higher in the code base a permanent structure? 5000 ms is really useful but Blink in particular requires 10 seconds between each command. Gets a bit messy with 7 cameras and 3 modes.

  2. Can we get another system variable for a delay between each device in a group/set/list? This would help overwhelming the network when I ask it to turn off 25 devices at once like in Night mode or check 30 contacts for open/close states.

Cheers!

couple of things

The max command delay is a variable in the code. If using built-in, In current code its at line 2659 in the piston source file:

	(sDEVMAXDEL): 1000L,

That is 1000 ms

command execution is a per piston setting, if that piston is executing all these commands it should use that for all the commands that piston generates. it would seem to protect the mesh, you only would need 100-1000ms between commands.

The goal of this is not to generate a wait between commands to the same device (it can work that way, but to control load by this piston on the entire network). it seems to me you may want your piston to handle devices for waiting 5 seconds, or something differently.

ie if you are turning off a bunch of devices, you have a list of devices, you send the commands. If they devices are not duplicated in the list, it seems < 1000msec would be good to get a command to each device.

If your piston may run again, and send another command to all those devices with 5 seconds, it seems the piston should save $now and make a decision to wait 5 or 10 seconds or whatever before it does something again because it knows it just sent a bunch of commands.

I'm not sure I understand on checking contact states, as that should not be generating commands, it should be reading the HE db for current device state. Ie reading a device attribute is not a device command, but a db operation.

Maybe this example will clarify my ramblings.

I have a piston that sets my blind positions based on the sun.
I have duplicated the commands in the piston as they regularly fail if executed once.
THe command to close the blinds to 25% just failed twice but the events log show the command occured.
If I break these up to singe device commands or execute them manually via the Devices page they always work.
When grouped in a device list they fail; I am assuming because they get sent too quickly.
I have the command delay set to 1000 but it doesn't seem to help.

I can break them all out to separate commands but that just seem so inelegant.

image

Would need to see logs, but I don't expect

With
      list of  device
do
       on()
end with

to be much different that

for each ($device in bbb)
do
     $device.on()
end for each
1 Like

@nh.schottfam
Good idea though as I can put e delay after each $device.on() and that would slow the execution of the members, no?

Now I'm just feeling stupid, I don't use For Each much :wink:
I can't find any demo pistons and this link is a todo Piston - webCoRE Wiki - Web-enabled Community's own Rule Engine.
Searching For Each in the forum is, well, silly. :slight_smile:

The For Each will only let me add another statement not a task for $device.
I can "Add an Action" but that only lets me have generic Location tasks which aren't specific to the device, e.g. close, open etc.

I think this is the same issue without a clear answer. I'm going to try the trick $device suggested.

this is the way

Yes, that's what I did and it seems to be working as intended. :slight_smile:
You just have to trick the Do | Add Task as it doesn't know about the attributes of the specific device by just using $device.

yeah, it does not infer $device capabilities from the variable in the for, though it could (in the future :man_shrugging:)

Why do I feel that several webcore programmers have crossed this path before, with equal frustration? At least as far back as Feb 2020, or further, as suggested here.

(hides in a corner)

2 Likes

The future is nowwwwww! See screen recording.

Well... not now but more like once I feel comfortable enough to deploy this code to staging. I also think I can do the same for $currentEventDevice inside on events from.

3 Likes

unsung hero right here :muscle::clap::heart:

3 Likes

Here is the same concept applied to $currentEventDevice and $currentEventValue inside an on events from block.

Screen recording

This is live on https://staging.webcore.co, just be sure to do a hard refresh if your browser doesn't pick up the new code. If you encounter any issues please look up how to view your browser's developer console and share any red errors that appear there.

$currentEventValue will work as long as all of the attributes in on events from are of the same type (e.g. number, boolean, enum). In the case of multiple enum attributes you'll get a combined list like this for windowShade and switch:

If the on events from block includes two distinct attribute types then $currentEventValue is not enriched. There would be no way to help choose values between an enum like windowShade and a numeric value like power.

3 Likes

I don't see it yet after clearing the cache etc. but I'm sure it's there somewhere. :slight_smile:

Probably me but... :slight_smile:
I cleared all the usual data/cache stuff.
With the $device pointing to a global with Blinds in it I get lighting attibutes for a selection.
I included some HTML but I have no idea what is an error or just standard warnings.

js?libraries=placese…nsO2-Icrc3r8tzc:299 Google Maps JavaScript API has been loaded directly without loading=async. This can result in suboptimal performance. For best-practice loading patterns please see खास जानकारी  |  Maps JavaScript API  |  Google for Developers
js?libraries=placese…nsO2-Icrc3r8tzc:296 The library placeses is unknown. Please see Librerie  |  Maps JavaScript API  |  Google for Developers
pagead2.googlesyndic…js/adsbygoogle.js:1
Failed to load resource: net::ERR_BLOCKED_BY_CLIENT
15
Third-party cookie will be blocked. Learn more in the Issues tab.
js?libraries=placese…nsO2-Icrc3r8tzc:228 Uncaught (in promise) Error: Could not load "placeses".
at HTMLScriptElement. (js?libraries=placese…-Icrc3r8tzc:228:234)

I took a closer look at your piston shared earlier in this thread and found that $device is not working when the for each loop is inside an if/else.

I’ll fix that tomorrow, stay tuned! Unfortunately there is no way to reverse up the statement tree from $device to the for each loop. Instead I have to start at the root of the piston and check every branch until that specific use of $device is found. Seems I need to widen the search a little there if it’s not looking inside if/else statements.

Go ahead and give that another try on staging. It looked like for each statements inside else, else if, and switch case were not working. I think that covers the bases but let me know if you notice any other scenarios where the special device variables do not resolve correctly.

Yeah still odd things out there :wink:
That piston just ran sdending an Open command to the blinds in the last For Each in the piston.
One blind Closed and then reopened 5 seconds later, the one next to it was perfectly fine obeyin g the open command.

Events below show the Open command closin the blind and reopening it:

Another example weirdness just now.
Command to SetPostion sent to blinds. Piston processed, command arrived (see event) but nothing happened. This is happening often and all I can think of is that the SetPosition value isn't being passed.
Works fine from a test piston sending a single command a With.

PS: The next hour trigger worked perfectly with SetPosition.

image

04/03/2024, 10:00:18 +326ms
+4ms ╔Received event [HomeC8].time = 1709575217848 with a delay of 478ms, canQueue: true, calledMyself: false
+111ms ║Runtime (17974 bytes) initialized in 3ms (v0.3.114.20240115_HE)
+146ms ║╔Execution stage started
+196ms ║║Executed device command [Living Room Window Right].setPosition(25) (31ms)
+201ms ║║Executed virtual command [Living Room Window Right].wait [5000] (0ms)
+205ms ║║Requesting wake up at Mon, Mar 4 2024 @ 10:00:23 AM PST (in 4999ms) for 20 (st:22)
+210ms ║╚Execution stage complete. (64ms)
+353ms ║Setting up scheduled job for Mon, Mar 4 2024 @ 10:00:23 AM PST (in 4985ms)
+355ms ╚Event processed successfully (351ms)
04/03/2024, 10:00:12 +646ms
+3ms ╔Received event [HomeC8].time = 1709575212623 with a delay of 23ms, canQueue: true, calledMyself: false
+140ms ║Runtime (17970 bytes) initialized in 2ms (v0.3.114.20240115_HE)
+147ms ║╔Execution stage started
+198ms ║║Executed device command [Living Room Window Couch].setPosition(25) (37ms)
+202ms ║║Executed virtual command [Living Room Window Couch].wait [5000] (1ms)
+204ms ║║Requesting wake up at Mon, Mar 4 2024 @ 10:00:17 AM PST (in 4999ms) for 20 (st:22)
+208ms ║╚Execution stage complete. (62ms)
+262ms ║Setting up scheduled job for Mon, Mar 4 2024 @ 10:00:17 AM PST (in 4989ms)
+264ms ╚Event processed successfully (261ms)

Your'e definitely on to something here with no traversing the statements correctly.
This morning, four of my blinds should have received the same SetPosition(60) command from a For Each.
Three got an Open command and one executed a SetPosition(60)