Setting up IF/THEN with Lua

Okay, please forgive the crudeness of my code, I am trying to learn here and was trying to put bits and pieces of examples I have seen together to something workable.

My goal is to set up a Scene that runs between 15 min. before sunset and 15 min. after sunrise.
The trigger will be a door sensor
The action will be to turn on a light (actually two light, but I set up a spare sensor and a spare Aeotec Smart Switch so I could test and play).

What I would like to happen is pretty obvious and straight forward. Between the times given, when the door is open (sensor is triggered) turn on the lights, but then turn them back off when the door is closed. Right now, I have two scenes set up, one to turn the lights on when the door is open and one to turn the lights back off. I wanted to consolidate this down to one scene and use Lua to check the sensor for when it is closed and turn the lights back off. What I post below is crude, trust me, I know, but I tried and so I am here seeing if I can get some input on the proper way to do this.

local sensorDevice = 52
local switchDevice = 46
local pStart = 15
local pEnd = 15
local allow = true

local SENSORID = "urn:schemas-micasaverde-com:device:DoorSensor:1"
loca SWITCHID = "urn:schemas-upnp-org:device:BinaryLight:1"

function switchON()
 if SENSORID = 1 && luup.sunrise() = false
   luup.call_action("urn:schemas-upnp-org:device:BinaryLight:1", "SetTarget", {newLoadlevelTarget = "1"}, 46)
 else
   luup.call_action("urn:schemas-upnp-org:device:BinaryLight:1", "SetTarget", {newLoadlevelTarget = "0"}, 46)
 end
end

I thought that perhaps a DO/WHILE loop might work too, but I am not entirely sure. I would appreciate any assistance on this learning journey.

That’s fine, we all have to learn somewhere and some of that learning can come from the expertise available on the forum. However, what you’re battling with here is really three separate things

[ol][li]the syntax of the Lua language itself[/li]
[li]the semantics of Vera’s Luup (Lua UPnP) extensions[/li]
[li]the actual implementation of the logic[/li][/ol]

To be a bit more explicit:

Lua language

[ul][li]the comparison operator is == not =, that’s assignment[/li]
[li]the ‘and’ operator is and not &&, that’s C syntax[/li]
[li]you’re missing a then from the if - then - else statement[/li][/ul]

…strongly suggest you take a look at Programming in Lua

Luup semantics

[ul][li]your SENSORID and SWITCHID strings are device schemas, whereas I think you’ll be needing serviceIds[/li]
[li]your function will never be called if just this code is put into a scene… what triggers have you set on the scene?[/li]
[li]luup.sunrise() is a function which returns the Unix epoch of the next sunrise[/li]
[li]your calls to luup.call_action() need a serviceId, not a device schema, as a first parameter[/li]
[li]your comparison of SENSORID (a string) and 1 (a number) will fail anyway[/li][/ul]

Logic implementation

‘While’ loops will never be a good idea to use when waiting for a condition to become true. The whole idea of scene code is to run quickly and evaluate a set of conditions which determine whether of not the scene actions should run. If your code runs for too long, Luup will terminate it anyway.

[hr]

I’m not going to suggest an implementation solution here, but just point out some things to think about further:

[ul][li]what conditions do you want to trigger this scene? (hint: you’ve specified door open and close as key events)[/li]
[li]what conditions do you want to be true for the light to be switched on/off? (hint: you’ve specified times of day/night)[/li]
[li]what’s the correct syntax for turning a light on/off anyway[/li][/ul]

There’s no doubt that there’s a big learning curve here. Many would say that you should use a third-party plugin for this type of thing, rather than use Lua, but then you are off on another learning curve anyway. Good luck with your Vera coding adventure!

akbooer, thank you for your reply, and the detailed explainations.

Quite frankly, I am glad you are not suggesting any solutions. Yeah, it would make things easier and perhaps give me something in which to look at and study, but in the grander scheme of things if I can use your pointers and detailed info to put all the pieces together, I think it will stick more.

I do agree that a third-party plugin would make things immensely easier, but I like the flexibility of being able to use Lua. I was in the process of setting up home automation on a Raspberry Pi with Home Assistant and it too has a pretty steep learning curve but I was getting there and had some pretty basic automations working. However, I decided for the time I was investing and with all the technical details of just using the Raspberry Pi 3 I was better off starting with a commercially available hub like Vera.

So here I am, starting again. Thank you again for your links and suggestions, I will get busy and see if I can make good use of them.

Well it turns out that you can have the best of both worlds, because there is an emulation of Vera which runs on RPi (or anything else) called openLuup. However, perhaps that’s something for later.

Ask again if you need more review.

I don’t want to discourage you from learning Lua, but if you really get into HA on Vera, the amount of code will get unmanageable IMHO. (MiCasaVerde didn’t exactly build tools into Vera to assist with code management.) PLEG will save you a lot of time and frustration (although it has a learning curve of its own).

I don’t want to discourage you from learning Lua, but if you really get into HA on Vera, the amount of code will get unmanageable IMHO. (MiCasaVerde didn’t exactly build tools into Vera to assist with code management.) PLEG will save you a lot of time and frustration (although it has a learning curve of its own).[/quote]

To be honest, I did check out PLEG after a suggestion in another post, but I got it installed and could not get it to work either. So I thought if it’s going to get this involved then I might as well learn at least the basics of the code.

Okay, I am kind of at my wits end here. So I decided to set up a test switch (an Aeotec Smart Switch 6) and a test sensor (an Aeotec Door/Window Sensor 6) to make things a little simpler to experiment with. I had to find out how to look at the logs so I could get the proper service ids as I did not see where to get those within Vera itself. So I pulled up the logs, triggered each device so I could see the event in the log and snagged the service ids. Then I set up a Scene in which to work with.

Condition: Whenever TestSensor is opened whether is armed or disarmed

I set up no devices so that I could use Lua to turn on the switch. I saved that scene and then went in and added Lua code. To test, I first added:

luup.call_action("urn:upnp-org:serviceId:SwitchPower1","SetTarget",{newTargetValue = "1"}, 46)

That worked perfectly. Of course, there was nothing set up to turn the switch back off, so I went to tackle that next and thought an IF statement would work nicely. I added the following code for the Scene:

if ("urn:micasaverde-com:serviceId:SecuritySensor1", 57) == 0 then
    luup.call_action("urn:upnp-org:serviceId:SwitchPower1","SetTarget",{newTargetValue = "1"}, 46)
else
    luup.call_action("urn:upnp-org:serviceId:SwitchPower1","SetTarget",{newTargetValue = "0"}, 46)
end

Nothing happened and I got an alert at the top stating

ERROR : Error in lua for scenes and events

Vera kind of sucks with respect to telling you what the error was within the interface itself, so I went back to the logs and found the following error:

LuaInterface::LoadCode: [string "if ("urn:micasaverde-com:serviceId:SecuritySensor1", 57) == 0 t..."]:1: ')' expected near ',' <0x74bfb520>

I tried variations on setting up the IF statement to no avail. I found an online resource for being able to test the code instead of having to test it within Vera then pulling the log back up to find the error.

Despite that, and trying all the variations that made sense to me and I keep getting the same error. It seems it does not like that closing parenthesis, but I don’t know what else would go there. I am thinking there is probably a simpler way to do this, but at this stage of knowledge, I do not know what it is. I simply wanted one scene to turn on the light when the sensor was tripped and turn the light back off once the sensor was no longer tripped.

Even if you use PLEG, there will be situations where you will want Lua in your PLEG start up and PLEG actions.

Sent from my SM-G900V using Tapatalk

if ("urn:micasaverde-com:serviceId:SecuritySensor1", 57) == 0 then

Is not valid code …

Maybe you meant something like:

if (luup.variable_get("urn:micasaverde-com:serviceId:SecuritySensor1", "SomeVariableName", 57) == "0")  then

You have a lot more details to keep up with using LUA (Service and Device Ids, Names of Variables and Actions, all of which are case sensitive, LUA syntax, Vera Extensions to LUA, …) as compared to PLEG.

In PLEG you focus on the automation logic (which is also needed in LUA, just implemented slightly differerently)

Richard, thank you.

I have spent the last hour or so trying to implement this very thing in PLEG and I find it even more confusing. The conditional statements make absolutely no sense to me. I tell PLEG I want the device trigger to be when the Door/Window sensor is opened whether armed or not. Yet when I go to the conditional statement I can say cTest is true or anything meaningful (to me at least). I mean, it’s a binary sensor and I have already told it which of the two states I am looking for in setting up the device trigger and I have to set that to some logical operator?? So I am giving up on that for the night. I downloaded the manual on PLEG, but it has not shed any real light on the matter and does not look like it has been updated as the interfaces have changed. Nonetheless, the explanations have not shed any light on how to make a simple binary sensor trigger a simple binary switch. I accept there is a learning curve and am willing to invest the time and work, but when such simple tasks are made to be so difficult, it just takes the wind out of your sails.

Anyway, sorry for the rant. I will try out your code suggestion and see where that leads. Thanks again for taking the time to try and help out.

Input Trigger

tDoorTrigger - When some door is Opened

Condition:

cTest tDoorTrigger

So cTest is true when tDoorTrigger is true…
Add actions to cTest

Okay, let me give that a shot. Thank you for your patience and time.

So this is what I have, and so far, no bueno

I got this to work this morning, finally. Apparently, you have to reload Lua in order for it to work, at least that’s how it started working for me. After that, I set up another condition so that when the sensor is closed, the light turns off. That worked too.

Now, having done all this, I am left with a sense that at least on a basic level that PLEG is no different than setting up a scene. The ultimate goal that took me down all this is still elusive.

Is there no way, within a single logic statement, whether through PLEG or just native Scenes, to control a device? That is to say, is there no method in which I can say Vera, when this sensor is tripped (door open) turn this light on. But, when you see it reset (door closed) turn that light back off? Thus far, it seems that no matter what I use, two separate logic controls are needed. One to monitor when the device is open and another when the device is closed.

Please don’t take my statements as bashing Vera, I am not. I love that Vera runs locally instead of running all my automations through the cloud. So if this is life with Vera and having to set up two logic statements, then so be it. I will take its speed and the fact things run locally and roll with it as best I can.

Those really are two distinct events … that’s why there are typically two scenes or two conditions.

But if you want to use some advanced PLEG syntax you can do it in one …

Input Trigger

tDoorTrigger - When some door is Opened

Condition:

cTest tDoorTrigger

Action for cTest
Turn the Light On

Go into advanced mode … turn on Allow logic expressions in arguments
Then modify the action … and replace the “1” with "{(tDoorTrigger)}

This will set the light to the same as the door trigger. Of course you can have a more complicated expression in the argument.
Do not snap images … the approved way to share info is to share the PDF from a Status report.

Richard, thank you again. I will give that a shot. And thank you again for your continuing education.

I apologize for the use of the images, I was not aware I could have grabbed a pdf. I will keep that in mind if I should need to share such things again.

Oh, and also, I do understand that they are two distinct events. In the process of working on this last night trying to reason out why things were as they were and watching how Lua code added to a scene worked, I realized that it is a one shot proposition. If this happens, do this and also do this, end. In the bigger picture of things it makes sense as monitoring such things probably would take more processing power, memory, etc. and thus make things more costly. To say nothing of the simplicity.

So if I can get PLEG to work then awesome. If I have to make two Scenes for some things then I will just have to suck it up and do it and be done with it.