Using time in Uservariable in script  [Solved]

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
User avatar
madpatrick
Posts: 761
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Using time in Uservariable in script

Post 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
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
User avatar
madpatrick
Posts: 761
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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
}
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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
}

Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
User avatar
madpatrick
Posts: 761
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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')
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
User avatar
madpatrick
Posts: 761
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
User avatar
madpatrick
Posts: 761
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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
}
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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.
		
            },
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
User avatar
madpatrick
Posts: 761
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Re: Using time in Uservariable in script  [Solved]

Post by madpatrick »

Hi Waaren,

I've tried the first option and this is working.
Thanks for the support !
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
User avatar
madpatrick
Posts: 761
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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.
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post 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.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
User avatar
madpatrick
Posts: 761
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Re: Using time in Uservariable in script

Post by madpatrick »

Thanks. WIll try it the next days
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest