Script starts too many times at specific time?  [Solved]

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

Moderator: leecollings

Post Reply
Marcjeok
Posts: 37
Joined: Wednesday 01 November 2017 19:12
Target OS: -
Domoticz version:
Location: Netherlands
Contact:

Script starts too many times at specific time?

Post by Marcjeok »

Hi,

I've made a new script to control my outdoor lights (previous was in blockly). My first attempt worked (see an example at First code), but I noticed that when the script triggered at 15 minutes after sunset (or at 05:40), the script started more then 1000 times. The lights were going on and the logging of the lights showed ~2,130 entries (7 days of history). My Domotiz crashed a little later. To prevent that much of On commands, I've changed my script to the current script. Now the On and Off commands are only 1 or 2. But Domoticz is still crashing sometimes and I have the feeling that this is because of this script that starts still a lot of times in one minute (or is it coincidence?). Am I doing something wrong or is this a bug?

First code:

Code: Select all

            if domoticz.time.matchesRule(ONEVENING) then
                LOGGING = LOGGING .."\n".."Program On-Evening"
                    OUTDOORHALLWAY.switchOn()
                    OUTDOORSTORAGEROOM.switchOn()
Current script:

Code: Select all

--[[
SCRIPT DESCRIPTION:
This script turns on and off the outdoor lights based on time, sunset and sunrise.

DEVICES USED:
Idx 39 = Berging buitenlamp
Idx 43 = Gang buitenlamp
]]--

--SET USER INPUT VARIABLES:
local IDOSR = 39
local IDOHW = 43
local SECLLOFF = 60         -- turn off the lights after xx seconds at day time
local ONMORNING = 'at 05:40 on mon,tue,wed,thu,fri'
local OFFMORNING = '15 minutes before sunrise on mon,tue,wed,thu,fri'
local ONEVENING = '15 minutes after sunset'
local OFFEVENING = 'at 23:30'
local LOGGINGON = "Yes"     -- turn logging on or off (values: On = "Yes", Off = "No")

return {
    active = true,
    on = {
        devices = {
            IDOSR,
            IDOHW,
        },
        timer = {
            ONMORNING,
            OFFMORNING,
            ONEVENING,
            OFFEVENING,
            'at sunset',
            'at sunrise',
            '2 minutes after sunrise',
        },
    },
    execute = function(domoticz, triggeredItem, info)

        --SET VARIABLES:
        local OUTDOORHALLWAY = domoticz.devices(IDOHW)
        local OUTDOORSTORAGEROOM = domoticz.devices(IDOSR)
        local LOGGING = "\n++++++++++++++++++++\n".."SCRIPT LIGHTS OUTDOOR:".."\n...................."

        -- EXECUTE SCRIPT
        LOGGING = LOGGING .."\n".."Outdoor light StorageRoom: "..OUTDOORSTORAGEROOM.state..", Outdoor light Hallway: "..OUTDOORHALLWAY.state
        if (domoticz.time.isNightTime) then 
            LOGGING = LOGGING .."\n".."Program Nighttime active"
            if domoticz.time.matchesRule(ONEVENING) then
                LOGGING = LOGGING .."\n".."Program On-Evening"
                if (OUTDOORHALLWAY.state == "Off") or (OUTDOORSTORAGEROOM.state == "Off") then
                    LOGGING = LOGGING .."\n".."Turn on the lights "..ONEVENING
                    OUTDOORHALLWAY.switchOn()
                    OUTDOORSTORAGEROOM.switchOn()
                else
                    LOGGING = LOGGING .."\n".."No action needed, lights "..OUTDOORSTORAGEROOM.state
                end
            elseif domoticz.time.matchesRule(OFFEVENING) then
                LOGGING = LOGGING .."\n".."Program Off-Evening"
                if (OUTDOORHALLWAY.state == "On") or (OUTDOORSTORAGEROOM.state == "On") then
                    LOGGING = LOGGING .."\n".."Turn off the lights "..OFFEVENING
                    OUTDOORHALLWAY.switchOff()
                    OUTDOORSTORAGEROOM.switchOff()
                else
                    LOGGING = LOGGING .."\n".."No action needed, lights "..OUTDOORSTORAGEROOM.state
                end
            elseif domoticz.time.matchesRule(ONMORNING) then
                LOGGING = LOGGING .."\n".."Program On-Morning"
                if (OUTDOORHALLWAY.state == "Off") or (OUTDOORSTORAGEROOM.state == "Off") then
                    LOGGING = LOGGING .."\n".."Turn on the lights "..ONMORNING
                    OUTDOORHALLWAY.switchOn()
                    OUTDOORSTORAGEROOM.switchOn()
                else
                    LOGGING = LOGGING .."\n".."No action needed, lights "..OUTDOORSTORAGEROOM.state
                end
            elseif domoticz.time.matchesRule(OFFMORNING) then
                LOGGING = LOGGING .."\n".."Program Off-Morning"
                if (OUTDOORHALLWAY.state == "On") or (OUTDOORSTORAGEROOM.state == "On") then
                    LOGGING = LOGGING .."\n".."Turn off the lights "..OFFMORNING
                    OUTDOORHALLWAY.switchOff()
                    OUTDOORSTORAGEROOM.switchOff()
                else
                    LOGGING = LOGGING .."\n".."No action needed, lights "..OUTDOORSTORAGEROOM.state
                end
            else
                LOGGING = LOGGING .."\n".."No action needed (night time)"
            end
        elseif (domoticz.time.isDayTime) then
            LOGGING = LOGGING .."\n".."Program Daytime active"
            if (OUTDOORHALLWAY.state == "On") or (OUTDOORSTORAGEROOM.state == "On") then
                LOGGING = LOGGING .."\n".."Lights are on, turn off the lights in "..SECLLOFF .." seconds"
                OUTDOORHALLWAY.switchOff().afterSec(SECLLOFF)
                OUTDOORSTORAGEROOM.switchOff().afterSec(SECLLOFF)
            else
                LOGGING = LOGGING .."\n".."No action needed (day time)"
            end
        else
            LOGGING = LOGGING .."\n".."No action needed (no night/day time)"
        end

        LOGGING = LOGGING .."\n++++++++++++++++++++"
        
        --LOGGING:
        if (LOGGINGON == "Yes") then
            domoticz.log(LOGGING)
        end
end
}
BOverdevest
Posts: 23
Joined: Wednesday 28 March 2018 20:56
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.11307
Location: Nederland
Contact:

Re: Script starts too many times at specific time?  [Solved]

Post by BOverdevest »

Hi

you have programmed to start your script at a certain time, but also when the device themselves change.
So when the script runs the first time on the timer setting, it changes the light/device and that triggers a new script to run, which will trigger a new script, which will change the device, which will...

try to remove the bit with
devices = { IDOSR, IDOHW, },
and lets see what happens.

alternatively switch the device silently, so it does not re-trigger the script: device.switchOn().silent()

Below my "Buitenlamp" script, which also deals with the wish to turn on/off the light at a certain time, while keeping the sunrise/sunset in mind as well. The order of the if/then takes care of this.
Also, it turns off the lights with a 15 minute delay. This is to cater for the fact that opening a door or a PIR outside can also trigger the light bulb.
If you are interested, I can share all three scripts....

Code: Select all

    local DeviceName    = "Voordeur Lamp"
    local TijdAan       = "6:30" -- Lamp aan in de ochtend
    local TijdUit       = "21:30" -- Lamp uit in de avond
    local LightningTarget= 45 -- gewenste lichtsterkte van lamp
    local Timer         = 15 -- hoe lang het licht nog aan blijft, bij afschakeling
    local Actie = "Niks"

return {
        on =    { timer = {'at ' .. TijdAan, 'at ' .. TijdUit, "at sunrise", "at sunset" }},
        
        logging = { level = domoticz.LOG_ERROR
--	LOG_INFO, LOG_DEBUG, LOG_ERROR, LOG_FORCE, LOG_MODULE_EXEC_INFO
        ,marker = "Verlichting Voordeur"},
        
        
        execute = function(domoticz, Trigger)
        print(Trigger)
        
    if (domoticz.time.matchesRule('between ' .. TijdUit ..' and 23:59')) then
         Actie = "Licht Uit"
         print("Matchrule =" .. 'between ' .. TijdUit ..' and 23:59')

    elseif (domoticz.time.matchesRule('at sundown') ) then
         Actie = 'Licht Aan'
         print("Matchrule =" .. 'at sundown')
         
    elseif (domoticz.time.matchesRule('between sunrise and 12:00')) then
         Actie = "Licht Uit"
        print("Matchrule =" ..'between sunrise and 12:00')
        
    else -- Tijd gelijk aan TijdAan
         Actie = 'Licht Aan'
         print("Matchrule =" .. TijdAan)
         
    end

    if Actie == 'Licht Aan' then
        domoticz.devices(DeviceName).switchOn()
        --domoticz.devices(DeviceName).switchSelector(LightningTarget)
    else -- "Licht Uit"
        domoticz.devices(DeviceName).switchOff() --.checkFirst().afterMin(Timer)
    end
end
}
HUE, Tradfri, Zwave, RFXCOM, rooted TOON, PS4
Marcjeok
Posts: 37
Joined: Wednesday 01 November 2017 19:12
Target OS: -
Domoticz version:
Location: Netherlands
Contact:

Re: Script starts too many times at specific time?

Post by Marcjeok »

Thanks!

I've added the '.silent()' to my script and this morning it looks really promising (see my logging below). No performance issue or crashing Domoticz. I'll keep monitoring it, but I think this is doing the right job! I wasn't aware of this function (now I can rework all my other scripts as well), so thank you for your explanation. I'm still learning (sometimes the hard way :oops:).

Thank you also for sharing your script. I like to see other well working scripts, because it shows me how it (also) can be done :idea:.

My logging this morning (only 1 time):
2019-10-21 08:02:00.384 Status: dzVents: Info: ------ Start internal script: Lights outdoor:, trigger: 15 minutes before sunrise on mon,tue,wed,thu,fri
2019-10-21 08:02:00.409 Status: dzVents: Info:
2019-10-21 08:02:00.409 ++++++++++++++++++++
2019-10-21 08:02:00.409 SCRIPT LIGHTS OUTDOOR:
2019-10-21 08:02:00.409 ....................
2019-10-21 08:02:00.409 Outdoor light StorageRoom: On, Outdoor light Hallway: On
2019-10-21 08:02:00.409 Program Nighttime active
2019-10-21 08:02:00.409 Program Off-Morning
2019-10-21 08:02:00.409 Turn off the lights 15 minutes before sunrise on mon,tue,wed,thu,fri
2019-10-21 08:02:00.409 ++++++++++++++++++++
2019-10-21 08:02:00.410 Status: dzVents: Info: ------ Finished Lights outdoor

My modified script:

Code: Select all

--[[
SCRIPT DESCRIPTION:
This script turns on and off the outdoor lights based on time, sunset and sunrise.

DEVICES USED:
Idx 39 = Berging buitenlamp
Idx 43 = Gang buitenlamp
]]--

--SET USER INPUT VARIABLES:
local IDOSR = 39
local IDOHW = 43
local SECLLOFF = 60         -- turn off the lights after xx seconds at day time
local ONMORNING = 'at 05:40 on mon,tue,wed,thu,fri'
local OFFMORNING = '15 minutes before sunrise on mon,tue,wed,thu,fri'
local ONEVENING = '15 minutes after sunset'
local OFFEVENING = 'at 23:30'
local LOGGINGON = "Yes"     -- turn logging on or off (values: On = "Yes", Off = "No")

return {
    active = true,
    on = {
        devices = {
            IDOSR,
            IDOHW,
        },
        timer = {
            ONMORNING,
            OFFMORNING,
            ONEVENING,
            OFFEVENING,
            'at sunset',
            'at sunrise',
            '2 minutes after sunrise',
        },
    },
    execute = function(domoticz, triggeredItem, info)

        --SET VARIABLES:
        local OUTDOORHALLWAY = domoticz.devices(IDOHW)
        local OUTDOORSTORAGEROOM = domoticz.devices(IDOSR)
        local LOGGING = "\n++++++++++++++++++++\n".."SCRIPT LIGHTS OUTDOOR:".."\n...................."

        -- EXECUTE SCRIPT
        LOGGING = LOGGING .."\n".."Outdoor light StorageRoom: "..OUTDOORSTORAGEROOM.state..", Outdoor light Hallway: "..OUTDOORHALLWAY.state
        if (domoticz.time.isNightTime) then 
            LOGGING = LOGGING .."\n".."Program Nighttime active"
            if domoticz.time.matchesRule(ONEVENING) then
                LOGGING = LOGGING .."\n".."Program On-Evening"
                if (OUTDOORHALLWAY.state == "Off") or (OUTDOORSTORAGEROOM.state == "Off") then
                    LOGGING = LOGGING .."\n".."Turn on the lights "..ONEVENING
                    OUTDOORHALLWAY.switchOn().silent()
                    OUTDOORSTORAGEROOM.switchOn().silent()
                else
                    LOGGING = LOGGING .."\n".."No action needed, lights "..OUTDOORSTORAGEROOM.state
                end
            elseif domoticz.time.matchesRule(OFFEVENING) then
                LOGGING = LOGGING .."\n".."Program Off-Evening"
                if (OUTDOORHALLWAY.state == "On") or (OUTDOORSTORAGEROOM.state == "On") then
                    LOGGING = LOGGING .."\n".."Turn off the lights "..OFFEVENING
                    OUTDOORHALLWAY.switchOff().silent()
                    OUTDOORSTORAGEROOM.switchOff().silent()
                else
                    LOGGING = LOGGING .."\n".."No action needed, lights "..OUTDOORSTORAGEROOM.state
                end
            elseif domoticz.time.matchesRule(ONMORNING) then
                LOGGING = LOGGING .."\n".."Program On-Morning"
                if (OUTDOORHALLWAY.state == "Off") or (OUTDOORSTORAGEROOM.state == "Off") then
                    LOGGING = LOGGING .."\n".."Turn on the lights "..ONMORNING
                    OUTDOORHALLWAY.switchOn().silent()
                    OUTDOORSTORAGEROOM.switchOn().silent()
                else
                    LOGGING = LOGGING .."\n".."No action needed, lights "..OUTDOORSTORAGEROOM.state
                end
            elseif domoticz.time.matchesRule(OFFMORNING) then
                LOGGING = LOGGING .."\n".."Program Off-Morning"
                if (OUTDOORHALLWAY.state == "On") or (OUTDOORSTORAGEROOM.state == "On") then
                    LOGGING = LOGGING .."\n".."Turn off the lights "..OFFMORNING
                    OUTDOORHALLWAY.switchOff().silent()
                    OUTDOORSTORAGEROOM.switchOff().silent()
                else
                    LOGGING = LOGGING .."\n".."No action needed, lights "..OUTDOORSTORAGEROOM.state
                end
            else
                LOGGING = LOGGING .."\n".."No action needed (night time)"
            end
        elseif (domoticz.time.isDayTime) then
            LOGGING = LOGGING .."\n".."Program Daytime active"
            if (OUTDOORHALLWAY.state == "On") or (OUTDOORSTORAGEROOM.state == "On") then
                LOGGING = LOGGING .."\n".."Lights are on, turn off the lights in "..SECLLOFF .." seconds"
                OUTDOORHALLWAY.switchOff().afterSec(SECLLOFF)
                OUTDOORSTORAGEROOM.switchOff().afterSec(SECLLOFF)
            else
                LOGGING = LOGGING .."\n".."No action needed (day time)"
            end
        else
            LOGGING = LOGGING .."\n".."No action needed (no night/day time)"
        end

        LOGGING = LOGGING .."\n++++++++++++++++++++"
        
        --LOGGING:
        if (LOGGINGON == "Yes") then
            domoticz.log(LOGGING)
        end
end
}
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Script starts too many times at specific time?

Post by waaren »

Marcjeok wrote: Monday 21 October 2019 8:21 Thank you also for sharing your script. I like to see other well working scripts, because it shows me how it (also) can be done :idea:.
Good that your script is working better now !

A small word of advice on the way you combine your log statements in one string and do the actual logging at the end of your script. This will cause that you do not see any logging when the script fails somewhere in the middle.
The standard dzVents logging is immediate and will show you the information when the log statement is reached.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest