Page 1 of 1
Using time in Uservariable in script
Posted: Tuesday 02 March 2021 19:53
by madpatrick
Hi
I want to use a time which has been set in my Uservariable within a script.
When i set my UV with a String 23:00 it gives an error in my script
Code: Select all
Error: dzVents: Error: (3.0.2) ...domoticz/scripts/dzVents/generated_scripts/Sleepmode.lua:7: attempt to index a nil value (global 'dz')
I'm set this in my script
Code: Select all
local Sleep = dz.variables('UV_Sleep').value
Code: Select all
if (Switch.state == 'Off') and dz.time.matchesRule('at ' .. Sleep) then
Re: Using time in Uservariable in script
Posted: Tuesday 02 March 2021 20:40
by waaren
madpatrick wrote: Tuesday 02 March 2021 19:53
Code: Select all
Error: dzVents: Error: (3.0.2) ...domoticz/scripts/dzVents/generated_scripts/Sleepmode.lua:7: attempt to index a nil value (global 'dz')
Please always include the complete script that generates the error. It makes the bug finding so much easier...
In this case I can only guess that your
execute = line looks like
execute = function(domoticz, ... )
The first parm of the execute function is the domoticz object with all devices, variables, etc.. and your script tries to refer to a dz which is not declared or passed as parameter to the execute function.
Again hard to advise whether you should change domoticz to dz in the execute line or change dz to domoticz in line 7 without seeing the rest of the script.
Re: Using time in Uservariable in script
Posted: Tuesday 02 March 2021 20:44
by madpatrick
Hi Waaren,
This is the complete script
Code: Select all
local scriptVersion = 'Versie 1.02'
local scriptVar = '-=# Sleepmode #=-'
-- local Night = '21:30' -- after sleep time switch Toon on Sleep temperature
-- local Sleep = '23:00' -- Tablet screen off
-- local Awake = '06:00' -- Tablet screen on
local Night = dz.variables('UV_Night').value
local Sleep = dz.variables('UV_Sleep').time
local Awake = dz.variables('UV_Awake').value
local Switch = 'Party Mode' -- Schakelaar Party Mode (464)
local ToonScene = 20 -- 20 = Sleep mode Toon
local toon = 254 -- 'Toon Scenes'
return {
on =
{
timer = { 'at ' .. Night,
'at ' .. Sleep,
'at ' .. Awake,
--'every minute',
},
devices = { Switch
},
},
logging = { level = domoticz.LOG_FORCE,
marker = scriptVar },
execute = function(dz, item)
local Switch = dz.devices(Switch)
local toon = dz.devices(toon)
local Pass = dz.variables("UV_Pass").value -- Fully Admin password
local Tablet_IP = dz.variables('UV_TabletIP').value -- IP adress van Tablet
if (Switch.state == 'On') then
dz.log('Party Mode: Thermaat blijft nog even aan !',dz.LOG_FORCE)
elseif (Switch.state == 'Off') and dz.time.matchesRule('between ' .. Night .. ' and 30 minutes before' .. Awake) then
if dz.time.matchesRule('at ' .. Sleep) then
dz.log('Bypass Thermostaat op Slaapmodus door Sleep trigger..', dz.LOG_FORCE)
else
toon.switchSelector(ToonScene).silent()
dz.log('Thermostaat op Slaapmodus....', dz.LOG_FORCE)
end
end
if (Switch.state == 'Off') and dz.time.matchesRule('at ' .. Sleep) then
dz.openURL(string.format(Tablet_IP .. '/?cmd=screenOff&password=' .. Pass))
dz.log('Dashticz Tablet in Slaapmodus....', dz.LOG_FORCE)
end
if dz.time.matchesRule('at ' .. Awake) then
dz.openURL(string.format(Tablet_IP .. '/?cmd=screenOn&password=' .. Pass))
dz.openURL(string.format(Tablet_IP .. '/?cmd=loadStartUrl&password=' .. Pass)).afterSec(30)
dz.log('Dashticz Tablet ontwaakt in Dagmodus....', dz.LOG_FORCE)
end
end
}
Re: Using time in Uservariable in script
Posted: Tuesday 02 March 2021 21:20
by waaren
madpatrick wrote: Tuesday 02 March 2021 20:44
This is the complete script
Your script tried to access the domoticz object but at that line it is not known yet in the script. You will have to pass it to the area where you intend to use it. If you need it in the timer section then do something like below.
Code: Select all
local scriptVersion = 'Versie 1.02'
local scriptVar = '-=# Sleepmode #=-'
local Switch = Party Mode' -- Schakelaar Party Mode (464)
local ToonScene = 20 -- 20 = Sleep mode Toon
local toon = 254 -- 'Toon Scenes'
return
{
on =
{
timer =
{
function(domoticz)
return
domoticz.time.matchesRule('at ' .. domoticz.variables('UV_Night').value) or
domoticz.time.matchesRule('at ' .. domoticz.variables('UV_Sleep').value) or
domoticz.time.matchesRule('at ' .. domoticz.variables('UV_Awake').value)
end,
},
devices =
{
Switch,
},
},
logging =
{
level = domoticz.LOG_FORCE,
marker = scriptVar,
},
execute = function(dz, item)
local Switch = dz.devices(Switch)
local toon = dz.devices(toon)
local Pass = dz.variables("UV_Pass").value -- Fully Admin password
local Tablet_IP = dz.variables('UV_TabletIP').value -- IP adress van Tablet
local Sleep = dz.variables('UV_Sleep').value
local Night = dz.variables('UV_Night').value
local Awake = dz.variables('UV_Awake').value
if (Switch.state == 'On') then
dz.log('Party Mode: Thermaat blijft nog even aan !',dz.LOG_FORCE)
elseif (Switch.state == 'Off') and dz.time.matchesRule('between ' .. Night .. ' and 30 minutes before' .. Awake) then
if dz.time.matchesRule('at ' .. Sleep) then
dz.log('Bypass Thermostaat op Slaapmodus door Sleep trigger..', dz.LOG_FORCE)
else
toon.switchSelector(ToonScene).silent()
dz.log('Thermostaat op Slaapmodus....', dz.LOG_FORCE)
end
end
if (Switch.state == 'Off') and dz.time.matchesRule('at ' .. Sleep) then
dz.openURL(string.format(Tablet_IP .. '/?cmd=screenOff&password=' .. Pass))
dz.log('Dashticz Tablet in Slaapmodus....', dz.LOG_FORCE)
end
if dz.time.matchesRule('at ' .. Awake) then
dz.openURL(string.format(Tablet_IP .. '/?cmd=screenOn&password=' .. Pass))
dz.openURL(string.format(Tablet_IP .. '/?cmd=loadStartUrl&password=' .. Pass)).afterSec(30)
dz.log('Dashticz Tablet ontwaakt in Dagmodus....', dz.LOG_FORCE)
end
end
}
Re: Using time in Uservariable in script
Posted: Tuesday 02 March 2021 21:31
by madpatrick
Ok. That makes sense.
Unfortunately an other error is poping up.
Code: Select all
2021-03-02 21:30:00.416 Error: dzVents: Error: (3.0.2) -=# Sleepmode #=-: An error occurred when calling event handler Sleepmode #2
2021-03-02 21:30:00.416 Error: dzVents: Error: (3.0.2) -=# Sleepmode #=-: ...oticz/scripts/dzVents/generated_scripts/Sleepmode #2.lua:45: attempt to concatenate a table value (local 'Awake')
Re: Using time in Uservariable in script
Posted: Tuesday 02 March 2021 21:38
by madpatrick
Found it.
Needed to add .value
Code: Select all
local Sleep = dz.variables('UV_Sleep').value
local Night = dz.variables('UV_Night').value
local Awake = dz.variables('UV_Awake').value
Re: Using time in Uservariable in script
Posted: Thursday 04 March 2021 19:28
by madpatrick
Tried the function with another script, but this will start the script constantly and not on the set times
Log file
Code: Select all
2021-03-04 19:22:00.515 Status: dzVents: Info: -=# PIR Woonkamer #=-: ------ Start internal script: PIR Woonkamer #2:, trigger: "function"
This was original working timer
Code: Select all
timer =
{
'at ' .. minutesBeforeSunset .. ' minutes before sunset', -- This will be concatenated to xx minutes before sunset
--'every minute', -- only for testing
'at ' .. Sleep,
},
Changed it into
Code: Select all
timer =
{
function(domoticz)
return
domoticz.time.matchesRule('at ' .. domoticz.variables('UV_Sleep').value) or
'at ' .. minutesBeforeSunset .. ' minutes before sunset' -- This will be concatenated to xx minutes before sunset
end,
},
Complete script
Code: Select all
local scriptVersion = 'Versie 1.0 '
local scriptVar = '-=# PIR Woonkamer #=-'
local PIR = 451 -- "PIR Sensor" change to name of your PIR
local lux = 454 -- "PIR Lux" change to name of your lux device
local light = 'Woonkamer' -- change to name of your light/group
--local Sleep = '23:00' -- after sleep time switch off lamps unless PIR movement and LUX value < xx
local retrigger = 'Retrigger using customEvent'
local minutesBeforeSunset = 60 -- 60 min before sunset
local Switch = 'Party Mode' -- Schakelaar Party Mode (464)
return
{
on =
{
timer =
{
function(domoticz)
return
domoticz.time.matchesRule('at ' .. domoticz.variables('UV_Sleep').value) or
'at ' .. minutesBeforeSunset .. ' minutes before sunset' -- This will be concatenated to xx minutes before sunset
end,
},
customEvents =
{
retrigger,
}
},
logging = { level = domoticz.LOG_INFO,
marker = scriptVar },
execute = function(dz)
local PIR = dz.devices(PIR)
local light = dz.groups(light) -- groups instead of device
local lux = dz.devices(lux).lux
local Switch = dz.devices(Switch)
local Sleep = dz.variables('UV_Sleep').value
dz.log(' LUX = ' .. lux,dz.LOG_FORCE)
dz.log(PIR.name .. ' was last updated ' .. PIR.lastUpdate.secondsAgo .. ' seconds ago',dz.LOG_FORCE)
dz.log(light.name .. ' state is ' .. light.state ,dz.LOG_FORCE)
-- the text between quotes and the variables minutesBeforeSunset (60) and Sleep (23:00) will be concatenated to
-- between xx minutes before sunset and 23:00
if dz.time.matchesRule('between ' .. minutesBeforeSunset .. ' minutes before sunset and ' .. Sleep) and not(dz.time.matchesRule('at ' .. Sleep)) then
if lux < 10 then
light.switchOn().checkFirst()
dz.log(light.name .. ' switched On or already On',dz.LOG_FORCE)
else
dz.emitEvent(retrigger).afterSec(300) -- try again in 5 min.
dz.log('Script will start again in 5 minutes',dz.LOG_FORCE)
end
else
if PIR.lastUpdate.secondsAgo > 1800 and (Switch.state == 'Off') then
light.switchOff().checkFirst()
dz.log(light.name .. ' switching Off or already Off and: ' .. Switch.name .. ' switched Off' ,dz.LOG_FORCE)
else
dz.emitEvent(retrigger).afterSec(300) -- try again in 5 min.
dz.log('Script will start again in 5 minutes',dz.LOG_FORCE)
end
end
end
}
Re: Using time in Uservariable in script
Posted: Thursday 04 March 2021 20:48
by waaren
madpatrick wrote: Thursday 04 March 2021 19:28
Tried the function with another script, but this will start the script constantly and not on the set times
You left out the function domoticz.time.matchesRule for the second condition, Can you try again after changing to
Code: Select all
return
{
on =
{
timer =
{
function(domoticz)
return
domoticz.time.matchesRule('at ' .. domoticz.variables('UV_Sleep').value) or
domoticz.time.matchesRule('at ' .. minutesBeforeSunset .. ' minutes before sunset') -- must use matchesRule when making your own function
end,
},
or to
Code: Select all
return
{
on =
{
timer =
{
function(domoticz)
return
domoticz.time.matchesRule('at ' .. domoticz.variables('UV_Sleep').value)
end,
'at ' .. minutesBeforeSunset .. ' minutes before sunset', -- dzVents will internally use the matchesRule function now.
},
Re: Using time in Uservariable in script [Solved]
Posted: Friday 05 March 2021 18:12
by madpatrick
Hi Waaren,
I've tried the first option and this is working.
Thanks for the support !
Re: Using time in Uservariable in script
Posted: Wednesday 05 May 2021 14:37
by madpatrick
Hi Waaren,
I have a another question with the script, but i can't find a proper solution with my limited programming knowledge.
Yesterday the following happened.
Due to bad weather and rain it was pretty dark around 18:30, but the script only gets triggered 60 minutes before sunset (21:14) and therefore i turned on the lights manually.
Becasue the lights were on, the lux value will never reach the trigger setting (<10 lux) and the script will retrigger it self every 5 min after 20:14 (60 minutebefore sunset).
No problem, but i turned of the lights manually around 22:30, which is before UV_sleep (23:00) and the script was still running and turned on the lights again with the retrigger event.
How can I bypass this ? If I turn on the lights manually before the script is started and switch on after sunset.
This is my latest version of the script
Code: Select all
local scriptVersion = 'Versie 1.01'
local scriptVar = '-=# PIR Woonkamer #=-'
local PIR = 451 -- "PIR Sensor" change to name of your PIR
local lux = 454 -- "PIR Lux" change to name of your lux device
local light = 'Woonkamer' -- change to name of your light/group
local retrigger = 'Retrigger using customEvent'
local Switch = 'Party Mode' -- Schakelaar Party Mode (464)
local minutesBeforeSunset = 60 -- 60 min before sunset
return
{
on =
{
timer =
{
function(domoticz)
return
domoticz.time.matchesRule('at ' .. domoticz.variables('UV_Sleep').value) or
domoticz.time.matchesRule('at ' .. minutesBeforeSunset .. ' minutes before sunset') -- must use matchesRule when making your own function
end,
},
customEvents =
{
retrigger,
}
},
logging = { level = domoticz.LOG_INFO,
marker = scriptVar },
execute = function(dz)
local PIR = dz.devices(PIR)
local light = dz.groups(light) -- groups instead of device
local lux = dz.devices(lux).lux
local Switch = dz.devices(Switch)
local Sleep = dz.variables('UV_Sleep').value
dz.log(' LUX = ' .. lux,dz.LOG_FORCE)
dz.log(PIR.name .. ' was last updated ' .. PIR.lastUpdate.secondsAgo .. ' seconds ago',dz.LOG_FORCE)
dz.log(light.name .. ' state is ' .. light.state ,dz.LOG_FORCE)
-- the text between quotes and the variables minutesBeforeSunset (60) and Sleep (23:00) will be concatenated to
-- between xx minutes before sunset and 23:00
if dz.time.matchesRule('between ' .. minutesBeforeSunset .. ' minutes before sunset and ' .. Sleep) and not(dz.time.matchesRule('at ' .. Sleep)) then
if lux < 10 then
light.switchOn().checkFirst()
dz.log(light.name .. ' switched On or already On',dz.LOG_FORCE)
else
dz.emitEvent(retrigger).afterSec(300) -- try again in 5 min.
dz.log('Script will start again in 5 minutes',dz.LOG_FORCE)
end
else
if PIR.lastUpdate.secondsAgo > 1800 and (Switch.state == 'Off') then
light.switchOff().checkFirst()
dz.log(light.name .. ' switching Off or already Off and: ' .. Switch.name .. ' switched Off' ,dz.LOG_FORCE)
else
dz.emitEvent(retrigger).afterSec(300) -- try again in 5 min.
dz.log('Script will start again in 5 minutes',dz.LOG_FORCE)
end
end
end
}
I hope you can give me some advise.
Re: Using time in Uservariable in script
Posted: Wednesday 05 May 2021 16:31
by waaren
madpatrick wrote: Wednesday 05 May 2021 14:37
I have a another question with the script, but i can't find a proper solution.
it depends a bit on how you switch manually. If you switch the group light, you could try after changing line 51/52 from
Code: Select all
else
dz.emitEvent(retrigger).afterSec(300) -- try again in 5 min.
to
Code: Select all
elseif light.state ~= 'On' then
dz.emitEvent(retrigger).afterSec(300) -- try again in 5 min.
If you use another domoticz device to switch manually then you have to evaluate the state of that other device.
Re: Using time in Uservariable in script
Posted: Wednesday 05 May 2021 17:24
by madpatrick
Thanks. WIll try it the next days