I’m doing my best to learn how to code, so I’ve had a go at this one, am I close?
[code]-- Picking the device
local SENSOR = 42 – The device to be checked.
– Add any parameters
local DIFFERENCE = 600 – Seconds
– Picking the services
local SES_SID = “urn:micasaverde-com:serviceId:HaDevice1”
– compare times and whether to act or not
function timecheck()
local TimeStampDay = luup.variable_get( SES_SID, “TimeStampDay”, SENSOR)
local TimeStamp = luup.variable_get( SES_SID, “TimeStamp”, SENSOR)
if TimeStamp - TimeStampDay>= DIFFERENCE) then
Apart from the mismatched parentheses, which you would have figured out for yourself, keep in mind that the values returned by luup.variable_get() are strings*, which you can’t do subtraction on. You have to explicitly convert them to numbers with the Lua builtin function tonumber():
if (tonumber(TimeStamp) - tonumber(TimeStampDay) >= DIFFERENCE) then
Also, you’ve created a function timecheck() but nowhere do you actually call it, so you’ll find this piece of code does nothing until you add
return timecheck()
somewhere at the outermost level.
Strings that contain only digits are still strings. Think of US postal codes or your government ID “number”; if these were really numbers then you could safely leave off leading zeroes without loss of meaning.
[quote=“GroundLoop, post:6, topic:173761”]
if (tripped == "1" and (secsopen >= DELAY)) then
speak ("Attention. The garage door has been open for " .. timeopen / 60 .. " minutes.")
luup.call_delay( "announceProblem", DELAY)
end
end
[/quote]
How does it know ‘timeopen’ if that value is not set or calculated somewhere else in the script?
What do the double full stops (Periods for those in the US) signify?
Why do you also need to put the following in the function itself, as it looks like that’s already the first thing the full script is does? Does it create a loop
luup.call_delay( "announceProblem", DELAY)
* Apologies if I’m not using the correct grammar for programmers.
It’s probably safe to assume that this is only a fragment of code and that the bit that sets timeopen is elsewhere.
What do the double full stops (Periods for those in the US) signify?
String concatenation. “a” … “b” produces “ab”. (Every programming language has a different operator for this. dotdot is Lua’s. You can see the whole set of operators in the Lua manual.)
Why do you also need to put the following in the function itself, [...]? Does it create a loop
This code works well so far, and won’t rattle off nine digits of precision on the number of minutes like the above code.
local SENSOR = 65 -- The door/window sensor device number
local DELAY = 1 * 60 -- Seconds
local SES_SID = "urn:micasaverde-com:serviceId:SecuritySensor1"
luup.call_delay( "announceProblem", DELAY)
-- Send a message if the garage has been open for at least 5 minutes.
function announceProblem()
local lastTrip = tonumber (luup.variable_get( SES_SID, "LastTrip", SENSOR) or os.time())
local secsopen = os.time() - lastTrip
local tripped = luup.variable_get( SES_SID, "Tripped", SENSOR) or "0"
if (tripped == "0") then
-- Timer expired, and door is closed (not tripped). Do nothing. Do not reschedule.
return true; -- Keep executing any commands in this scene.
end
-- This check is needed in case the door opened/closed/opened quickly.
if (secsopen >= DELAY) then
speak ("Attention. The garage door has been open for " .. math.floor(secsopen / 60) .. " minutes.")
end
luup.call_delay( "announceProblem", DELAY) -- Repeat
end
return true; -- Keep executing any commands in this scene.
This could have been just a return statement ... It does not effect the execution of any commands in the scene.
The block of code defines a function and schedules it for later execution. The block of code itself does not return anything. It’s because of that fact that the execution of commands in the scene are executed!. (if the lua code for a scene returns true or nothing … than continue processing)
Ah, good point… thanks.
Makes sense… this function only runs in the timer callback. The scene code returns nothing.
Doh… Now I also see that telltale ‘;’ snuck in there…
Next step is to generalize it into a list of sensors and minute-limits. If any of these five sensors is tripped for than these minutes, then get word out to Vera Alerts.
The following code will be great for me but I cannot make it work (no errors, nothing happens) despiite I changed the Sensor ID to the door sensor I use (313) (I am using UI5 with Vera 3 (created a scene scheduling for each minute and put the code in LUA section).
Thanks for any help
[quote=“GroundLoop, post:10, topic:173761”]This code works well so far, and won’t rattle off nine digits of precision on the number of minutes like the above code.
[code]
local SENSOR = 65 – The door/window sensor device number
local DELAY = 1 * 60 – Seconds
local SES_SID = “urn:micasaverde-com:serviceId:SecuritySensor1”
luup.call_delay( “announceProblem”, DELAY)
– Send a message if the garage has been open for at least 5 minutes.
function announceProblem()
local lastTrip = tonumber (luup.variable_get( SES_SID, “LastTrip”, SENSOR) or os.time())
local secsopen = os.time() - lastTrip
local tripped = luup.variable_get( SES_SID, “Tripped”, SENSOR) or “0”
if (tripped == “0”) then
– Timer expired, and door is closed (not tripped). Do nothing. Do not reschedule.
return true; – Keep executing any commands in this scene.
end
– This check is needed in case the door opened/closed/opened quickly.
if (secsopen >= DELAY) then
speak (“Attention. The garage door has been open for " … math.floor(secsopen / 60) … " minutes.”)
end
luup.call_delay( “announceProblem”, DELAY) – Repeat
end
[/code][/quote]