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.

Astronomical clock
#3
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
Reply


Messages In This Thread
Astronomical clock - by josep - 13.12.2016, 19:01
RE: Astronomical clock - by admin - 13.12.2016, 19:39
RE: Astronomical clock - by Erwin van der Zwart - 13.12.2016, 19:45
RE: Astronomical clock - by Jørn - 13.12.2016, 20:28
RE: Astronomical clock - by Jørn - 13.12.2016, 21:48
RE: Astronomical clock - by davidchispas - 19.07.2021, 08:34
RE: Astronomical clock - by Domoticatorino - 17.11.2022, 09:50
RE: Astronomical clock - by Mihail - 06.03.2017, 18:06
RE: Astronomical clock - by admin - 07.03.2017, 11:43
RE: Astronomical clock - by tuxtof - 08.03.2017, 21:07
RE: Astronomical clock - by buuuudzik - 07.03.2017, 12:07
RE: Astronomical clock - by admin - 09.03.2017, 07:10
RE: Astronomical clock - by admin - 19.07.2021, 09:13
RE: Astronomical clock - by davidchispas - 19.07.2021, 10:03
RE: Astronomical clock - by admin - 19.07.2021, 10:09
RE: Astronomical clock - by davidchispas - 19.07.2021, 10:25
RE: Astronomical clock - by admin - 19.07.2021, 10:29
RE: Astronomical clock - by asgeirsb - 30.06.2022, 13:24
RE: Astronomical clock - by asgeirsb - 01.07.2022, 06:55
RE: Astronomical clock - by asgeirsb - 01.07.2022, 10:03
RE: Astronomical clock - by admin - 30.06.2022, 14:42
RE: Astronomical clock - by asgeirsb - 04.09.2022, 16:08
RE: Astronomical clock - by admin - 05.09.2022, 06:12

Forum Jump: