Posts: 92 
	Threads: 31 
	Joined: Feb 2016
	
 Reputation: 
 0
	 
 
	
	
		Hello it's possible to make a Schedule that it depends of a coordinates to turn on a light in sunset and turn off in a sunrise? THX!!
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		Not yet but we have this is our todo list
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 1807 
	Threads: 7 
	Joined: Jul 2015
	
 Reputation: 
 121
	 
 
	
		
		
		13.12.2016, 19:45 
(This post was last modified: 12.01.2017, 12:57 by Erwin van der Zwart.)
		
	 
	
		Hi Josep, 
Make sure this function is inside common functions:
 Code: -- sunrise / sunset calculation 
function rscalc(latitude, longitude, when) 
  local pi = math.pi 
  local doublepi = pi * 2 
  local rads = pi / 180.0 
 
  local TZ = function(when) 
    local ts = os.time(when) 
    local utcdate, localdate = os.date('!*t', ts), os.date('*t', ts) 
    localdate.isdst = false 
 
    local diff = os.time(localdate) - os.time(utcdate) 
    return math.floor(diff / 3600) 
  end 
 
  local range = function(x) 
    local a = x / doublepi 
    local b = doublepi * (a - math.floor(a)) 
    return b < 0 and (doublepi + b) or b 
  end 
 
  when = when or os.date('*t') 
 
  local y2k = { year = 2000, month = 1, day = 1 } 
  local y2kdays = os.time(when) - os.time(y2k) 
  y2kdays = math.ceil(y2kdays / 86400) 
 
  local meanlongitude = range(280.461 * rads + 0.9856474 * rads * y2kdays) 
  local meananomaly = range(357.528 * rads + 0.9856003 * rads * y2kdays) 
  local lambda = range(meanlongitude + 1.915 * rads * math.sin(meananomaly) + rads / 50 * math.sin(2 * meananomaly)) 
 
  local obliq = 23.439 * rads - y2kdays * rads / 2500000 
 
  local alpha = math.atan2(math.cos(obliq) * math.sin(lambda), math.cos(lambda)) 
  local declination = math.asin(math.sin(obliq) * math.sin(lambda)) 
 
  local LL = meanlongitude - alpha 
  if meanlongitude < pi then 
    LL = LL + doublepi 
  end 
 
  local dfo = pi / 216.45 
 
  if latitude < 0 then 
    dfo = -dfo 
  end 
 
  local fo = math.min(math.tan(declination + dfo) * math.tan(latitude * rads), 1) 
  local ha = 12 * math.asin(fo) / pi + 6 
 
  local timezone = TZ(when) 
  local equation = 12 + timezone + 24 * (1 - LL / doublepi) - longitude / 15 
 
  local sunrise, sunset = equation - ha, equation + ha 
 
  if sunrise > 24 then 
    sunrise = sunrise - 24 
  end 
 
  if sunset > 24 then 
    sunset = sunset - 24 
  end 
 
  return math.floor(sunrise * 60), math.ceil(sunset * 60) 
end
 
Then create a resident script with time 60 seconds and add this code:
 Code: -- ***** Astronomic clock module Version 1.0 Created by Erwin van der Zwart ***** -- 
-- ********* Use this script as resident script and run every 60 seconds ******** -- 
-- ****** This script makes use of rscalc function inside common functions ****** -- 
-- ******************************** SET PARAMETERS ****************************** -- 
 
-- Set output address 
adressoutput = '1/1/1' -- 1 bit output for control object 
 
-- Set time shifting addresses 
addressshifttimesunrice = '1/1/2' -- 1 or 2 byte signed integer to be able to adjust/offset calculated sunrise time (set min/max on object) 
addressshifttimesundown = '1/1/3'-- 1 or 2 byte signed integer to be able to adjust/offset calculated down time (set min/max on object) 
 
-- Set feedback adresses 
addresssunrise = '1/1/4' -- 255 byte object for user feedback, shows calculated sunrise time 
addresssundown = '1/1/5' -- 255 byte object for user feedback, shows calculated sundown time 
addresssunriseshifted = '1/1/6' -- 255 byte object for user feedback, shows with offset calculated sunrise time 
addressundownshifted = '1/1/7' -- 255 byte object for user feedback, shows with offset calculatedsundown time 
 
-- Set location coordinates 
latitude = 52.52198 --Zwolle Netherlands, Look at 'http://www.mapcoordinates.net/en' for other locations 
longitude = 6.08213 --Zwolle Netherlands, Look at 'http://www.mapcoordinates.net/en' for other locations 
 
-- ******************************** END PARAMETERS ****************************** -- 
-- ********************* DON'T CHANGE ANYTHING UNDER THIS LINE ****************** -- 
 
-- Function to calculate switching times based and output value 
function astronomic(latitude,longitude,shiftedsunrise,shiftedsundown) 
  local now = os.date('*t') 
  local sunrise, sunset = rscalc(latitude, longitude, now) --Zwolle Netherlands, See http://www.mapcoordinates.net/en for other locations 
  sunriseorg = string.format('%d:%.2d', math.floor(sunrise / 60), sunrise % 60) 
  sunsetorg = string.format('%d:%.2d', math.floor(sunset / 60), sunset % 60) 
  sunrisenew = sunrise + shiftedsunrise 
  sunsetnew = sunset + shiftedsundown 
  sunrisetime = string.format('%d:%.2d', math.floor(sunrisenew / 60), sunrisenew % 60) 
  sunsettime = string.format('%d:%.2d', math.floor(sunsetnew / 60), sunsetnew % 60) 
  local minutes = now.hour * 60 + now.min 
  nowdark = minutes < sunrisenew or sunsetnew < minutes 
  local t = {sunricenormal = sunriseorg, sundownnormal = sunsetorg, sunriceshifted = sunrisetime, sundownshifted = sunsettime, output = nowdark}  
    return (t) 
end 
 
-- Get values for timeshifting 
shiftedsunrise = grp.getvalue(addressshifttimesunrice) or 0 -- Make minutes negative to switch earlyer than normal calculated sunrice and positive to switch later than normal calculated sunrice 
shiftedsundown = grp.getvalue(addressshifttimesundown) or 0 -- Make minutes negative to switch earlyer than normal calculated sundown and positive to switch later than normal calculated sundown 
 
-- Call function to calculate astroinfo 
astroinfo = astronomic(latitude,longitude,shiftedsunrise,shiftedsundown) 
 
-- Set new sunrice time (unshifted) 
currentvalue = grp.getvalue(addresssunrise) 
if astroinfo.sunricenormal ~= currentvalue then 
    grp.update(addresssunrise, astroinfo.sunricenormal) 
end 
 
-- Set new sundown time (unshifted) 
currentvalue = grp.getvalue(addresssundown) 
if astroinfo.sundownnormal ~= currentvalue then 
    grp.update(addresssundown, astroinfo.sundownnormal) 
end 
 
-- Set new sunrice time (shifted) 
currentvalue = grp.getvalue(addresssunriseshifted) 
if astroinfo.sunriceshifted ~= currentvalue then 
    grp.update(addresssunriseshifted, astroinfo.sunriceshifted) 
end 
 
-- Set new sundown time (shifted) 
currentvalue = grp.getvalue(addressundownshifted) 
if astroinfo.sundownshifted ~= currentvalue then 
  grp.update(addressundownshifted, astroinfo.sundownshifted) 
end 
 
-- Set output value to output object 
currentvalue = grp.getvalue(adressoutput) 
if astroinfo.output == true then 
  if currentvalue == false then 
    grp.write(adressoutput, true) 
  end 
else 
  if currentvalue == true then 
    grp.write(adressoutput, false) 
  end 
end
  
If you want to combine it with a scheduler then make a 'and' logic, put the output of this script to input 1, output of the schedular to input 2 and the control object to the output of your 'and' logic.
 
BR,
 
Erwin
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 79 
	Threads: 5 
	Joined: Sep 2016
	
 Reputation: 
 4
	 
 
	
	
		 (13.12.2016, 19:45)Erwin van der Zwart Wrote:  Hi Josep, 
 
 
Make sure this function is inside common functions: 
 
If you want to combine it with a scheduler then make a 'and' logic, put the output of this script to input 1, output of the schedular to input 2 and the control object to the output of your 'and' logic. 
 
BR, 
 
Erwin 
Hi Erwin, tried this out, but it results in this error;
 Resident script:16: attempt to perform arithmetic on local 'verschuifingAM' (a nil value) 
stack traceback: 
 Resident script:16: in function 'astronomic'
	 
	
	
 
Best regards, Jørn.
 
	
		
	 
 
 
	
	
	
		
	Posts: 1807 
	Threads: 7 
	Joined: Jul 2015
	
 Reputation: 
 121
	 
 
	
		
		
		13.12.2016, 21:08 
(This post was last modified: 13.12.2016, 23:40 by Erwin van der Zwart.)
		
	 
	
		Hi, 
 
Did you create the objects mentioned on line 16 and 17? 
 
These are for changing the output times with a offset. 
Create them as 1 or 2 byte signed integer so you can set for 
example -30 or +45 minutes to the original calculated sunrise/down time. 
If you dont want offset set them to 0 but they must excist or you must rewrite script. 
 
BR, 
 
Erwin
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 79 
	Threads: 5 
	Joined: Sep 2016
	
 Reputation: 
 4
	 
 
	
	
		 (13.12.2016, 21:08)Erwin van der Zwart Wrote:  Hi, 
 
Did you create the objects mentioned on line 6 and 7? 
 
These are for changing the output times with a offset. 
Create them as 1 or 2 byte signed integer so you can set for 
example -30 or +45 minutes to the original calculated sunrise/down time. 
If you dont want offset set them to 0 but they must excist or you must rewrite script. 
 
BR, 
 
Erwin 
I did create the objects, but forgot to write initial value to them, that did the trick! 
The time group objects used with datatype "255 byte string". 
Thanks alot Erwin!
 
Br from Jørn.
	  
	
	
 
Best regards, Jørn.
 
	
		
	 
 
 
	
	
	
		
	Posts: 1807 
	Threads: 7 
	Joined: Jul 2015
	
 Reputation: 
 121
	 
 
	
		
		
		13.12.2016, 22:59 
(This post was last modified: 13.12.2016, 23:00 by Erwin van der Zwart.)
		
	 
	
		Hi Jørn, 
 
Thanks for pointing this out, i cleaned the script from dutch texts and i added additional fallback to 0 when timeshifting objects values are not set/init. 
 
I updated the previous post with the new version. 
 
Please use new version to make sure it wont happen again (; 
 
BR, 
 
Erwin
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 1 
	Threads: 0 
	Joined: Dec 2015
	
 Reputation: 
 0
	 
 
	
	
		Hello Erwin! 
I'm trying to use your script in LM4 but there is an error during the saving (Resident script). 
 
Lua syntax error at line 28: '=' expected near 'now'
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 1807 
	Threads: 7 
	Joined: Jul 2015
	
 Reputation: 
 121
	 
 
	
	
		Hi, 
 
You probably use Chrome, there is a copy paste bug in Chrome, please try with another browser to copy the code from this forum. 
 
BR, 
 
Erwin
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		Sunrise/sunset scheduler coming in the next FW release   
    
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 942 
	Threads: 161 
	Joined: Jul 2015
	
 Reputation: 
 33
	 
 
	
	
		Very simple and beautiful tool  
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 19 
	Threads: 6 
	Joined: Mar 2017
	
 Reputation: 
 1
	 
 
	
	
		 (07.03.2017, 11:43)admin Wrote:  Sunrise/sunset scheduler coming in the next FW release   
Yeah wonderful feature, do you have an approx availability date ?
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		April/May, we might provide RC version earlier though.
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 301 
	Threads: 39 
	Joined: Apr 2019
	
 Reputation: 
 4
	 
 
	
	
		 (13.12.2016, 19:45)Erwin van der Zwart Wrote:  Hi Josep, 
 
 
Make sure this function is inside common functions: 
Code: -- sunrise / sunset calculation 
function rscalc(latitude, longitude, when) 
  local pi = math.pi 
  local doublepi = pi * 2 
  local rads = pi / 180.0 
 
  local TZ = function(when) 
    local ts = os.time(when) 
    local utcdate, localdate = os.date('!*t', ts), os.date('*t', ts) 
    localdate.isdst = false 
 
    local diff = os.time(localdate) - os.time(utcdate) 
    return math.floor(diff / 3600) 
  end 
 
  local range = function(x) 
    local a = x / doublepi 
    local b = doublepi * (a - math.floor(a)) 
    return b < 0 and (doublepi + b) or b 
  end 
 
  when = when or os.date('*t') 
 
  local y2k = { year = 2000, month = 1, day = 1 } 
  local y2kdays = os.time(when) - os.time(y2k) 
  y2kdays = math.ceil(y2kdays / 86400) 
 
  local meanlongitude = range(280.461 * rads + 0.9856474 * rads * y2kdays) 
  local meananomaly = range(357.528 * rads + 0.9856003 * rads * y2kdays) 
  local lambda = range(meanlongitude + 1.915 * rads * math.sin(meananomaly) + rads / 50 * math.sin(2 * meananomaly)) 
 
  local obliq = 23.439 * rads - y2kdays * rads / 2500000 
 
  local alpha = math.atan2(math.cos(obliq) * math.sin(lambda), math.cos(lambda)) 
  local declination = math.asin(math.sin(obliq) * math.sin(lambda)) 
 
  local LL = meanlongitude - alpha 
  if meanlongitude < pi then 
    LL = LL + doublepi 
  end 
 
  local dfo = pi / 216.45 
 
  if latitude < 0 then 
    dfo = -dfo 
  end 
 
  local fo = math.min(math.tan(declination + dfo) * math.tan(latitude * rads), 1) 
  local ha = 12 * math.asin(fo) / pi + 6 
 
  local timezone = TZ(when) 
  local equation = 12 + timezone + 24 * (1 - LL / doublepi) - longitude / 15 
 
  local sunrise, sunset = equation - ha, equation + ha 
 
  if sunrise > 24 then 
    sunrise = sunrise - 24 
  end 
 
  if sunset > 24 then 
    sunset = sunset - 24 
  end 
 
  return math.floor(sunrise * 60), math.ceil(sunset * 60) 
end
  
Then create a resident script with time 60 seconds and add this code: 
 
Code: -- ***** Astronomic clock module Version 1.0 Created by Erwin van der Zwart ***** -- 
-- ********* Use this script as resident script and run every 60 seconds ******** -- 
-- ****** This script makes use of rscalc function inside common functions ****** -- 
-- ******************************** SET PARAMETERS ****************************** -- 
 
-- Set output address 
adressoutput = '1/1/1' -- 1 bit output for control object 
 
-- Set time shifting addresses 
addressshifttimesunrice = '1/1/2' -- 1 or 2 byte signed integer to be able to adjust/offset calculated sunrise time (set min/max on object) 
addressshifttimesundown = '1/1/3'-- 1 or 2 byte signed integer to be able to adjust/offset calculated down time (set min/max on object) 
 
-- Set feedback adresses 
addresssunrise = '1/1/4' -- 255 byte object for user feedback, shows calculated sunrise time 
addresssundown = '1/1/5' -- 255 byte object for user feedback, shows calculated sundown time 
addresssunriseshifted = '1/1/6' -- 255 byte object for user feedback, shows with offset calculated sunrise time 
addressundownshifted = '1/1/7' -- 255 byte object for user feedback, shows with offset calculatedsundown time 
 
-- Set location coordinates 
latitude = 52.52198 --Zwolle Netherlands, Look at 'http://www.mapcoordinates.net/en' for other locations 
longitude = 6.08213 --Zwolle Netherlands, Look at 'http://www.mapcoordinates.net/en' for other locations 
 
-- ******************************** END PARAMETERS ****************************** -- 
-- ********************* DON'T CHANGE ANYTHING UNDER THIS LINE ****************** -- 
 
-- Function to calculate switching times based and output value 
function astronomic(latitude,longitude,shiftedsunrise,shiftedsundown) 
  local now = os.date('*t') 
  local sunrise, sunset = rscalc(latitude, longitude, now) --Zwolle Netherlands, See http://www.mapcoordinates.net/en for other locations 
  sunriseorg = string.format('%d:%.2d', math.floor(sunrise / 60), sunrise % 60) 
  sunsetorg = string.format('%d:%.2d', math.floor(sunset / 60), sunset % 60) 
  sunrisenew = sunrise + shiftedsunrise 
  sunsetnew = sunset + shiftedsundown 
  sunrisetime = string.format('%d:%.2d', math.floor(sunrisenew / 60), sunrisenew % 60) 
  sunsettime = string.format('%d:%.2d', math.floor(sunsetnew / 60), sunsetnew % 60) 
  local minutes = now.hour * 60 + now.min 
  nowdark = minutes < sunrisenew or sunsetnew < minutes 
  local t = {sunricenormal = sunriseorg, sundownnormal = sunsetorg, sunriceshifted = sunrisetime, sundownshifted = sunsettime, output = nowdark}  
    return (t) 
end 
 
-- Get values for timeshifting 
shiftedsunrise = grp.getvalue(addressshifttimesunrice) or 0 -- Make minutes negative to switch earlyer than normal calculated sunrice and positive to switch later than normal calculated sunrice 
shiftedsundown = grp.getvalue(addressshifttimesundown) or 0 -- Make minutes negative to switch earlyer than normal calculated sundown and positive to switch later than normal calculated sundown 
 
-- Call function to calculate astroinfo 
astroinfo = astronomic(latitude,longitude,shiftedsunrise,shiftedsundown) 
 
-- Set new sunrice time (unshifted) 
currentvalue = grp.getvalue(addresssunrise) 
if astroinfo.sunricenormal ~= currentvalue then 
    grp.update(addresssunrise, astroinfo.sunricenormal) 
end 
 
-- Set new sundown time (unshifted) 
currentvalue = grp.getvalue(addresssundown) 
if astroinfo.sundownnormal ~= currentvalue then 
    grp.update(addresssundown, astroinfo.sundownnormal) 
end 
 
-- Set new sunrice time (shifted) 
currentvalue = grp.getvalue(addresssunriseshifted) 
if astroinfo.sunriceshifted ~= currentvalue then 
    grp.update(addresssunriseshifted, astroinfo.sunriceshifted) 
end 
 
-- Set new sundown time (shifted) 
currentvalue = grp.getvalue(addressundownshifted) 
if astroinfo.sundownshifted ~= currentvalue then 
  grp.update(addressundownshifted, astroinfo.sundownshifted) 
end 
 
-- Set output value to output object 
currentvalue = grp.getvalue(adressoutput) 
if astroinfo.output == true then 
  if currentvalue == false then 
    grp.write(adressoutput, true) 
  end 
else 
  if currentvalue == true then 
    grp.write(adressoutput, false) 
  end 
end
  
 
If you want to combine it with a scheduler then make a 'and' logic, put the output of this script to input 1, output of the schedular to input 2 and the control object to the output of your 'and' logic. 
 
BR, 
 
Erwin My client has asked to do a gradual ignition. I have 8 exterior ignitions and I need to set a delay of at least 15-30min between them. Any suggestions on how I could solve it?
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		You can use schedulers with a sunrise/sunset offset for this. Why do you want to use a script?
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 301 
	Threads: 39 
	Joined: Apr 2019
	
 Reputation: 
 4
	 
 
	
	
		 (19.07.2021, 09:13)admin Wrote:  You can use schedulers with a sunrise/sunset offset for this. Why do you want to use a script? 
Hello Admin. Yes, I could use that option. I have several questions about it. 
Somehow the exact execution time status of each scheduler could be obtained? 
Would the second script's time setting affect the first? I would be interested in being able to adjust the real sunrise and real dusk without having to change all the programmers. So my client adjusts his nightfall and then the rest is all the same always.
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		Sunsire/sunset time is calculated automatically based on current date and coordinates that are set in Date/time settings. There's rscalc() function in common functions that calculates the same sunrise/sunset time. 
In schedulers you can add a time offset for each event bound to sunrise/sunset. For example, if sunrise is at 7:40 and the time offset it -1:30 then the object value will be changed at 6:10. This time is calculated automatically each day so you just need to create schedulers once.
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 301 
	Threads: 39 
	Joined: Apr 2019
	
 Reputation: 
 4
	 
 
	
	
		 (19.07.2021, 10:09)admin Wrote:  Sunsire/sunset time is calculated automatically based on current date and coordinates that are set in Date/time settings. There's rscalc() function in common functions that calculates the same sunrise/sunset time. 
In schedulers you can add a time offset for each event bound to sunrise/sunset. For example, if sunrise is at 7:40 and the time offset it -1:30 then the object value will be changed at 6:10. This time is calculated automatically each day so you just need to create schedulers once. 
If I understand already, could I somehow get the status of the scheduler run time and the actual sunrise and sunset time?
	  
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 8422 
	Threads: 45 
	Joined: Jun 2015
	
 Reputation: 
 481
	 
 
	
	
		For objects you can enable logging and check the time at which the write happens. 
You can also use this script to log current sunrise and sunset time:
 Code: require('uci') 
 
latitude = uci.get('genohm-scada.core.latitude') 
latitude = tonumber(latitude) or 0 
 
longitude = uci.get('genohm-scada.core.longitude') 
longitude = tonumber(longitude) or 0 
 
sunrise, sunset = rscalc(latitude, longitude) 
 
sunrise_hour = math.floor(sunrise / 60) 
sunrise_minute = sunrise % 60 
 
sunset_hour = math.floor(sunset / 60) 
sunset_minute = sunset % 60 
 
sunrise_text = string.format('%02d:%02d', sunrise_hour, sunrise_minute) 
sunset_text = string.format('%02d:%02d', sunset_hour, sunset_minute) 
 
log('Sunrise: ' .. sunrise_text) 
log('Sunset: ' .. sunset_text)
  
	 
	
	
	
		
	 
 
 
	
	
	
		
	Posts: 20 
	Threads: 4 
	Joined: Nov 2020
	
 Reputation: 
 0
	 
 
	
	
		Hi! Great script, thanks! 
 
I'm having an issue, trying to export the 250 byte strings for sunrise and sundown and calculated sunrise and sundown, but it won't let me export those objects. 
Also I did some adjustment to the script and byte the same times as 3 byte date / time but I still can't export to BACnet. Any reason it won't let me?
	 
	
	
	
		
	 
 
 
	 
 |