MCE - Scene not quite working need help.. (Resolved) I think.

Hi

I created a scene that is triggered by my Foscam sensor, this scene turns on a light and starts the Countdown timer add-in for 60 secs, it also sends the code below to “MCE Controller” on the Windows Media Center PC to popup a message and then open an add-in in Media Center to display the IP camera live video.

luup.inet.wget("http://192.168.0.6:40510/msgbox%20%22Motion%22%20%22Detected%20Back%20Garden%22%205") luup.sleep(3500) local socket = require("socket") host = "192.168.0.6" c = assert(socket.connect(host, 5150)) c:send("mControl") c:close()

Once the countdown timer reaches 0 another scene turns the light off.

This all works great when the Windows Media Center PC is turned on!

However when the PC is turned off the scene chokes and doesn’t run. I then can’t run any other scenes manually until I click the Reload button in the Vera web UI. When I do click the Reload button it then says “Received Empty Response” on the problem scene.

Is there any code I can add so the scene continues to work if the MCE PC is turned off ?

Thanks

There’s a settimeout() function in the LuaSocket library. Never used it, but according to the documentation it applies to the connect() function and causes it to return nil on failure. Give it a try. No, I don’t have example code.

I think all scenes run inside the one Lua context, which would explain the hang.

Code is not my strong point…

Here is a guy who had the same problem:

http://forum.micasaverde.com/index.php?topic=11182.0

Suggested solution:

[i]You need to used socket.tcp to get the handle, then set the timeout on it, then do a connect on the resulting handle.

There are a few examples on the web if you search for “luasocket timeout”[/i]

Solution:

[i]Great thanks.

This now works for when the server is either running or is not without any delays:[/i]

local socket = require("socket") host = "192.168.0.3" local tcp = assert(socket.tcp()) if( tcp ~= "nil" and tcp ~= nill) then tcp:settimeout(1) tcp:connect(host, 5150) tcp:send("@movie\r") tcp:close() end

This is my current code for my scene:

luup.inet.wget("http://192.168.0.6:40510/msgbox%20%22Motion%22%20%22Detected%20Back%20Garden%22%205") luup.sleep(3500) local socket = require("socket") host = "192.168.0.6" c = assert(socket.connect(host, 5150)) c:send("mControl") luup.sleep(2000) c:send("right") luup.sleep(500) c:send("right") luup.sleep(500) c:send("right") luup.sleep(500) c:send("right") luup.sleep(500) c:send("down") luup.sleep(500) c:send("ok") c:close()

Can I use this socket.tcp in my code ?

Thanks.

Tried merging code from here:

http://forum.micasaverde.com/index.php/topic,11182.msg79536.html#msg79536

In to my code:

luup.inet.wget("http://192.168.0.6:40510/msgbox%20%22Motion%22%20%22Detected%20Back%20Garden%22%205") luup.sleep(3500) local socket = require("socket") host = "192.168.0.6" local client = socket.connect(host, 5150) if (client == "nil" or client == nil) then luup.log("Connection to pc failed") else luup.log("Connection to PC OK") client:settimeout(3) client:send("mControl") luup.sleep(2000) client:send("right") luup.sleep(500) client:send("right") luup.sleep(500) client:send("right") luup.sleep(500) client:send("right") luup.sleep(500) client:send("down") luup.sleep(500) client:send("ok") client:close() end

But Vera still hangs it PC is asleep.

EDIT: As the other guy discovered if you wait long enough about 3 mins the scene will eventually run with the above code if the PC is off. But 3 mins is too long to wait. Need to look at the other code.

OK the scene is working quicker with the below code, when the PC happens to be in sleep mode ;D

However its not instant, there is still some delay before the light in the scene turns on. (About 25 seconds) But guess that’s better than 3 minutes.

Changed the code to use tcp instead of client commands.

luup.inet.wget("http://192.168.0.6:40510/msgbox%20%22Motion%22%20%22Detected%20Back%20Garden%22%205") luup.sleep(3500) local socket = require("socket") host = "192.168.0.6" local tcp = assert(socket.tcp()) if( tcp ~= "nil" and tcp ~= nill) then tcp:settimeout(1) tcp:connect(host, 5150) tcp:send("mControl") luup.sleep(2000) tcp:send("right") luup.sleep(500) tcp:send("right") luup.sleep(500) tcp:send("right") luup.sleep(500) tcp:send("right") luup.sleep(500) tcp:send("down") luup.sleep(500) tcp:send("ok") luup.sleep(10000) tcp:send("up") tcp:send("ok") tcp:close() end

[quote=“futzle, post:2, topic:172461”]There’s a settimeout() function in the LuaSocket library. Never used it, but according to the documentation it applies to the connect() function and causes it to return nil on failure. Give it a try. No, I don’t have example code.

I think all scenes run inside the one Lua context, which would explain the hang.[/quote]

Thanks for pointing me in the right direction btw! Searching for settimeout() found the solution.

Don’t use sleep. Just bad idea. You need your scene to complete regardless of success or fail. Trigger the other function using a delay. I’ll give a sample in next post.

The settimeout idea is really good. I need to do that myself. My MCE scenes don’t have dependencies so if I fire one off when the computer is off, it eventually fails, but no biggie…
Using a “call_timer” will allow the scene to complete and the failure actually occurs in another thread (so to speak).

Here’s a sample of code I used before I found the timer and combo switch:

[code]function deferLockScene(package)
if(lockInsecuredId == package) then
local veraUri = “urn:micasaverde-com:serviceId:HomeAutomationGateway1”
luup.call_action(veraUri , “RunScene”, {SceneNum = “1”}, 0)
end
end

lockInsecuredId = os.time() … “”
luup.call_timer(“deferLockScene”, 1, “1m”, “”, lockInsecuredId )[/code]

What this code does is sets a global variable to ensure that only the very last ‘deferLockScene’ actually executes and nothing executes prematurely.
If there was a ‘cancel_timer’ function I would have done this differently, but they don’t have that yet in UI5. (Similar to JavaScript’s setTimeout and clearTimeout).

Are you using the WakeOnLAN plugin to make sure the PC wakes up first?

I put those sleep commands in initially to slow down the navigational commands being sent to Media Center or it just couldn’t cope and it would not navigate to the correct place in MCE / mControl add-in where my IP camera can be viewed.

[quote=“electricessence, post:8, topic:172461”]The settimeout idea is really good. I need to do that myself. My MCE scenes don’t have dependencies so if I fire one off when the computer is off, it eventually fails, but no biggie…
Using a “call_timer” will allow the scene to complete and the failure actually occurs in another thread (so to speak).

Here’s a sample of code I used before I found the timer and combo switch:

[code]function deferLockScene(package)
if(lockInsecuredId == package) then
local veraUri = “urn:micasaverde-com:serviceId:HomeAutomationGateway1”
luup.call_action(veraUri , “RunScene”, {SceneNum = “1”}, 0)
end
end

lockInsecuredId = os.time() … “”
luup.call_timer(“deferLockScene”, 1, “1m”, “”, lockInsecuredId )[/code]

What this code does is sets a global variable to ensure that only the very last ‘deferLockScene’ actually executes and nothing executes prematurely.
If there was a ‘cancel_timer’ function I would have done this differently, but they don’t have that yet in UI5. (Similar to JavaScript’s setTimeout and clearTimeout).

Are you using the WakeOnLAN plugin to make sure the PC wakes up first?[/quote]

This is getting a bit complex for my simple understanding of programming, if I have clear instructions to follow I can get by but to start code new stuff on my own I’d be lost. I will have to read the above again for half an hour lol to try and understand what that code does!

I am not using WOL with this scene no.

Here is what I have setup.

Scene1: Motion Detected - Lights On

Scene is triggered by Foscam Sensor on outdoor IP Cam (If Armed)
Scene turns on Light in the kitchen
Scene starts a 60 second count down timer.
Scene has all that Luup code in it I posted above - So if MCE PC is on I get a popup and it jumps to live video for camera.
If MCE PC is asleep then so am I probably! But scene continues to run and the Light is still switched on within about 25 secs?

Scene2: Motion Detected - Lights Off
Scene is triggered by CountDown Complete (CountDown Timer)
Scene turns off the Light in the kitchen.

It seems to work fairly well as I have it setup now, if the MCE PC is on or asleep… But always happy to try and learn new things. Loving VeraLite only been using it a week and I have pretty much fully recreated my old Home Automation system based on mControl on my WHS server and then some!

Thanks

Youtube video of this scene in MCE

I really want to help you with this.
So let me get this straight. How do you ensure the PC is on?
I’m using WOL now and it works great. You should send that signal immediately to wake it up from a possible hibernate. 60 seconds later then do the lights etc.

The other side of this coin is that you may need to plan for your scene to fail.
What if you can’t access the PC for some reason, do you want the scene to continue?

@cw-kid, you might want to do a WOL and then use the ping sensor to see if the machine is actually up.

Why do I need to WOL the PC? If the PC is on then I am in Media Center watching TV or whatever, so will see the popup in MCE. If the PC is off then so is the TV. If I could turn on the TV and AVR via VeraLite which I can’t, then maybe then I’d want to wake the PC for this scene.

And yes if PC is asleep I need the scene to still run and turn on the light inside when motion detected on camera.

Not related to this scene, I have installed the WOL plugin for Vera and also now know how to send a sleep command to the PC via MCE Controller Kindel. So I can wake and sleep the PC via VeraLite if need be?

Thanks

I’d be interested to know more about this, so using ping you can display in Vera if a PC is awake or not?

Thanks

@cw-kid:
If you don’t need to worry about the wake state of the computer and just want the notification, then all you need is to wrap your MCE commands in a function like I posted and call the function instead of calling it directly.
The scene should continue and complete and the MCE command will simply “attempt” to work.

function mcecommand(payload) ... end luup.call_timer(mcecommand,delay,params)

[quote=“electricessence, post:18, topic:172461”]function mcecommand(payload) ... end luup.call_timer(mcecommand,delay,params) [/quote]

Electricessence,

This is my working code below, how do I add your suggested code to it ?

luup.inet.wget("http://192.168.0.6:40510/msgbox%20%22Motion%22%20%22Detected%20Back%20Garden%22%205") luup.sleep(3500) local socket = require("socket") host = "192.168.0.6" local tcp = assert(socket.tcp()) if( tcp ~= "nil" and tcp ~= nill) then tcp:settimeout(1) tcp:connect(host, 5150) tcp:send("mControl") luup.sleep(2000) tcp:send("right") luup.sleep(500) tcp:send("right") luup.sleep(500) tcp:send("right") luup.sleep(500) tcp:send("right") luup.sleep(500) tcp:send("down") luup.sleep(500) tcp:send("ok") luup.sleep(10000) tcp:send("up") tcp:send("ok") tcp:close() end

Break it up into pieces delimited by sleep()s, and turn each one into a function:

function step1() luup.inet.wget("http://192.168.0.6:40510/msgbox%20%22Motion%22%20%22Detected%20Back%20Garden%22%205") end

-- pull the local statements out from inside the function local socket = require("socket") local host local tcp function step2() host = "192.168.0.6" tcp = assert(socket.tcp()) if(tcp) then -- simpler version of your test tcp:settimeout(1) tcp:connect(host, 5150) tcp:send("mControl") end end

function step3() tcp:send("right") end
… you get the idea …

function step9() tcp:send("up") tcp:send("ok") tcp:close() end

To each step, add a luup.call_delay() to daisy-chain to the next. The delay is in seconds, not milliseconds.

function step1() luup.inet.wget("http://192.168.0.6:40510/msgbox%20%22Motion%22%20%22Detected%20Back%20Garden%22%205") luup.call_delay("step2", 3.5, "") -- do fractional seconds work? Try it and tell us. end

function step2() socket = require("socket") host = "192.168.0.6" local tcp = assert(socket.tcp()) if(tcp) then tcp:settimeout(1) tcp:connect(host, 5150) tcp:send("mControl") luup.call_delay("step3", 2, "") -- inside if(), so step3 is never called if the test fails. end end

function step3() tcp:send("right") luup.call_delay("step4", 0.5, "") end

… except for step9 that has no function to call.

Bang them all together, then light the fuse:

-- not in a function step1()