Every time you do something incredible out here or on the ST forums, I try my best to resist from responding with 'Dan's the man!'. Couldn’t help it this time
In all seriousness, am really glad you took this initiative. Thanks for keeping webCoRE alive even on Hubitat!
@ajayjohnm - I think I have fixed this one too by changing out the asynchttp_v1.put() call for just a normal synchronous httpPut() call. This was not just a simply change of the function call. I had to hack away at it to make it work, so it looks a little different. But at least it seems to return "OK" as the response!
I just updated the webCoRE Dashboard app in my github repo with this change as well.
I suspect the asyncHTTP is more relevant for web traffic because it allows for out-of-order packets, maybe? Local processing shouldn’t have that issue.
Also this:
Automatic smart request retries optimized for spotty mobile connections
In the Dashboard app, Adrian wasn't even declaring a handler for the response data. The Asynch Put was truly a 'fire and forget' call, just to update the Dashboard. Making is Asynch meant the code never had to wait for a response. Using the standard httpPut() call, the code will have to wait for a reply. If anyone knows of a method to avoid this, I am all ears. I'm just hacking my way through each error as they pop up!
So the good news is, waits do indeed now work correctly. But something still isn't right with the execution. Tried this simple piston (turn light on, wait 4 sec, turn light off):
The piston triggers properly and light does turn on, but never turns off; log shows no errors (that's the scary part) and says that physical command execution was skipped because it would make no change to the device:
+1ms
╔Received event [Deck Light].switch = off with a delay of 94ms
+221ms
║RunTime Analysis CS > 161ms > PS > 15ms > PE > 45ms > CE
+269ms
║Runtime (36586 bytes) successfully initialized in 15ms (v0.3.000.20180224) (268ms)
+270ms
║╔Execution stage started
+553ms
║║Comparison (enum) off changes_to (string) off = true (1ms)
+554ms
║║Cancelling condition #2's schedules...
+555ms
║║Condition #2 evaluated true (277ms)
+555ms
║║Cancelling condition #1's schedules...
+556ms
║║Condition group #1 evaluated true (state changed) (279ms)
Maybe the status of the device isn’t being recognized as changed even though the command was sent? Is there a way to confirm the device is on after sending the “on” command?
IF the light is already ON when you send the piston, does it then turn the light off?
Agreed, WebCoRE isn’t seeing the correct state of the device; I don’t think it is sending out the off command (though the log implies it is, somewhat contradicting itself).Turning off the optimization might be an easier workaround (especially if there is a setting somewhere), finding out where the state is being kept (and why it isn’t correct) sounds a lot more difficult.
So when the light is already on, it does turn off after the delay. In this case the optimization (on the front end) works as shown in the log:
3/5/2018, 11:54:49 PM +90ms
+0ms ╔Received event [Deck Light].switch = off with a delay of 100ms
+182ms ║RunTime Analysis CS > 123ms > PS > 16ms > PE > 44ms > CE
+233ms ║Runtime (36587 bytes) successfully initialized in 16ms (v0.3.000.20180224) (232ms)
+234ms ║╔Execution stage started
+545ms ║║Comparison (enum) off changes_to (string) off = true (1ms)
+546ms ║║Cancelling condition #2’s schedules…
+547ms ║║Condition #2 evaluated true (305ms)
+548ms ║║Cancelling condition #1’s schedules…
+548ms ║║Condition group #1 evaluated true (state changed) (306ms)
+550ms ║║Cancelling statement #3’s schedules…
+558ms ║║Skipped execution of physical command [Kitchen Sink Light].on([]) because it would make no change to the device. (3ms)
+558ms ║║Executed [Kitchen Sink Light].on (4ms)
+562ms ║║Executed virtual command [Kitchen Sink Light].wait (0ms)
+562ms ║║Waiting for 4000ms
+4582ms ║║Executed physical command [Kitchen Sink Light].off() (11ms)
+4584ms ║║Executed [Kitchen Sink Light].off (14ms)
+4586ms ║╚Execution stage complete. (4352ms)
+4592ms ╚Event processed successfully (4592ms)
Code around line 1677 of WebCoRE Piston is relevant to command optimization. It can be disabled in that line (by setting disableCommandOptimization from false to true). My test case now works! Not sure if this has any other side effects (and it is only masking the problem); will keep peeling.
Needless to say, it’s probably not a good idea to sequence any rocket launches with WebCoRE on Hubitat at this time.
@Tony WebCoRE does allow you to set the command optimization as well. Simply edit the Piston, click on the piston title to take you to the “Piston Settings” screen, click cog, choose Command Optimizations and then choose Disable
@ogiewon created a github repo a few posts up. I have a couple announcement pistons that would be slightly difficult to recreate in Rule Machine (with a lot of local variables) running without issue. I also have the dist folder running on a local web server, so everything including the web interface is running locally! I tested a simple lighting automation and Rule Machine is noticeably faster. There’s a lot of overhead with webCoRE. Right tool for the right job I suppose!
Thanks for all that, I was should have it up and running shortly. Does your statement above mean Webcore's TTS works with hubitat? Also, I have a 24/7 machine sitting next to me what do I need to do to get this all running local?
I actually haven’t worked with webCoRE TTS, so not sure if it’s working. I’m using a custom driver to call a speak() command.
Nice! Just to be clear, the pistons all run locally. The web server is only used for setting up the piston. Currently there aren’t any big advantages to running the web interface locally. A future advantage is if there’s a webCoRE platform change requiring an update to the app code on Hubitat. I doub’t webCoRE is going anywhere so shouldn’t have to worry about access to webcore.co disappearing.
What type of machine do you have running? WAMP is probably the easiest to get set up on Windows. Pretty much the only change to the code is to initialize the endpoint to the local URL instead of cloud URL on line 852: