Closed GoogleCodeExporter closed 9 years ago
this lib looks promising http://www.jstott.me.uk/jsuntimes/
Original comment by teichsta
on 4 Feb 2012 at 2:45
I use these fields in Misterhouse, would welcome them in Openhab:
$Time_Sunset_Twilight,
$Time_Sunrise_Twilight,
$Dark: true between $Time_Sunset_Twilight and $Time_Sunrise_Twilight, false
otherwise.
These are more relevant than fixed offsets before sunrise and after sunset.
Original comment by vanhobo...@gmail.com
on 9 Apr 2012 at 7:01
This can be achieved by using the following (thanks RaK for providing the base
script)
#################################################
import org.openhab.core.library.types.*
import java.lang.Math
// constants
var Number K = 0.017453
// coordinates (see Google-Maps)
var Number latitude = xx.xxxxxx
var Number longitude = xx.xxxxxx
rule "Calculate Sunheight and Azimut"
when
Time cron "0 0/5 * * * ?"
then
var Number tageszahl
var Number deklination
var Number zeitgleichung
var Number stundenwinkel
var Number x
var Number y
var Number sonnenhoehe
var Number azimut
var month = now.getMonthOfYear
var day = now.getDayOfMonth
var hour = now.getHourOfDay
var minute = now.getMinuteOfHour
// Source: http://www.jgiesen.de/SME/tk/index.htm
tageszahl = (month - 1) * 30 + day + hour / 24
deklination = -23.45 * Math::cos((K * 360 * (tageszahl + 10) / 365).doubleValue)
zeitgleichung = 60.0 * (-0.171 * Math::sin((0.0337*tageszahl+0.465).doubleValue) - 0.1299 * Math::sin((0.01787*tageszahl-0.168).doubleValue))
stundenwinkel = 15.0 * (hour.doubleValue + (minute.doubleValue/60.0) - (15.0-longitude)/15.0 - 12.0 + zeitgleichung/60.0)
x = Math::sin((K * latitude).doubleValue()) * Math::sin((K * deklination).doubleValue()) + Math::cos((K * latitude).doubleValue()) * Math::cos((K * deklination).doubleValue()) * Math::cos((K * stundenwinkel).doubleValue())
y = - (Math::sin((K*latitude).doubleValue) * x - Math::sin((K*deklination).doubleValue)) / (Math::cos((K*latitude).doubleValue) * Math::sin(Math::acos(x.doubleValue)))
sonnenhoehe = Math::asin(x.doubleValue) / K
var break = hour.doubleValue + (minute.doubleValue/60.0) <= 12.0 + (15.0-longitude)/15.0 - zeitgleichung/60.0
if (break) {
azimut = Math::acos(y.doubleValue) / K
} else {
azimut = 360.0 - Math::acos(y.doubleValue) / K
}
logDebug("Sun.rules", "Calculated new SunHeight angle '" + sonnenhoehe + "°'")
logDebug("Sun.rules", "Calculated new Azimut angle '" + azimut + "°'")
// post new values to the bus
Sun_Height.postUpdate(sonnenhoehe)
Sun_Azimut.postUpdate(azimut)
end
#################################################
furthermore you need two new items of type 'Number'
* Sun_Height
* Sun_Azimut
In order to react properly please add other rules with an Item-Changed-Trigger
in Sun_Height or Sun_Azimut which in turn can do all the time tweaks using
joda-time
Does that suite your needs?
Original comment by teichsta
on 26 Jul 2012 at 1:06
may be this will also help:
import org.openhab.core.library.types.*
import org.openhab.model.script.actions.*
import java.lang.Math
import java.util.Date
import java.util.Calendar
import org.joda.time.DateTime
// Change this reflecting your destination
var Number lat = x.xxxx
var Number lng = y.yyyy
var Calendar sunrise = Calendar::getInstance()
var Calendar sunset = Calendar::getInstance()
rule "Sun"
when
Time cron "0 0/30 * * * ?"
then
// http://www.suncalc.net
var J1970 = 2440588
var J2000 = 2451545
var deg2rad = Math::PI / 180
var M0 = 357.5291 * deg2rad
var M1 = 0.98560028 * deg2rad
var J0 = 0.0009
var J1 = 0.0053
var J2 = -0.0069
var C1 = 1.9148 * deg2rad
var C2 = 0.0200 * deg2rad
var C3 = 0.0003 * deg2rad
var P = 102.9372 * deg2rad
var e = 23.45 * deg2rad
var th0 = 280.1600 * deg2rad
var th1 = 360.9856235 * deg2rad
var h0 = -0.83 * deg2rad //sunset angle
var d0 = 0.53 * deg2rad //sun diameter
var h1 = -6 * deg2rad //nautical twilight angle
var h2 = -12 * deg2rad //astronomical twilight angle
var h3 = -18 * deg2rad //darkness angle
var msInDay = 1000 * 60 * 60 * 24
var lw = -lng * deg2rad
var phi = lat * deg2rad
var datum = new Date()
var J = datum.getTime() / msInDay - 0.5 + J1970
var n = Math::round( (J - J2000 - J0 - lw/(2 * Math::PI)).doubleValue)
var Js = (J2000 + J0 + (0 + lw)/(2 * Math::PI) + n)
var M = ( M0 + M1 * (Js - J2000))
var C = C1 * Math::sin(M.doubleValue) + C2 * Math::sin((2 * M).doubleValue) + C3 * Math::sin((3 * M).doubleValue)
var Lsun = M + P + C + Math::PI
var Jtransit = Js + (J1 * Math::sin(M.doubleValue)) + (J2 * Math::sin((2 * Lsun).doubleValue))
var d = Math::asin((Math::sin(Lsun.doubleValue) * Math::sin(e.doubleValue)).doubleValue)
var w0 = Math::acos(((Math::sin(h0.doubleValue) - Math::sin(phi.doubleValue) * Math::sin(d.doubleValue)) / (Math::cos(phi.doubleValue) * Math::cos(d.doubleValue))).doubleValue)
var w1 = Math::acos(((Math::sin((h0+d0).doubleValue) - Math::sin(phi.doubleValue) * Math::sin(d.doubleValue)) / (Math::cos(phi.doubleValue) * Math::cos(d.doubleValue))).doubleValue)
var Jset = J2000 + J0 + (w0 + lw)/(2 * Math::PI) + n + (J1 * Math::sin(M.doubleValue)) + (J2 * Math::sin((2 * Lsun).doubleValue))
var Jsetstart = J2000 + J0 + (w1 + lw)/(2 * Math::PI) + n + (J1 * Math::sin(M.doubleValue)) + (J2 * Math::sin((2 * Lsun).doubleValue))
var Jrise = Jtransit - (Jset - Jtransit)
var Jriseend = Jtransit - (Jsetstart - Jtransit)
var sunrise_ms_start = ( (Jrise + 0.5 - J1970) * msInDay).longValue
var sunrise_ms_end = ( (Jriseend + 0.5 - J1970) * msInDay).longValue
var sunset_ms_start = ((Jsetstart + 0.5 - J1970) * msInDay).longValue
var sunset_ms_end = ((Jset + 0.5 - J1970) * msInDay).longValue
// Items:
// DateTime SunRise "Sonnenaufgang [%1$tA, %1$td.%1$tm.%1$tY %1$tT]" <calendar>
// DateTime SunSet "Sonnenuntergang [%1$tA, %1$td.%1$tm.%1$tY %1$tT]" <calendar>
var Calendar sunrise_start = Calendar::getInstance()
sunrise_start.setTimeInMillis( sunrise_ms_start )
SunRise.postUpdate( new DateTimeType(sunrise_start))
var Calendar sunset_start = Calendar::getInstance()
sunset_start.setTimeInMillis( sunset_ms_start )
SunSet.postUpdate( new DateTimeType(sunset_start))
end
Original comment by kleina.i...@gmail.com
on 5 Oct 2012 at 6:58
Can someon confirm that comment #4 give valid results? I tried it for my self
(northern germany) and got
SunRise 3:44 seems to be wrong
SunSet 15:16 seens to be UTC, so this is correct
while Google gives me
SunRise 8:34 local
SunSet 16:17 local
Original comment by gzock...@gmail.com
on 6 Jan 2013 at 8:50
This code works for me :
import org.openhab.core.library.types.*
import java.lang.Math
// Constants
var Number K = 0.017453
// Change this reflecting your destination
var Number latitude = 50.892
var Number longitude = 4.733
rule "Set Sun and Dawn States"
when
Time cron "0 0/5 * * * ?"
then
var Number tageszahl
var Number deklination
var Number zeitgleichung
var Number stundenwinkel
var Number x
var Number y
var Number sonnenhoehe
var Number azimut
var month = now.getMonthOfYear
var day = now.getDayOfMonth
var hour = now.getHourOfDay
var minute = now.getMinuteOfHour
// Source: http://www.jgiesen.de/SME/tk/index.htm
tageszahl = (month - 1) * 30 + day + hour / 24
deklination = -23.45 * Math::cos((K * 360 * (tageszahl + 10) / 365).doubleValue)
zeitgleichung = 60.0 * (-0.171 * Math::sin((0.0337*tageszahl+0.465).doubleValue) - 0.1299 * Math::sin((0.01787*tageszahl-0.168).doubleValue))
stundenwinkel = 15.0 * (hour.doubleValue + (minute.doubleValue/60.0) - (15.0-longitude)/15.0 - 12.0 + zeitgleichung/60.0)
x = Math::sin((K * latitude).doubleValue()) * Math::sin((K * deklination).doubleValue()) + Math::cos((K * latitude).doubleValue()) * Math::cos((K * deklination).doubleValue()) * Math::cos((K * st
undenwinkel).doubleValue())
y = - (Math::sin((K*latitude).doubleValue) * x - Math::sin((K*deklination).doubleValue)) / (Math::cos((K*latitude).doubleValue) * Math::sin(Math::acos(x.doubleValue)))
sonnenhoehe = Math::asin(x.doubleValue) / K
var break = hour.doubleValue + (minute.doubleValue/60.0) <= 12.0 + (15.0-longitude)/15.0 - zeitgleichung/60.0
if (break) {
azimut = Math::acos(y.doubleValue) / K
} else {
azimut = 360.0 - Math::acos(y.doubleValue) / K
}
logDebug("Sun.rules", "month: " + month)
logDebug("Sun.rules", "day: " + day)
logDebug("Sun.rules", "hour: " + hour)
logDebug("Sun.rules", "minute: " + minute)
logDebug("Sun.rules", "tageszahl: " + tageszahl)
logDebug("Sun.rules", "deklination: " + deklination)
logDebug("Sun.rules", "zeitgleichung: " + zeitgleichung)
logDebug("Sun.rules", "stundenwinkel: " + stundenwinkel)
logDebug("Sun.rules", "x: " + x)
logDebug("Sun.rules", "y: " + y)
logDebug("Sun.rules", "sonnenhoehe: " + sonnenhoehe)
logDebug("Sun.rules", "azimut: " + azimut)
logDebug("Sun.rules", "Calculated new SunHeight angle '" + sonnenhoehe + "°'")
logDebug("Sun.rules", "Calculated new Azimut angle '" + sonnenhoehe + "°'")
// Send all calculations to the event bus
Sun_Height.postUpdate(sonnenhoehe)
Sun_Azimut.postUpdate(azimut)
Daytime.postUpdate( if (sonnenhoehe > 0) OPEN else CLOSED )
if (hour > 3 && hour < 10){
Sun_Dawn_Civil.postUpdate( if (sonnenhoehe > -6 && sonnenhoehe < 0 ) OPEN else CLOSED )
Sun_Dawn_Nautical.postUpdate( if (sonnenhoehe > -12 && sonnenhoehe < -6 ) OPEN else CLOSED )
Sun_Dawn_Astronomical.postUpdate( if (sonnenhoehe > -18 && sonnenhoehe < -12) OPEN else CLOSED )
} if (hour > 15 && hour < 21) {
Sun_Dusk_Civil.postUpdate( if (sonnenhoehe > -6 && sonnenhoehe < 0 ) OPEN else CLOSED )
Sun_Dusk_Nautical.postUpdate( if (sonnenhoehe > -12 && sonnenhoehe < -6 ) OPEN else CLOSED )
Sun_Dusk_Astronomical.postUpdate( if (sonnenhoehe > -18 && sonnenhoehe < -12) OPEN else CLOSED )
}
end
in items
Contact Sun_Dawn_Civil "Zon dawn civil [MAP(sunstates.map):%S]" <sun> (Sun)
Contact Sun_Dawn_Nautical "Zon dawn nautical [MAP(sunstates.map):%S]" <sun>
(Sun)
Contact Sun_Dawn_Astronomical "Zon dawn astronomical [MAP(sunstates.map):%S]"
<sun> (Sun)
Contact Sun_Dusk_Civil "Zon dusk civil [MAP(sunstates.map):%S]" <sun> (Sun)
Contact Sun_Dusk_Nautical "Zon dusk nautical [MAP(sunstates.map):%S]"
<sun> (Sun)
Contact Sun_Dusk_Astronomical "Zon dusk astronomical
[MAP(sunstates.map):%S]" <sun> (Sun)
Contact Daytime "Daytime [MAP(test.map):%s]" <clock> (Sun)
Maybe this helps.
Regards,
Nico
Original comment by nicoat...@gmail.com
on 7 Jan 2013 at 1:18
Shame on me ... i mixed up the variables "lng" and "lat". :(
Original comment by gzock...@gmail.com
on 7 Jan 2013 at 8:51
It seems to me, that #4 gives good results for sunrise / sunset.
It also seems to me that #6 gives me negative sun height values quite too early
in the evenings. My coordinates are roughly 25,66E and 60,39N (if you like to
test).
Have anyone written a rule for calculating the solar beam hitting angle against
flat solar collectors for a given time? The additional parameters would
naturally be panel tilt angle and panel rotation angle.
I would like to forecast their power, by also using weather forecasts for
estimating the cloud cover.
Regards,
Kristian
Original comment by kristian...@gmail.com
on 2 Apr 2013 at 11:28
good question ...
I would propose to ask the question on the google group since there are more
observers than on this issue.
Regards,
Thomas E.-E.
Original comment by teichsta
on 3 Apr 2013 at 8:21
[deleted comment]
For sake of completness, two booleans should be made available as well:
MidnightSun and MidWinterDarkness, or something similiar in name.
Those should indicate when we are outside of the valid region for the equation,
i.e. when the sun doesn't set resp. rise. Then the equation work for everybody
(on this planet).
Original comment by Erland.L...@gmail.com
on 28 Jun 2013 at 6:25
Why not integrate this into the official code with the next release?
Original comment by evazzo...@gmail.com
on 17 Jul 2013 at 10:27
we could add the calculation rule to the demo package, yes
Original comment by teichsta
on 18 Jul 2013 at 8:18
No, I meant in the code giving the possibility to use a short syntax in a rule:
"Time is sunset"
or
"Time is sunrise.plusHours(2)"
Pay attention on this: there is no home automation where no astronomical timer
is provided...
Original comment by enrico.v...@archeometra.it
on 24 Jul 2013 at 10:35
I would agree with that, those functions should be nicely available.
Original comment by belovic...@gmail.com
on 25 Jul 2013 at 5:01
sounds like a good idea, yes.
Original comment by kai.openhab
on 25 Jul 2013 at 7:29
This is something that I needed for my own Apache Karaf project. I'm in the
process of converting it from Apache Karaf to OpenHab but will have difficulty
converting the sunrise/sunset functionality as OpenHab is quite restricted
regarding extension of the trigger mechanism.
This component really should allow an extensible mechanism of allowing custom
triggers to be written and deployed as bundles.
In the meantime I will try to package up my Quartz Astrological Scheduler and
make it available. As OpenHab uses Quartz it would fit straight in if the
createTimer method was changed to switch schedulers instead of statically using
the cron scheduler.
Original comment by m...@subscribe.audumla.net
on 16 Sep 2013 at 4:58
For the Eclipse SmartHome project, I plan to further modularize the rule engine
- triggers as addons definitely sound like a good idea.
Original comment by kai.openhab
on 16 Sep 2013 at 4:35
Original comment by kai.openhab
on 5 Dec 2013 at 10:08
has been migrated to https://github.com/openhab/openhab/issues/633
Original comment by teichsta
on 10 Dec 2013 at 10:04
Original issue reported on code.google.com by
belovic...@gmail.com
on 3 Feb 2012 at 7:41