This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Is it sunrise or sunset with an offset?
#1
Hi,

If you need to know if the current time is equal to an minute offset ( + or - ) of Sunset or Sunrise  place these scripts in the Common script.   For example, if its 40 minutes before sunrise,  you would create a resident script to run every minute.  


Code:
if( isSunrise(-40, 51.5072, 0.1275) == true) then
  doSomething()
end


example 2,  if its 30 minutes after then you would use

Code:
if( isSunset(30, 51.5072, 0.1275) == true) then
  doSomething()
end


And when you need to know if its Sunset or Sunrise then set the offset parameter to 0.



Code:
function isSunset(offset, latitude, longitude)
  local sunrise, sunset = rscalc(latitude, longitude)
  local now = os.date("*t")
  local yr =now.year
  local mth = now.month
  local dy = now.day
  local hr = math.floor(sunset / 60)
  local minute = sunset % 60
  local tm = os.time{year=yr, month=mth, day=dy, hour=hr, min=minute, sec=0}
  local offsettm
  if(offset >=1) then
    offsettm= tm+(offset*60)
  else
    offsettm= tm-((offset*-1)*60)
  end
  local now = os.time()
  if(offsettm>=(now-30) and offsettm<=(now+30))then
    return true
  else
    return false
  end
end

function isSunrise(offset, latitude, longitude)
  local sunrise, sunset = rscalc(latitude, longitude)
  local now = os.date("*t")
  local yr =now.year
  local mth = now.month
  local dy = now.day
  local hr = math.floor(sunrise / 60)
  local minute = sunrise % 60
  local tm = os.time{year=yr, month=mth, day=dy, hour=hr, min=minute, sec=0}
  local offsettm
  if(offset >=1) then
    offsettm= tm+(offset*60)
  else
    offsettm= tm-((offset*-1)*60)
  end
  local now = os.time()
  if(offsettm>=(now-30) and offsettm<=(now+30))then
    return true
  else
    return false
  end
end



Hope this may help.

Thanks,


Roger
Reply
#2
Thank you Roger for the functions. However, when I place the functions in the common functions script after the rscalc function, I get an error message "Lua syntax error at line 109: '=' expected near 'local'". The error corresponds to line 2 in the function. This is probably because the rscalc function takes three arguments in my version of the software (the recent one):

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

Any thougths on this? I'm a bit of a newbie with Lua.

Best regards,

Pontus
Finland
Reply
#3
Hi Pontus,

The when is an optional parameter,  so you you can then ask for the sunset \ sunrise for next Tuesday.    Your rscalc function is different to mine.  Here is mine which is from the Feb 2015 release of the firmware.

Thanks,

Roger


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
Reply
#4
Thanks Roger, now it works. I have the firmware from february as well, but guess I overwrote the new rscalc with the old one when restoring my config from the backup file...
Reply
#5
Hi Roger,

my version is a little more basic, what do you think :


Code:
-- answer if we have the sun shining
function sun_is_up()
  local longitude = *****
  local latitude = ****
  local now = os.date('*t')
  local now_calc = now.min + now.hour*60
  
  local sunrise, sunset = rscalc(latitude, longitude)
  
  local result = (now_calc>(sunrise)) and (now_calc<(sunset))
  return result
end

longitude and latitude are fixed and there is no offset.

For those who search for the timezone setting, it's in Utilities > Date and time

Matthieu
Reply
#6
Hi Matthieu,

Yep that's cool.

Thanks,

Roger
Reply
#7
Hello guys,
I tried both your scripts, and in both I keep getting an annoying mistake.
In Matts script I keep getting:  Lua syntax error at line 111: '=' expected near 'local', see screenshot 1. 

I also tried Rogers scripts with his version of rscalc function. In this case I get an error even in the rscalc function itself: Lua syntax error at line 46: '=' expected near 'pi', as in screenshot 2.

Can you tell me whats going on?
Thank you

Attached Files Thumbnail(s)
       
Reply
#8
Maybe you browser pasted some non-printable characters? Try doing copy/paste via a text editor so it strips unnecessary stuff. If it still does not work then post your whole userlib source including bits that fail during save.
Reply
#9
I found the mistake!! If I copy the text from this forum into the script it will remove one space "character" on the very beginning of each line where there should be two of them. So basically every line inside a loop or a condition (if, while, ...). Strange thing is that if I delete the remaining one space it works. Even when I type it back again Smile.
Reply


Forum Jump: