Run time scripts at different intervals than every minute

In this subforum you can show projects you have made, or you are busy with. Please create your own topic.

Moderator: leecollings

Post Reply
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

Run time scripts at different intervals than every minute

Post by BakSeeDaa »

Time scripts run once every minute.

Maybe You have time scripts that you want to run less frequently... let's say that You want to run it every 5 minutes instead. That can't be done but you can make some clever if-statements in it. I've seen it done before by saving a user variable, a counter every minute. I wanted a different solution that didn't write to the Domoticz database 1440 times every day.

I made a LUA time script named script_time_misc.lua where it put miscellaneous tasks.

Code: Select all

-- script_time_misc.lua
-------------------------------------
commandArray = {}

local m = os.date('%M')
if (m % 5 == 0) then
	print("The 5 minute script interval reached")
	-- Put your script code here that shall run every 5 minutes
end
if (m % 10 == 0) then
	print("The 10 minute script interval reached")
	-- Put your script code here that shall run every 10 minutes
end
if (m % 30 == 0) then
	print("The 30 minute script interval reached")
	-- Put your script code here that shall run every 30 minutes
end
if (m % 60 == 0) then
	print("The 60 minute script interval reached")
	-- Put your script code here that shall run every 60 minutes
end
return commandArray
Edit: There is an enhanced version of this script a few posts below :)
Happy coding! :D
Last edited by BakSeeDaa on Saturday 21 November 2015 10:23, edited 1 time in total.
User avatar
bizziebis
Posts: 182
Joined: Saturday 19 October 2013 14:00
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.8805
Location: The Netherlands
Contact:

Re: Run time scripts at different intervals than every minut

Post by bizziebis »

Works great indeed! :)

I tried to relief my system from heavy (LUA) load every start of the minute by shifting the start time of a script by 10 seconds or more.. But that didn't work for time scripts. It just doesn't check time scripts at times like 21:30:10 so it will never trigger Image

Do you know how to achieve this? So that script A will run at 21:30:00, B on 21:30:10 and C on 21:30:20?

I don't want to use sleep commands as it will only stall LUA scripts.

It works if you use dummy switches at the end of each script like 'commandArray['DummyB']='On AFTER 10' and trigger on devicechanged DummyB, but that's really messy.
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: Run time scripts at different intervals than every minut

Post by BakSeeDaa »

bizziebis wrote:Works great indeed! :)

I tried to relief my system from heavy (LUA) load every start of the minute by shifting the start time of a script by 10 seconds or more.. But that didn't work for time scripts. It just doesn't check time scripts at times like 21:30:10 so it will never trigger Image

Do you know how to achieve this? So that script A will run at 21:30:00, B on 21:30:10 and C on 21:30:20?

I don't want to use sleep commands as it will only stall LUA scripts.

It works if you use dummy switches at the end of each script like 'commandArray['DummyB']='On AFTER 10' and trigger on devicechanged DummyB, but that's really messy.
I keep my time-scripts to a minimum, always using device-scripts whenever possible and I use virtual switches for schedules that occurs every day etc. Heavy LUA load every start of a minute might be because of the device changes triggered by your time script. Every device script must be evaluated every time a single device changes. You've already started to use 'On AFTER 10' and I think it's an excellent idea to use that in Your time scripts for spreading out the load more evenly each minute.

Things to keep in mind:

1) Always check the devicechanged array in the devicescripts before doing anything.

Code: Select all

if (devicechanged["Disarm Z2-Z4"]) then
    if (otherdevices_svalues["Z2 Alarm"] ~= DISARMED) then
		b.OpenURL("http://"..b.localhost.."/json.htm?type=command&param=udevice&idx="..alarmVDevs[2].."&nvalue=0&svalue=" .. b.urlencode(DISARMED))
    end
end
2) Always check the device status before changing it.

Code: Select all

if otherdevices["Radio"] ~= "Off" then commandArray["Radio"] = "Off" end
Without the check above, the radio would go "Off" even if it´s already "Off" and it would trigger all your device scripts to evaluate in a vain.

3) In cases where the exact time between the intervals is not critical, I think that it makes sense to use the following type of command in time-scripts whenever adding something to the commandarray. It will spread out the events more evenly.

Code: Select all

commandArray[#commandArray + 1]={['Radio']="On AFTER "..math.random(10,50) }
(Random delay from 10 to 50 seconds. You may want to alter that to suit your needs)


Using the form commandArray[#commandArray + 1] makes it possible to schedule multiple commands for a single device using nested tables.
mvzut
Posts: 443
Joined: Thursday 12 November 2015 10:55
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: The Netherlands
Contact:

Run time scripts at different intervals than every minute

Post by mvzut »

The above worries me a bit. It should not be up to the user to worry about these things. I would expect that Domoticz has a scheduler built in to make sure commands are send nicely in order without the risk of a too high CPU load or other problems.
Using event-based scripts instead of time based doesn't help me much, I have so many devices in my device list (almost 200) that I have a device trigger every few seconds (mostly temperature and other sensors updating).
Therefore I have chosen the opposite approach: I have one time-based script that updates all my virtual sensors once a minute, instead of a device script that is called every few seconds. I only use device-based scripts for handling switches. I don't do any advanced scheduling as you describe, and have never had any issues so far! My CPU load is very constant at around 3% (Raspberry Pi 2).

But maybe my situation is different, I mostly deal with updating virtual sensors & switches, less with actual switching of lights etc. all the time.
Raspberry Pi 4 - RFXtrx433 - CC2531 Zigbee - Opentherm Gateway - P1 smart meter - Netatmo - Philips Hue - ELV Max! - ESP8266 DIY water meter - 6 x Sonos - 4 x IP cameras - Wall mounted tablet + Dashticz - Google Home integration - MANY switches/sensors
ceedebee
Posts: 44
Joined: Sunday 08 March 2015 20:18
Target OS: -
Domoticz version:
Contact:

Re: Run time scripts at different intervals than every minut

Post by ceedebee »

BakSeeDaa wrote:Time scripts run once every minute.

Maybe You have time scripts that you want to run less frequently... let's say that You want to run it every 5 minutes instead. That can't be done but you can make some clever if-statements in it. I've seen it done before by saving a user variable, a counter every minute. I wanted a different solution that didn't write to the Domoticz database 1440 times every day.

I made a LUA time script named script_time_misc.lua where it put miscellaneous tasks.



Happy coding! :D
Is it posible to call another lua file or function from this script? Or is it posible to include functions in an other file into a lua script?
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: Run time scripts at different intervals than every minut

Post by BakSeeDaa »

ceedebee wrote:Is it posible to call another lua file or function from this script? Or is it posible to include functions in an other file into a lua script?
It certainly is. But if Your reason for that is only to make your time-script more organized You can do something like this instead:

Code: Select all

-- script_time_misc.lua
-------------------------------------
commandArray = {}

local function runEvery5min()
	-- Put your script code here that shall run every 5 minutes
	-- Below is an example using nested tables commandarray and a random delay
	-- commandArray[#commandArray + 1]={['My Device']='Off AFTER '..math.random(10,50) }
end

local function runEvery10min()
	-- Put your script code here that shall run every 10 minutes
end

local function runEvery30min()
	-- Put your script code here that shall run every 30 minutes
end

local function runEvery60min()
	-- Put your script code here that shall run every 60 minutes
end

local m = os.date('%M')
if (m % 5 == 0) then
	runEvery5min()
end
if (m % 10 == 0) then
	runEvery10min()
end
if (m % 30 == 0) then
	runEvery30min()
end
if (m % 60 == 0) then
	runEvery60min()
end

return commandArray
But if you have functions or variables that you want to define in one single place and then call from multiple Lua scripts it makes sense to put them in a module like this:

First create the commonly used script file, the "module". In this example we call it myFunctions.lua
Put it in your Lua scripts folder.

Code: Select all

-----------------------------------------------------------------------------
--	myFunctions.lua: A module with various functions aimed for Domoticz

local mf = {}  -- Public namespace

mf.HELLO = "Hello world" -- Just an example

function mf.blinkLight(light, times)
	times = times or 2
	local cmd1 = 'Off'
	local cmd2 = 'On'
	local pause = 0
	if (otherdevices[light] == 'Off') then
		cmd1 = 'On'
		cmd2 = 'Off'
	end	
	for i = 1, times do
		commandArray[#commandArray + 1]={[light]=cmd1..' AFTER '..pause }
		pause = pause + 3
		commandArray[#commandArray + 1]={[light]=cmd2..' AFTER '..pause }
		pause = pause + 3
	end
end

return mf
Then, in your ordinary device-script or time-script you can use the functions (or variables) like this:

Code: Select all

if (devicechanged["My Button"]) then
	local mf = require("scripts/lua/myFunctions")
	print(mf.HELLO)
	mf.blinkLight("My Living Room Light")
end
ONLY IF YOU ARE NOT ON A RASPBERRY PI
Note: The require statement local mf = require("scripts/lua/myFunctions") will probably only work on Raspberry Pi. If You are running Domoticz on a different distribution you must help Lua to find the path of your Lua scripts folder.
In that case put this line before the line with the require statement

Code: Select all

package.path = "/usr/local/domoticz/scripts/lua/?.lua;"..package.path

You should of course replace /usr/local/domoticz/scripts/lua/ with whatever the actual lua script name folder path is on your installation.
ceedebee
Posts: 44
Joined: Sunday 08 March 2015 20:18
Target OS: -
Domoticz version:
Contact:

Re: Run time scripts at different intervals than every minut

Post by ceedebee »

Thnx for your explanation, it is for both purposes: organization and reuse of code
NietGiftig
Posts: 121
Joined: Sunday 11 October 2015 8:50
Target OS: Raspberry Pi / ODroid
Domoticz version: V3.6224
Location: Holland
Contact:

Re: Run time scripts at different intervals than every minut

Post by NietGiftig »

But if Your reason for that is only to make your time-script more organized You can do something like this instead:
Thanks for this write-up, useful for starters like me
RPI-2 + SSD / ESPEasy Sensors & Switches / Sonoff / RFLink / Action Switches / TP-Link switch / Node-Red / Reacticz
Derik
Posts: 1601
Joined: Friday 18 October 2013 23:33
Target OS: Raspberry Pi / ODroid
Domoticz version: BETA
Location: Arnhem/Nijmegen Nederland
Contact:

Re: Run time scripts at different intervals than every minute

Post by Derik »

@ Bakseedaa

Thanks for this option..
Need this for my moonphase script. that runs to often so i was killing my api...


Do you have perhaps great scripts that you are running with this option?
Xu4: Beta Extreme antenna RFXcomE,WU Fi Ping ip P1 Gen5 PVOutput Harmony HUE SolarmanPv OTG Winddelen Alive ESP Buienradar MySensors WOL Winddelen counting RPi: Beta SMAspot RFlinkTest Domoticz ...Different backups
Toulon7559
Posts: 843
Joined: Sunday 23 February 2014 17:56
Target OS: Raspberry Pi / ODroid
Domoticz version: mixed
Location: Hengelo(Ov)/NL
Contact:

Re: Run time scripts at different intervals than every minute

Post by Toulon7559 »

Not new (already available here to control periodic, low-frequent upload of data to meteo-sites etc.) and perhaps an open door, but the following lines are a similar solution if you organise repeating time in minutes relative to t=0 minutes at the full hour.
- Interval is a local variable which you can set to your needs, defining the interval-time
- Offset is also a local variable, which defines the delay relative to the time defined by Interval
You can adjust for each desired Scriptloop by setting a dedicated set of Interval and Offset.

Code: Select all

-- Current date as date.year, date.month, date.day, date.hour, date.min, date.sec
date = os.date("*t")
-- Scriptloop1
if (date.min % Interval == Offset) then
     <script/instructions>
end
Set1 = RPI-Zero+RFXCom433+S0PCM+Shield for BMP180/DS18B20/RS485+DDS238-1ZNs
Set2 = RPI-3A++RFLinkGTW+ESP8266s+PWS_WS7000
Common = KAKUs+3*PVLogger+PWS_TFA_Nexus
plus series of 'satellites' for dedicated interfacing, monitoring & control.
Derik
Posts: 1601
Joined: Friday 18 October 2013 23:33
Target OS: Raspberry Pi / ODroid
Domoticz version: BETA
Location: Arnhem/Nijmegen Nederland
Contact:

Re: Run time scripts at different intervals than every minute

Post by Derik »

mmm something strange....
Until last night works great:
ScreenShot187.jpg
ScreenShot187.jpg (189.66 KiB) Viewed 16273 times
Only @ this moment....
ScreenShot188.jpg
ScreenShot188.jpg (72.26 KiB) Viewed 16273 times
No script running.
Is there something that i can do?
Xu4: Beta Extreme antenna RFXcomE,WU Fi Ping ip P1 Gen5 PVOutput Harmony HUE SolarmanPv OTG Winddelen Alive ESP Buienradar MySensors WOL Winddelen counting RPi: Beta SMAspot RFlinkTest Domoticz ...Different backups
Pjedr
Posts: 38
Joined: Friday 27 December 2013 3:13
Target OS: Linux
Domoticz version: Beta
Location: Friesland
Contact:

Re: Run time scripts at different intervals than every minute

Post by Pjedr »

Try also using the nohup (no hang up) function and & at the end of your executions to start it in a new process.
Then the lua scripts immidiatly continues, while the executions kan still go on, like pinging every few seconds every minute.
So the time script does basically nothing else then lunching external tools\scripts.

Code: Select all

commandArray={} LogLvl=uservariables['Nivo Lua Script Logging']
if LogLvl >= 3  then print('module_ping_ipdevices') end
local f=io.popen('/var/ramdrive/scripts/RunFromRamDisk.sh') local l=f:read("*a") f:close()
if l=='yes' then sRunDir='/var/ramdrive' else sRunDir='/opt/domoticz-extra' end
sScriptsDir=sRunDir..'/scripts' --print('sScriptsDir='..sScriptsDir)
--/var/ramdrive/Ping.sh benodigd met 3 parameters: <ip-adres> <status On\Off> <idx-nummer>
if LogLvl >= 4  then print('module_ping_lgg4_phone') end
os.execute('nohup '..sScriptsDir..'/Ping.sh 192.168.192.123 '..otherdevices['Ping LG G4 Android Telefoan']..' 932 2>/dev/null &')
..............<I ping 22 devices every few seconds every minute here with options IP, devname, devid for switching via jsonurl>..........
return commandArray
Pjedr
Posts: 38
Joined: Friday 27 December 2013 3:13
Target OS: Linux
Domoticz version: Beta
Location: Friesland
Contact:

Re: Run time scripts at different intervals than every minute

Post by Pjedr »

In case you are curriouse to my Ping.sh I use from the lua script:

Code: Select all

#!/bin/bash
sDomoticzServer="192.168.192.234:8080"; #ping -q -c1 -W 1
ping -c3 -w5 $1 > /dev/null; if  [ $? -eq 0 ]; then
 echo Node with IP: $1 is up.
 if [ "$2" == "On" ]; then echo Node with IP: $1 is nog steeds up.;
 else
  echo Node with IP: $1 is up gegaan.
  echo "Versturen van statuswijziging naar Domoticz server via json"
  echo curl -s -i -m 5 -H "Accept: application/json" "http://$sDomoticzServer/json.htm?type=command&param=switchlight&idx=$3&switchcmd=On"
  strCurl=`nice -n 10 curl -s -i -m 5 -H "Accept: application/json" "http://$sDomoticzServer/json.htm?type=command&param=switchlight&idx=$3&switchcmd=On"`
 fi
else
 echo Node with IP: $1 is down.
 if [ "$2" == "On" ]; then
  echo Node with IP: $1 is down gegaan.
  echo "Versturen van statuswijziging naar Domoticz server via json"
  echo curl -s -i -m 5 -H "Accept: application/json" "http://$sDomoticzServer/json.htm?type=command&param=switchlight&idx=$3&switchcmd=Off"
  strCurl=`nice -n 10 curl -s -i -m 5 -H "Accept: application/json" "http://$sDomoticzServer/json.htm?type=command&param=switchlight&idx=$3&switchcmd=Off"`
 else echo Node with IP: $1 is nog steeds down.;
 fi
fi

Post Reply

Who is online

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