Using webCoRE with Hubitat

Is there a GitHub repository with this modified webcore hanging around?

2 Likes

Tony,

Looks like that line you referenced is call a function called pause(). What is interesting is the definition of that function , as shown below, does NOT support passing any arguments into it, which is probably why the error is being thrown. So, I am not sure why that would have ever worked.

Map pause() {

Now I am the first to admit that I am not much of a Groovy programmer, so maybe I am missing something obvious here?

Interesting. That line appears in the code as ’ pause(delay)’ and also has that same usage in line 2155 of the WebCore code.

Going by the WebCoRE log message that gets generated immediately before it is used (in WebCoRE Piston) with an action of ‘Wait 4 seconds’, it appears that delay in my failing testcase evaluates to 4000 (4000ms). If I comment out that line (in WebCoRE Piston), no errors are thrown, but no delay happens either, so it seems to be the culprit. I’ve used ‘Wait’ actions with the ST version, and they certainly work in that environment.

From looking at the code near line 607 where pause() appears after the Map keyword I see the msg string “Piston successfully stopped” so I assume (and I am definitely out on a limb here) that the pause function may also serve to ‘Pause’ the entire piston… and I’ve seen some odd behavior with that feature as well (as in, it doesn’t seem to pause the piston at all). Fixing that may fix both issues.

Line 1644 gives us a clue:

if (rtData.logging > 1) trace "Waiting for ${delay}ms", rtData

All the pause(delay) call should do is wait delay milliseconds.

Looking at the pause() function, in addition to stopping a Piston, it's set up to return the runtime data Map rtdata. This doesn't match the call from line 1645 at all.

This is because the pause(delay) function must be elsewhere. I assume in another executable.

Any idea what the ’ Map pause()’ section does around line 606? Then there’s the asycnttp_v1 includes that need to be commented out; possibly something missing from there. Would be nice if this was fixable; the functionality is severly limited without the ability to do waits.

All, I have successfully found a workaround to the pause() issue found by @Tony earlier. In both the webCoRE and webCoRE Piston apps, you must replace all 'pause(argument)' calls with 'pauseExecution(argument)' calls instead. Only change the pause calls that have an argument passed to them, and of course keep using the original argument!

Note: DO NOT change the 'piston.pause()' call in the main webCoRE app. It is the one call that uses the 'map pause() {...}' function defined in the Piston app.

I have forked Adrian's webCoRE GitHub repository at (removed link - see update below) so I could have one place to share our collective fixes to make webCoRE run more reliably on Hubitat. If you have other fixes, please share them here so all are aware of them. You can also issue a pull request to my GitHub repository so we can keep the four apps up to date in a common location. Thanks for that idea, @justin.bennett.

UPDATE: Please use the community supported version of webCoRE for Hubitat found in the following thread. This version is much more up to date than the version I had been maintaining early on.

5 Likes

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 :sweat_smile:

In all seriousness, am really glad you took this initiative. Thanks for keeping webCoRE alive even on Hubitat!

1 Like

Well done! Now (peeling the next layer of the onion) all we are missing is the ability to use button devices. Still this is major progress. Thanks!

1 Like

@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.

2 Likes

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! :wink:

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)
+557ms ║║Cancelling statement #3's schedules...
+569ms ║║Executed physical command [Kitchen Sink Light].on() (8ms)
+570ms ║║Executed [Kitchen Sink Light].on (9ms)
+575ms ║║Executed virtual command [Kitchen Sink Light].wait (0ms)
+575ms ║║Waiting for 4000ms
+4581ms ║║Skipped execution of physical command [Kitchen Sink Light].off([]) because it would make no change to the device. (1ms)
+4582ms ║║Executed [Kitchen Sink Light].off (3ms)
+4585ms ║╚Execution stage complete. (4314ms)
+4591ms ╚Event processed successfully (4590ms)

As I recall CoRE had an option to turn off command optimization but I can't seem to find a setting to do that in WebCoRE.

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.

3 Likes

@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

3 Likes

Oh yes, there it is… I was beginning to think I imagined that settings screen.

1 Like

So did you guys get it to all work? Anybody sharing the code?

@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!

3 Likes

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?