Piston to play messages on Sonos from other pistons


#1

1) Give a description of the problem
A growing number of my pistons included code to play messages on my Kitchen Sonos. This led to duplicated and inconsistent code. To address this issue and make all other pistons lighter/simpler, I created a piston that plays a string sent to it via an attribute. The code is quite simple as it just looks at what time it is to set the appropriate volume and then plays the message. I am planning on adding an override Boolean to enable a loud message during quiet times for cases where it is a critical message.

2) What is the expected behavior?
I’d like my piston to play the text in the textMessage attribute completely before moving on to the next message. The 2000ms wait was just an attempt to give the piston enough time to play a typical message but it doesn’t seem to make any difference.

3) What is happening/not happening?
I can’t figure out how to prevent overlapping messages from interfering with each other. Messages get truncated by each other mostly, or some just get skipped. I am wondering whether a small buffer might help to keep messages in queue but if I am not mistaken, each time the Piston is run, the variables get reset so I am not sure how to accomplish this.

4) Post a Green Snapshot of the pistonimage

5) Attach any logs (From ST IDE and by turning logging level to Full)
The logs below are what is in the log. It may or may not include the issue. I’ll have to force the overlapping to get a log of that if necessary.

`
11/25/2017, 8:01:39 AM +219ms
+1ms â•”Received event [Dog House].execute = :022e5aba024833ac5e78e468689aa6ad: with a delay of 90ms
+171ms â•‘RunTime Analysis CS > 24ms > PS > 89ms > PE > 58ms > CE
+182ms â•‘Runtime (40721 bytes) successfully initialized in 89ms (v0.2.0fe.20171109) (180ms)
+183ms â•‘â•”Execution stage started
+196ms â•‘â•‘Comparison (enum) on is (string) on = true (1ms)
+198ms â•‘â•‘Condition #1 evaluated true (10ms)
+199ms â•‘â•‘Condition group #null evaluated true (state did not change) (11ms)
+215ms ║║Comparison (time) 28899421 is_between (time) 77400000 … (time) 23400000 = false (8ms)
+217ms â•‘â•‘Condition #26 evaluated false (15ms)
+218ms ║║Cancelling statement #26’s schedules…
+227ms â•‘â•‘Requesting time schedule wake up at Sat, Nov 25 2017 @ 9:30:00 PM CST
+230ms â•‘â•‘Condition group #21 evaluated false (state did not change) (29ms)
+905ms â•‘â•‘Executed physical command [Kitchen Sonos].playTextAndRestore([T Rex escaped containment zone, 60]) (662ms)
+906ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (663ms)
+910ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (0ms)
+910ms â•‘â•‘Waiting for 2000ms
+2914ms ║╚Execution stage complete. (2731ms)
+2916ms â•‘Setting up scheduled job for Sat, Nov 25 2017 @ 9:30:00 PM CST (in 48497.866s)
+2934ms ╚Event processed successfully (2934ms)

11/25/2017, 7:37:56 AM +822ms
+1ms â•”Received event [Dog House].execute = :bf9180acd8cb15dbde41601ef9007c21: with a delay of 5ms
+171ms â•‘RunTime Analysis CS > 24ms > PS > 89ms > PE > 59ms > CE
+182ms â•‘Runtime (40725 bytes) successfully initialized in 89ms (v0.2.0fe.20171109) (181ms)
+183ms â•‘â•”Execution stage started
+197ms â•‘â•‘Comparison (enum) on is (string) on = true (2ms)
+198ms â•‘â•‘Condition #1 evaluated true (10ms)
+199ms â•‘â•‘Condition group #null evaluated true (state did not change) (11ms)
+216ms ║║Comparison (time) 27477024 is_between (time) 77400000 … (time) 23400000 = false (8ms)
+217ms â•‘â•‘Condition #26 evaluated false (15ms)
+218ms ║║Cancelling statement #26’s schedules…
+227ms â•‘â•‘Requesting time schedule wake up at Sat, Nov 25 2017 @ 9:30:00 PM CST
+230ms â•‘â•‘Condition group #21 evaluated false (state did not change) (28ms)
+675ms ║║Executed physical command [Kitchen Sonos].playTextAndRestore([Today’s weather forecast is: Sunny. High near 25C. Winds light and variable., 60]) (432ms)
+676ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (434ms)
+680ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (1ms)
+680ms â•‘â•‘Waiting for 2000ms
+2684ms ║╚Execution stage complete. (2501ms)
+2686ms â•‘Setting up scheduled job for Sat, Nov 25 2017 @ 9:30:00 PM CST (in 49920.493s)
+2697ms ╚Event processed successfully (2697ms)

11/25/2017, 6:29:59 AM +117ms
+0ms â•”Received event [Dog House].time = 1511613000000 with a delay of -884ms
+139ms â•‘RunTime Analysis CS > 22ms > PS > 67ms > PE > 51ms > CE
+150ms â•‘Runtime (40652 bytes) successfully initialized in 67ms (v0.2.0fe.20171109) (148ms)
+151ms â•‘â•”Execution stage started
+163ms â•‘â•‘Comparison (enum) on is (string) on = true (2ms)
+165ms â•‘â•‘Condition #1 evaluated true (8ms)
+166ms â•‘â•‘Condition group #null evaluated true (state did not change) (10ms)
+182ms ║║Comparison (time) 23399286 is_between (time) 77400000 … (time) 23400000 = false (9ms)
+183ms ║║Cancelling condition #26’s schedules…
+184ms â•‘â•‘Condition #26 evaluated false (16ms)
+185ms ║║Cancelling statement #26’s schedules…
+194ms â•‘â•‘Requesting time schedule wake up at Sat, Nov 25 2017 @ 9:30:00 PM CST
+197ms ║║Cancelling condition #21’s schedules…
+198ms â•‘â•‘Condition group #21 evaluated false (state changed) (30ms)
+347ms ║║Executed physical command [Kitchen Sonos].playTextAndRestore([Today’s weather forecast is: Clear. Low 10C., 60]) (136ms)
+348ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (137ms)
+351ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (0ms)
+352ms â•‘â•‘Waiting for 2000ms
+2356ms ║╚Execution stage complete. (2206ms)
+2359ms â•‘Setting up scheduled job for Sat, Nov 25 2017 @ 9:30:00 PM CST (in 53998.525s)
+2395ms ╚Event processed successfully (2396ms)

11/24/2017, 9:56:51 PM +183ms
+1ms â•”Received event [Dog House].execute = :bf9180acd8cb15dbde41601ef9007c21: with a delay of 12ms
+189ms â•‘RunTime Analysis CS > 26ms > PS > 114ms > PE > 50ms > CE
+200ms â•‘Runtime (40691 bytes) successfully initialized in 114ms (v0.2.0fe.20171109) (199ms)
+201ms â•‘â•”Execution stage started
+214ms â•‘â•‘Comparison (enum) on is (string) on = true (2ms)
+216ms â•‘â•‘Condition #1 evaluated true (9ms)
+216ms â•‘â•‘Condition group #null evaluated true (state did not change) (11ms)
+232ms ║║Comparison (time) 79011402 is_between (time) 77400000 … (time) 23400000 = true (8ms)
+233ms â•‘â•‘Time restriction check passed
+235ms â•‘â•‘Condition #26 evaluated true (16ms)
+236ms ║║Cancelling statement #26’s schedules…
+244ms â•‘â•‘Requesting time schedule wake up at Sat, Nov 25 2017 @ 6:30:00 AM CST
+247ms â•‘â•‘Condition group #21 evaluated true (state did not change) (28ms)
+249ms ║║Cancelling statement #24’s schedules…
+253ms â•‘â•‘Executed virtual command setVariable (1ms)
+633ms ║║Executed physical command [Kitchen Sonos].playTextAndRestore([Today’s weather forecast is: Clear. Low 10C., 35]) (369ms)
+634ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (370ms)
+638ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (0ms)
+638ms â•‘â•‘Waiting for 2000ms
+2641ms ║╚Execution stage complete. (2440ms)
+2643ms â•‘Setting up scheduled job for Sat, Nov 25 2017 @ 6:30:00 AM CST (in 30786.175s)
+2658ms ╚Event processed successfully (2658ms)

11/24/2017, 9:51:40 PM +500ms
+0ms â•”Received event [Dog House].execute = :022e5aba024833ac5e78e468689aa6ad: with a delay of 349ms
+164ms â•‘RunTime Analysis CS > 25ms > PS > 92ms > PE > 48ms > CE
+184ms â•‘Runtime (40690 bytes) successfully initialized in 92ms (v0.2.0fe.20171109) (183ms)
+185ms â•‘â•”Execution stage started
+198ms â•‘â•‘Comparison (enum) on is (string) on = true (2ms)
+200ms â•‘â•‘Condition #1 evaluated true (10ms)
+201ms â•‘â•‘Condition group #null evaluated true (state did not change) (11ms)
+216ms ║║Comparison (time) 78700704 is_between (time) 77400000 … (time) 23400000 = true (8ms)
+217ms â•‘â•‘Time restriction check passed
+219ms â•‘â•‘Condition #26 evaluated true (15ms)
+220ms ║║Cancelling statement #26’s schedules…
+228ms â•‘â•‘Requesting time schedule wake up at Sat, Nov 25 2017 @ 6:30:00 AM CST
+230ms â•‘â•‘Condition group #21 evaluated true (state did not change) (27ms)
+233ms ║║Cancelling statement #24’s schedules…
+236ms â•‘â•‘Executed virtual command setVariable (1ms)
+403ms â•‘â•‘Executed physical command [Kitchen Sonos].playTextAndRestore([T Rex safely contained, 35]) (154ms)
+403ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (156ms)
+407ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (1ms)
+408ms â•‘â•‘Waiting for 2000ms
+2411ms ║╚Execution stage complete. (2226ms)
+2413ms â•‘Setting up scheduled job for Sat, Nov 25 2017 @ 6:30:00 AM CST (in 31097.088s)
+2448ms ╚Event processed successfully (2448ms)

11/24/2017, 9:29:59 PM +95ms
+1ms â•”Received event [Dog House].time = 1511580600000 with a delay of -906ms
+172ms â•‘RunTime Analysis CS > 25ms > PS > 85ms > PE > 63ms > CE
+183ms â•‘Runtime (40678 bytes) successfully initialized in 85ms (v0.2.0fe.20171109) (181ms)
+185ms â•‘â•”Execution stage started
+201ms â•‘â•‘Comparison (enum) on is (string) on = true (2ms)
+203ms â•‘â•‘Condition #1 evaluated true (11ms)
+205ms â•‘â•‘Condition group #null evaluated true (state did not change) (13ms)
+226ms ║║Comparison (time) 77399304 is_between (time) 77400000 … (time) 23400000 = true (11ms)
+228ms â•‘â•‘Time restriction check passed
+230ms ║║Cancelling condition #26’s schedules…
+231ms â•‘â•‘Condition #26 evaluated true (22ms)
+241ms ║║Cancelling statement #26’s schedules…
+253ms â•‘â•‘Requesting time schedule wake up at Sat, Nov 25 2017 @ 6:30:00 AM CST
+257ms ║║Cancelling condition #21’s schedules…
+258ms â•‘â•‘Condition group #21 evaluated true (state changed) (50ms)
+261ms ║║Cancelling statement #24’s schedules…
+267ms â•‘â•‘Executed virtual command setVariable (1ms)
+442ms â•‘â•‘Executed physical command [Kitchen Sonos].playTextAndRestore([T Rex escaped containment zone, 35]) (154ms)
+443ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (155ms)
+447ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (1ms)
+448ms â•‘â•‘Waiting for 2000ms
+2452ms ║╚Execution stage complete. (2268ms)
+2454ms â•‘Setting up scheduled job for Sat, Nov 25 2017 @ 6:30:00 AM CST (in 32398.452s)
+2522ms ╚Event processed successfully (2522ms)

11/24/2017, 8:09:05 PM +581ms
+0ms â•”Received event [Dog House].execute = :022e5aba024833ac5e78e468689aa6ad: with a delay of 81ms
+153ms â•‘RunTime Analysis CS > 24ms > PS > 90ms > PE > 40ms > CE
+163ms â•‘Runtime (40700 bytes) successfully initialized in 90ms (v0.2.0fe.20171109) (162ms)
+164ms â•‘â•”Execution stage started
+177ms â•‘â•‘Comparison (enum) on is (string) on = true (2ms)
+179ms â•‘â•‘Condition #1 evaluated true (9ms)
+179ms â•‘â•‘Condition group #null evaluated true (state did not change) (10ms)
+194ms ║║Comparison (time) 72545763 is_between (time) 77400000 … (time) 23400000 = false (8ms)
+196ms â•‘â•‘Condition #26 evaluated false (14ms)
+197ms ║║Cancelling statement #26’s schedules…
+205ms â•‘â•‘Requesting time schedule wake up at Fri, Nov 24 2017 @ 9:30:00 PM CST
+207ms â•‘â•‘Condition group #21 evaluated false (state did not change) (25ms)
+346ms â•‘â•‘Executed physical command [Kitchen Sonos].playTextAndRestore([T Rex escaped containment zone, 60]) (126ms)
+347ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (128ms)
+350ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (0ms)
+351ms â•‘â•‘Waiting for 2000ms
+2354ms ║╚Execution stage complete. (2190ms)
+2356ms â•‘Setting up scheduled job for Fri, Nov 24 2017 @ 9:30:00 PM CST (in 4852.064s)
+2372ms ╚Event processed successfully (2372ms)

11/24/2017, 7:56:08 PM +703ms
+0ms â•”Received event [Dog House].execute = :022e5aba024833ac5e78e468689aa6ad: with a delay of 430ms
+155ms â•‘RunTime Analysis CS > 25ms > PS > 90ms > PE > 41ms > CE
+166ms â•‘Runtime (40703 bytes) successfully initialized in 90ms (v0.2.0fe.20171109) (165ms)
+167ms â•‘â•”Execution stage started
+180ms â•‘â•‘Comparison (enum) on is (string) on = true (2ms)
+182ms â•‘â•‘Condition #1 evaluated true (10ms)
+183ms â•‘â•‘Condition group #null evaluated true (state did not change) (11ms)
+199ms ║║Comparison (time) 71768889 is_between (time) 77400000 … (time) 23400000 = false (8ms)
+200ms â•‘â•‘Condition #26 evaluated false (15ms)
+201ms ║║Cancelling statement #26’s schedules…
+210ms â•‘â•‘Requesting time schedule wake up at Fri, Nov 24 2017 @ 9:30:00 PM CST
+213ms â•‘â•‘Condition group #21 evaluated false (state did not change) (27ms)
+1137ms â•‘â•‘Executed physical command [Kitchen Sonos].playTextAndRestore([T Rex escaped containment zone, 60]) (912ms)
+1138ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (913ms)
+1142ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (0ms)
+1142ms â•‘â•‘Waiting for 2000ms
+3146ms ║╚Execution stage complete. (2979ms)
+3148ms â•‘Setting up scheduled job for Fri, Nov 24 2017 @ 9:30:00 PM CST (in 5628.15s)
+3204ms ╚Event processed successfully (3204ms)

11/24/2017, 7:05:02 PM +795ms
+0ms â•”Received event [Dog House].execute = :609aeefd68292337bb328175d3086833: with a delay of 7ms
+171ms â•‘RunTime Analysis CS > 26ms > PS > 98ms > PE > 47ms > CE
+182ms â•‘Runtime (40692 bytes) successfully initialized in 98ms (v0.2.0fe.20171109) (181ms)
+183ms â•‘â•”Execution stage started
+196ms â•‘â•‘Comparison (enum) on is (string) on = true (2ms)
+198ms â•‘â•‘Condition #1 evaluated true (9ms)
+198ms â•‘â•‘Condition group #null evaluated true (state did not change) (10ms)
+214ms ║║Comparison (time) 68702996 is_between (time) 77400000 … (time) 23400000 = false (8ms)
+216ms â•‘â•‘Condition #26 evaluated false (15ms)
+217ms ║║Cancelling statement #26’s schedules…
+225ms â•‘â•‘Requesting time schedule wake up at Fri, Nov 24 2017 @ 9:30:00 PM CST
+228ms â•‘â•‘Condition group #21 evaluated false (state did not change) (27ms)
+373ms â•‘â•‘Executed physical command [Kitchen Sonos].playTextAndRestore([Garage Door Closed and Locked, 60]) (132ms)
+374ms â•‘â•‘Executed [Kitchen Sonos].playTextAndRestore (133ms)
+377ms â•‘â•‘Executed virtual command [Kitchen Sonos].wait (0ms)
+378ms â•‘â•‘Waiting for 2000ms
+2382ms ║╚Execution stage complete. (2199ms)
+2384ms â•‘Setting up scheduled job for Fri, Nov 24 2017 @ 9:30:00 PM CST (in 8694.822s)
+2403ms ╚Event processed successfully (2402ms)
`


#2

First off don’t have voice notifications here. But, what if you created a new piston to actually play the Notifications. The with each piston pass the message to that piston with args. As they are received, have them save the messages to a variable. Wait an amount of time , lets say 30 seconds, and then play the messages from that piston.

Just remember to clear the variable after run so you don’t save previous messages.

Just a thought


#3

@Gopack2 - The piston above is exactly what you are suggesting and I edited my post to spell that out as I noticed I totally skipped that bit… I call the piston above each time I want to play a message and the piston above will handle both the volume setting based on the time and the actual playing. The issue is that when multiple pistons call this piston to play a message, things get screwed up… messages stop playing, some get cut off in favor of another, etc. What I need to figure out is a way to queue messages sent to this piston so that they can all be played in sequence. As for the delay, I can’t have 30 seconds as the notifications are often things that change relatively quickly and are only relevant in that moment… for example a door opening or closing. As an example, if my toddler opens the front door, I want to hear the notification immediately so I can chase after him.

This is an example piston that cals the piston above to play a message:


#4

I was using 30 secs as an arbitrary time to allow all the different pistonsto populate the variable, you can set that to suit you needs.

What I am proposing is when you execute this piston from another one pass the args to this piston. Set the variable text message = textmessage + $args.textMessage

This way that variable grows as more pistons add to it. Then after the wait( that you set by how long it generally takes to populate the whole text message) trigger the play message command. After which clear the variable.

That should work, however may not meet your needs. Just some food for thought


#5

Thank you for the suggestions. I need to do some testing along those lines. My understanding was that the variable is sent to some “TTS service” to create an audio file that is then sent to the Sonos so adding to the existing variable might result in the same message being repeated every time something is added to it. However, if I pass the arguments sent to the piston to an array, I could store multiple messages that get cleared as they get played. I have not tried this as the first issue I was trying to resolve was finding a way to prevent anything from stopping the message that is currently playing… and because I have no idea how to implement/use a global array in a piston (I am a very basic programmer).


#6

I AM STUMPED…

I tried a number of things and implemented some code that I found online which I believe was from @ipaterson but I still can’t get it to work properly. Messages play in full most of the time however I have one piston that calls the Alert Player piston twice to play the current time, and then the weather forecast. The time typically plays in full, but the weather forecast always gets truncated a few seconds into the alert. I believe, in some cases, both messages would get truncated but I can’t recall where I was at with the code when that was happening.

One of the pistons below calls the other twice. The first time it tells the current time (and yes it is very poorly done at this time as it doesn’t read the time as a human would but it is just a place keeper for now until I resolve the bigger issue) and the second time it provide a weather report that gets updated every 30 minutes by a 3rd piston.

The reason for multiple pistons is to make things modular. All my alerts are played by the alert player so I am trying to build in some way for it to play a message and if another one comes in too soon, to keep it in its buffer until it is ok to play it. In the future I might also add a sequence number so that messages that get to the player out of order can get skipped (I have door unlocked, open and unlocked, closed, closed and locked messages but due to differences in how fast a contact versus the lock report their status, I sometimes get “door unlocked” [reported by lock] after “door unlocked and open” [reported by door contact]). I may also bake in a flush feature where a message that for any reason has not reached the player for x amount of time just gets flushed unless marked critical.

Back to the issue at hand… what is causing my second, and sometimes first, messages to get truncated?