Example Rule for: Facade illumination control - Sunrise Sunset - Azimuth and Sunheight

1,054 views
Skip to first unread message

Helmut Lehmeyer

unread,
May 7, 2012, 2:19:30 PM5/7/12
to ope...@googlegroups.com


Hello everybody,

this is an example rule to protect against too much sun when you have blinds.
If you have any suggestions, ideas what else is missing or your own additions, please get out so.

At this point I would make the proposal, to have an area where code sections like these can be stored.
It would be great if gradual emergence of a large collection of solutions. Can I help at this point?


<code>
/**
 * openHAB, the open Home Automation Bus.
 * Copyright (C) 2010-2012, openHAB.org <ad...@openhab.org>
 *
 * See the contributors.txt file in the distribution for a
 * full listing of individual contributors.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>.
 *
 * Additional permission under GNU GPL version 3 section 7
 *
 * If you modify this Program, or any covered work, by linking or
 * combining it with Eclipse (or a modified version of that library),
 * containing parts covered by the terms of the Eclipse Public License
 * (EPL), the licensors of this Program grant you additional permission
 * to convey the resulting work.
 */

import org.openhab.core.library.types.*
import java.lang.Math
import java.util.Calendar
import java.util.Date
import java.util.TimeZone


/**
 * Sunrise and Sunset - Facade illumination control - Azimuth and Sunheight
 *
 * Code is based in part on equations and formulas from:: http://lexikon.astronomie.info
 *
 * @author Helmut Lehmeyer
 *
 * @version 0.1
 *
 */

// location and building orientation in degrees
var double longitude = 11.00000
var double latitude = 49.00000   
var Number diffToFasade = -26.09 // that means Northfasade looks abit more to west. When azimut is between -26.09 or 333,91 and 153,91 (180 + diffToFasade) east-fasade is illuminated

rule "Sun Calculations"
when
    Time cron "0/30 * * * * ?"
then

    // Main Variables
    var Number sunrise        // Sunrise at given length and timezone in hours
    var int sunriseHours    // Sunrise hours
    var int sunriseMinutes    // Sunrise minutes
    var Number sunset        // Sunset at given length and timezone in hours
    var int sunsetHours        // Sunset hours
    var int sunsetMinutes    // Sunset minutes
    var Number azimut        // Azimuth in degrees: 0°-north, 90°-east, 180°-south, 270°-west
    var Number height        // Height with refractive correction in degrees
   
    // Helper Variables
    var int leapyear
    var int doy
   
    //Grad/Rad
    var Number RAD = (Math::PI / 180)
   
    //Date and Time
    var Calendar current_time = java::util::Calendar::getInstance(TimeZone::getTimeZone("GMT"))
    var local_time  = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))
    var year                          = current_time.get(java::util::Calendar::YEAR)
    var month                        = (current_time.get(java::util::Calendar::MONTH) + 1)
    var Number day                  = current_time.get(java::util::Calendar::DAY_OF_MONTH)
    var Number hour                 = current_time.get(java::util::Calendar::HOUR_OF_DAY)
    var Number minute               = current_time.get(java::util::Calendar::MINUTE)
    var Number second               = current_time.get(java::util::Calendar::SECOND)
    var localgmtdiff                = local_time.get(java::util::Calendar::HOUR_OF_DAY) - hour //Timezone

    //Leapyear
    leapyear = 0
    if((year % 4) == 0 || (year % 400) == 0 && (year % 100) != 0)leapyear = 1

    //Day of Year
    doy = Math::round((Math::floor((275 * month)/9) - (leapyear+1) * Math::floor((month + 9)/12) + day -30).intValue())

    var latRad             = (RAD * latitude).doubleValue()                // Latitude in radians
    var sunMidpointH    = (RAD * (-(50.0/60.0))).doubleValue()            // Height of Sun midpoint at sunrise: radius + refraction
   
    // Solar declination
    // Declination of the sun in radians
    // Formula 2008 by Arnold(at)Barmettler.com, fit to 20 years of average declinations (2008-2017)
    var declination     =  0.409526325277017*Math::sin((0.0169060504029192*(doy - 80.0856919827619)).doubleValue())
   
    // time difference
    // duration of the half arc in hours: The time of sunrise (sunMidpointH) to the highest level in the south
    var timedifference     = 12.0*Math::acos(((Math::sin(sunMidpointH) - Math::sin(latRad) * Math::sin(declination.doubleValue())) / (Math::cos(latRad) * Math::cos(declination.doubleValue()))).doubleValue())/Math::PI

    // Time equation
    // Difference between true and mean solar time
    // formula 2008 by Arnold(at)Barmettler.com, fit to 20 years of average equation of time (2008-2017)
    var timeEquation     = -0.170869921174742*Math::sin((0.0336997028793971 * doy + 0.465419984181394).doubleValue()) - 0.129890681040717*Math::sin((0.0178674832556871*doy - 0.167936777524864).doubleValue())
    //var timeEquationval = 60.0*timeEquation
   
    //////////////////////////////////////////////////////////
    // calculation of sunrise and sunset
    sunrise                = 12.0 - timedifference - timeEquation                 // Sunrise at 0 ° longitude
    sunset              = 12.0 + timedifference - timeEquation                // Sunset at 0 ° longitude
    sunrise                = sunrise - longitude /15.0 + localgmtdiff             // Sunrise at given length and timezone in hours
    sunset              = sunset - longitude /15.0 + localgmtdiff             // Sunset at given length and timezone in hours
    sunriseHours         = sunrise.intValue()                                                        // Sunrise hours
    sunriseMinutes        = (Math::IEEEremainder(sunrise.doubleValue(), sunriseHours)*60).intValue()    // Sunrise minutes
    sunsetHours         = sunset.intValue()                                                            // Sunset hours
    sunsetMinutes         = (Math::IEEEremainder(sunset.doubleValue(), sunsetHours)*60).intValue()    // Sunrise minutes
       
    //////////////////////////////////////////////////////////
    // Now azimuth and elevation at a given Time or Date
    var time             = hour+localgmtdiff+(minute/60.0)+(second/60.0/60.0)    // Time in hours and decimal minutes, for the calculation of azimuth and elevation
    var timeSinceNoon  = time+longitude/15.0-localgmtdiff -12 + timeEquation    // Time in hours since the sun in the south
   
    // Azimuth and altitude of the sun (without refraction)
    var cosdec             = Math::cos(declination.doubleValue())
    var sindec             = Math::sin(declination.doubleValue())
    // 1.0027379: Correction factor for Stardate, 1.0/365.25: Progression of the right ascension of the sun in one day in degrees
    var lha             = timeSinceNoon*(1.0027379 - 1.0/365.25)*15*RAD         // Hour angle in radians since true noon
    var coslha             = Math::cos(lha.doubleValue())
    var sinlha             = Math::sin(lha.doubleValue())
    var coslat             = Math::cos(latRad)
    var sinlat             = Math::sin(latRad)
    var N                 = -cosdec * sinlha
    var D                 = sindec * coslat - cosdec * coslha * sinlat
    var azimutrad         = Math::atan2(N.doubleValue(), D.doubleValue()).doubleValue()
    if (azimutrad<0.0) azimutrad = (azimutrad + 2.0*Math::PI).doubleValue()                                                         // Azimuth. North = 0, East = pi / 2, West = 3/4pi
    var heightrad          = Math::asin( ((sindec * sinlat).doubleValue() + (cosdec * coslha * coslat).doubleValue()).doubleValue() )     // Height of the solar center

    azimut                 = azimutrad/RAD // Azimuth in degrees: 0°-north, 90°-east, 180°-south, 270°-west
    height              = heightrad/RAD // Height with refractive correction in degrees   
   
    //////////////////////////////////////////////////////////
    // Facade illumination control
    // When is the sun shining on the facade and when it is shaded again: east south west north
    // The standard house has four in 90 degree angles arranged facades
    // To calculate when a facade is illuminated, I use the difference between vertical angle to a facade (diffToFasade)

    var eastFasadeIn     = 90 -90 + diffToFasade        //For example: -26.09 or 333,91 - because 0 and 360 is north
    var eastFasadeOut     = 90 +90 + diffToFasade        //153,91
    var southFasadeIn     = 180-90 + diffToFasade        //63,91
    var southFasadeOut     = 180+90 + diffToFasade        //243,91
    var westFasadeIn     = 270-90 + diffToFasade        //153,91   
    var westFasadeOut     = 270+90 + diffToFasade        //333,91
    var northFasadeIn     = 360-90 + diffToFasade        //243,91
    var northFasadeOut     = 360+90 + diffToFasade        //386,09 or 63,91 -  because 360 and 0 is north
   
    //////////////////////////////////////////////////////////
    // What to do with these Data:
   
    // Sunrise and Sunset
    println("sunrise: "+sunriseHours+":"+sunriseMinutes+" = "+sunrise)
    println("sunset: "+sunsetHours+":"+sunsetMinutes+" = "+sunset)
   
    postUpdate( Sunrise_Time,    ""+sunriseHours+":"+sunriseMinutes+" Uhr")
    postUpdate(Sunset_Time,        ""+sunsetHours+":"+sunsetMinutes+" Uhr")
   
    // How it is shown in News: https://groups.google.com/forum/?fromgroups#!topic/openhab/VGbh6LN1KzQ you can switch Sun_DawnTwilight values too:   
    postUpdate(Sun_DawnTwilight_Solar,            if( height < 0  ) {ON} else {OFF})
    postUpdate(Sun_DawnTwilight_Civil,            if( height < 6  ) {ON} else {OFF})
    postUpdate(Sun_DawnTwilight_Nautical,         if( height < 12 ) {ON} else {OFF})
    postUpdate(Sun_DawnTwilight_Astronomical,     if( height < 18 ) {ON} else {OFF})
   
    // Azimuth and Sunheight
    println("azimut = "+azimut)
    println("height = "+height)
   
    postUpdate(Sun_Azimut,  azimut )
    postUpdate(Sun_Height,     height )
   
    // Facades, knowing when a Fasade is illuminated
    postUpdate(Sun_Fasade_Illum_East,        if( azimut > eastFasadeIn  && azimut < eastFasadeOut  && Sun_DawnTwilight_Astronomical.state == OFF) ON else OFF)
    postUpdate(Sun_Fasade_Illum_South,        if( azimut > southFasadeIn && azimut < southFasadeOut && Sun_DawnTwilight_Astronomical.state == OFF) ON else OFF)
    postUpdate(Sun_Fasade_Illum_West,         if( azimut > westFasadeIn  && azimut < westFasadeOut  && Sun_DawnTwilight_Astronomical.state == OFF) ON else OFF)
    postUpdate(Sun_Fasade_Illum_North,         if( azimut > northFasadeIn && azimut < northFasadeOut && Sun_DawnTwilight_Astronomical.state == OFF) ON else OFF)
   
    //////////////////////////////////////////////////////////
    // for a complex circuit scene for blinds, here some possible influential factors:
    //
    // for example the door to terrace is open - blocking
    // to the outside opening doors/windows are open - blocking
    // there is no storm warning - blocking
    // It is between sunrise and sunset
    // current blinds-mode is automatic (after activated manually, there is a hysteresis of 2h before falling back in automode)
    // sun is shining (data from weatherstation needs a hysteresis too)
    // fasade is illuminated by sun
    // it is needed solar heating in a room (temperature threshold whith hysteresis)
    // house is in heating- or cooling-mode (based on weather forecast_conditions)
    // is a scene control active (cinema-mode, private-mode -> all blinds dark or party-mode -> all blinds open)
    //
   
   
end

</code>
sunext.items
sunext.rules

Helmut Lehmeyer

unread,
May 7, 2012, 3:24:34 PM5/7/12
to ope...@googlegroups.com
Sorry, going a bit crazy with the UI from google groups

Have much fun...

Regards,
Helmut

Lars Bretschneider

unread,
May 9, 2012, 1:25:02 AM5/9/12
to openhab
hi helmut,

i think i just will parse a wheater service ... e.g. wetter.com there
you have sunrise and sunset and may be cloudy or not ... also a good
thing is: proplanta there you may store your own weather profile and
may choose the data you want in your forecast

Helmut Lehmeyer

unread,
May 9, 2012, 4:05:00 AM5/9/12
to ope...@googlegroups.com
Hi Lars,

yes
, of course! This script is only one way to get these values.

But there are Situations where it is not wanted, or there is no way to use
services online.

For me, the main argument is, that these values ​​take indirect influential on very important systems.
They have to do their Job reliable over 10 years or more.

These required continuity, online services can't offer, not yet.

And it's fun... :)

Regards,
Helmut

Lars Bretschneider

unread,
May 9, 2012, 5:24:05 AM5/9/12
to openhab
for what pupose do you use that information ? i would like to use it
for heating / roller shutter ... but than i need also the information
is the sun is shining or not ...
i think it would be good to have such calculations in an library, may
be more of them are interesting, so sun or weather related functions
could be collected somewhere in the core

Helmut Lehmeyer

unread,
May 9, 2012, 8:00:01 AM5/9/12
to ope...@googlegroups.com
Hello Lars,

Am Mittwoch, 9. Mai 2012 11:24:05 UTC+2 schrieb Lars Bretschneider:
for what purpose do you use that information ? i would like to use it
for heating / roller shutter ...

Same me!
 
but than i need also the information
is the sun is shining or not ...
Yes, but Online-Services do not real know if Sun is shining at my House.
For Brightness, Windspeed, Temperature and Rainfall I use a Elsner-Suntracer: http://www.eibmarkt.com/dwde/products/N700053.html
For Temperature in the North (absolutely no Sun there) I use the values ​​of the temperature sensor of my heater.

In dependence of the room temperatures, I can decide whether room has to be solar heated or not. With a Hysterrese logic, my blinds are then adjusted accordingly. (up to 24C° heating -> then close the blinds, temp fallen down under 23C° -> open blinds) This works very well since 5 years on a Gira Homeserver *bäh* in my House. Switching to oneHAB at the moment.
programming soon:
If Online-Weather forecast tells me tomorrow will be very Hot and sunny -> heating threshold goes down one degree
If Temp will fall down under 20 C° and it will be cloudy -> heating threshold goes up one degree(or a half)
 
 
i think it would be good to have such calculations in an library, may
be more of them are interesting, so sun or weather related functions
could be collected somewhere in the core

Yes, that will come in future, see: https://groups.google.com/forum/?fromgroups#!topic/openhab/lL7mVlZT8-U
We will get the ability, to dynamically link Libraries. But not in v1.0.0 I think.


Regards,
Helmut

Lars Bretschneider

unread,
May 9, 2012, 3:41:23 PM5/9/12
to openhab
how do you control the heating threshold ? what do you mean with
heating threshold ?

Helmut Lehmeyer

unread,
May 9, 2012, 4:16:15 PM5/9/12
to ope...@googlegroups.com
Hello Lars,


Am Mittwoch, 9. Mai 2012 21:41:23 UTC+2 schrieb Lars Bretschneider:
how do you control the heating threshold ? what do you mean with
heating threshold ?
"(up to 24C° heating -> then close the blinds, temp fallen down under 23C° -> open blinds) "

It's named Hysteresis, it prevents the blinds to run too often.

Without
Hysteresis, the blinds would always run up when the Temperature falls below 24° C (example: 23,95° C) , then sun comes in and ten Minutes later the Temperature is at 24,05° the blinds are going down... next, falls back below 24° C ...and so on all the sunny day... you would get nervous, really ;-)

To prevent this nervous behavior, the shutter moves down at 24° C. but up again later at 23° C. Then nobody gets nervous in your house! :)

In this Case the threshold is the temperature-distance between blinds going down and going up -> 1° C

With a threshold of 2° C:
The shutter moves down at 24° C. but up again later at 22° C.

If Online-Weather forecast tells me tomorrow will be very Hot and sunny -> The Temperature level goes down or cooler. (The shutter moves down at 23° C.)
If Temp will fall down under 20 C° and it will be cloudy -> The Temperature level goes up or warmer. (The shutter moves down at 25° C.)

Hope I have made it more understandable now.

Regards,
Helmut




Lars Bretschneider

unread,
May 10, 2012, 3:09:44 PM5/10/12
to openhab
now its more clearer ... but you still need a weather forecast for a
good working solution, its not possible without ? think about our
discussion about sunset... i think you thought about that, do have a
solution maybe if wheater forecast is not availabe take the values
from last day ... what service do you use for the weather forecast ?

Helmut Lehmeyer

unread,
May 11, 2012, 1:15:47 AM5/11/12
to ope...@googlegroups.com
Hello Lars,


Am Donnerstag, 10. Mai 2012 21:09:44 UTC+2 schrieb Lars Bretschneider:
now its more clearer ... but you still need a weather forecast for a
good working solution, its not possible without ?
It is working very well without weather forecast.
Our House is well insulated and we have large Window areas, so we could have our Heating off in March, by the current solution.
I hope, working with forecast, would just bring a little bit more Effectiveness in the Transition times Fall-Winter and Winter-Spring, it is not a must!

think about our
discussion about sunset... i think you thought about that, do have a
solution maybe if wheater forecast is not availabe take the values
from last day ...
Is an Idea, but I think last Day is represented through Temperatures in House, its cold Inside, then the Weather was cold. Its warm, it was not enough warm Outside.
As I said, integrating forecast is still a TODO, will see.
 
what service do you use for the weather forecast ?
Don't know jet, best is a "Rest" I think...  ;-) Weather APIs: http://www.programmableweb.com/apitag/?q=weather
 
Regards,
Helmut

Lars Bretschneider

unread,
May 23, 2012, 4:24:54 PM5/23/12
to openhab
hi helmut,

do use already the persitence service ? do you log temperatures, yes
you do ....
can you provide me how the temperatures were the last days ? you told
me you have very good insulated house, i would like to compare with
mine ...
is that possible ?

Helmut Lehmeyer

unread,
May 26, 2012, 10:14:10 AM5/26/12
to ope...@googlegroups.com
Hi Lars,

I'm not sure if I've understood everything correctly ...


Am Mittwoch, 23. Mai 2012 22:24:54 UTC+2 schrieb Lars Bretschneider:
hi helmut,

do use already the persitence service ? do you log temperatures, yes
you do ....

Yes, i log the Temperatures.
 
can you provide me how the temperatures were the last days ? you told
me you have very good insulated house, i would like to compare with
mine ...
is that possible ?

The last two weeks, it's always been very sunny, so the blinds are always gone down once the sun comes out. At night, cool air is brought into the house. During the day the temperature rises from 22.7 ° at 8:00 in the morning to a maximum of 24.8 ° so at 17:00.

 

Lars Bretschneider

unread,
May 26, 2012, 1:41:24 PM5/26/12
to openhab
Hi Helmut,

Thanks a lot... so you get also temperature about 25 degresse in your
house.... good to know. i was a little suprised about that for my
house ...

how do you get the fresh ait into the house, open the windows or some
technical system (we have an air installation)

Thanks for the discussion here ....

Helmut Lehmeyer

unread,
May 28, 2012, 8:04:45 AM5/28/12
to ope...@googlegroups.com
Hi Lars,

we cool the house at night by a large basement windows with mosquito nets provided, and a flap in the gable 1.OG.

We need to cool to approximately 10 - 15 days in midsummer.

We have built our house 8 years ago. It has real per 35 kWh / consumption year. We did not want a ventilation system at that time. Today I would decide differently, the technique is to miles further / easier.

Today I would probably organize the supply air with a ventilation system on a 50-meter long underground air hose. On a heater, I would do without today. (except for a small Swedish stove)

Lars Bretschneider

unread,
May 28, 2012, 10:24:06 AM5/28/12
to openhab
thank a lot....

we have built our house last year (KFW55), we have an air installation
with an "Sole Kreislauf". at the moment the "Sole Kreislauf" is not
ready but will be next week.

Brian Crosby

unread,
Apr 30, 2013, 7:59:55 AM4/30/13
to ope...@googlegroups.com
All:

Has anyone gotten this to work with a negative Longitude (i.e. from the US)? It does not seem to calculate the correct values.

Also, how does this take into account UTC Offsets?
Reply all
Reply to author
Forward
0 new messages