Skip to content

Weather data SmartHome

Reading time 9 minutes

Updated – January 20, 2023

Collecting weather data with SmartHome and visualizing it via AIO Creator on your cell phone or tablet is usually not a necessity, but it is a nice to have.

The online weather service weatherstack.com offers up to 250 queries per month – limited free of charge. If you really want up-to-date weather data, you should choose the standard package. 50,000 queries allow minute intervals.

The packages that are still available differ primarily in the number of requests and a weather forecast of 7 or 14 days.

The following data is included in all packages:

  • Geographic longitude and latitude
  • Location
  • region
  • country
  • Time zone
  • Local time and date
  • UTC offset
  • Current time of data collection
  • Air temperature
  • Weather description
  • wind speed
  • Wind direction numerical/geographical
  • Air pressure
  • Amount of rain
  • Humidity
  • Cloud density
  • Chill temperature
  • UV index
  • view

Registration, regardless of the package, requires the usual details and payment details. An annual subscription, as opposed to monthly, is discounted at 20%.

After successfully completing this procedure, you will receive a so-called API code (Application Programming Interface), which you copy into the query URL. The response is an XML output containing the above data categories and values. The data is extracted using suitable scripts and stored in variables. These can then be used for visualization in the AIO Creator.

A detailed description of all parameters possible in the XML output, as well as the optional query options included in the higher-priced packages, including various code examples, here visible.

Program

The program is quite extensive due to the large amount of data. Therefore, the individual sections are listed sequentially here. All code snippets can ultimately be combined into a single program.

In addition to the data mentioned above, additional data is calculated in the program and made available for visualization:

  • Solar elevation and azimuth
  • Sun protection factor recommendation
Program – W_Data – weather data query

Program header

The header only contains the URL, which must be supplemented by the API key, shown here with xxx, and the location (in plain text or, separated by a comma, as a longitude and latitude, marked with yyy:

var url = "http://api.weatherstack.com/current?access_key=xxx&query=yyy";

Conversion US to DE time format

Since there is no choice of display language in the free and standard tariff, so only the AM / PM time format is available, it is converted to 24-hour here.

Variable to be created:

  • W_LDU of type string

Code:

! AM/PM conversion – save in W_LDU

var posValueStart;
var posValueEnd;
var posStart;
var posEnd; string stderr; string stdout;
system.Exec("wget -q -O - '"#url#"'", &stdout, &stderr);
WriteLine(stdout);
string weather_xml = stdout;

string word = 'observation_time":"';
integer word_length = word.Length();
integer word_position = weather_xml.Find(word);
string data = weather_xml.Substr((word_position + word_length), 5);
integer word_position = data.Find(word);
data = data.Substr(0, (word_position -2));

string word = 'observation_time":"';
integer word_length = word.Length();
integer word_position = weather_xml.Find(word);
string PM = weather_xml.Substr((word_position + word_length +6), 2);
integer word_position = PM.Find(word);
PM = PM.Substr(0, (word_position -2));
WriteLine("AM/PM");WriteLine(PM);

string word = 'observation_time":"';
integer word_length = word.Length();
integer word_position = weather_xml.Find(word);
string HH = weather_xml.Substr((word_position + word_length) + 1, 1);
integer word_position = HH.Find(word);
HH = HH.Substr(0, (word_position -2));
WriteLine("HH");WriteLine(HH);

string word = 'observation_time":"';
integer word_length = word.Length();
integer word_position = weather_xml.Find(word);
string MM = weather_xml.Substr((word_position + word_length) +3, 2);
integer word_position = MM.Find(word);
MM = MM.Substr(0, (word_position -2));
WriteLine("MM");WriteLine(MM);

if (PM == "PM")
{
integer Diff = 12;
WriteLine("Diff");WriteLine(Diff);
var HH_i = HH.ToInteger();
integer H = (HH_i + Diff);
WriteLine("HHi + Diff is = H)");WriteLine(H);
string HHMM = H #":";
WriteLine("H_+ : ");WriteLine(HHMM);
string HM = HHMM # MM;
WriteLine("HH_+12+MM");WriteLine(HM);
dom.GetObject("W_LDU").State(HM);
}
else
{
WriteLine("LDU_data");WriteLine(data);
dom.GetObject("W_LDU").State(data);
}


Country – Country code

The country code is also output in English and converted here into the international code. Additional countries can be added according to this pattern if necessary. The current country is automatically determined by Weatherstack when you select the city.

Variable to be created:

W_country_code of type string

Code:

! Country_code

pos = 0;
posStart = 'country":"';
posEnd = '","region';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string country_code = stdout.Substr(posValueStart, posValueEnd);

if (country_code == "Germany")
{
string country_code = "DE";
}
if (country_code == "Sweden")
{
string country_code = "SE";
}

WriteLine("country_code");WriteLine(country_code);
dom.GetObject("W_country_code").State(country_code);


region

The region, for example in Germany, is called “Lower Saxony” and is also determined automatically by Weatherstack.

Variable to be created:

  • W_region of type string

Code:

! region

pos = 0;
posStart = 'region":"';
posEnd = '","lat';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string region = stdout.Substr(posValueStart, posValueEnd);
WriteLine("region");WriteLine(region);
dom.GetObject("W_region").State(region);


City

When you enter the city, Weatherstack automatically determines the associated longitude and latitude, while the city is determined from the geodata entered.

Variable to be created:

  • W_city_name of type string

Code:

! City_name

pos = 0;
posStart = 'name":"';
posEnd = '","country';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string city_name = stdout.Substr(posValueStart, posValueEnd);
WriteLine("city_name");WriteLine(city_name);
dom.GetObject("W_city_name").State(city_name);


Latitude – geographical. Width

Variable to be created:

  • W_Lat of type string

Code:

! Lat

pos = 0;
posStart = 'query":"Lat';
posEnd = 'and Lon';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string Lat = stdout.Substr(posValueStart, posValueEnd);
WriteLine("Lat");WriteLine(Lat);
dom.GetObject("W_Lat").State(Lat);


Longitude – geogr. length

Variable to be created:

  • W_Lon of type string

Code:

! Lon

pos = 0;
posStart = 'and Lon';
posEnd = '","language';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string Lon = stdout.Substr(posValueStart, posValueEnd);
WriteLine("Lon");WriteLine(Lon);
dom.GetObject("W_Lon").State(Lon);


Visibility – visibility

Variable to be created:

  • W_vis of type string

Code:

! Visibility

pos = 0;
posStart = 'visibility":';
posEnd = ',"is_day';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string vis_data = stdout.Substr(posValueStart, posValueEnd);
WriteLine("vis_data");WriteLine(vis_data);
dom.GetObject("W_vis").State(vis_data);


Air pressure and trend

In addition to the air pressure provided, this script determines the air pressure tendency by saving a measured value as “current” and a previous one as “old”. Both are compared with each other, which results in the tendency.

Variable to be created:

  • W_air pressure_act of type string
  • W_air pressure_old of type string
  • W_Barometric pressure trend of type string

Code:

! Pressure

var W_mb_old;
var W_mb_akt;
pos = 0;
posStart = 'pressure":';
posEnd = ',"precip';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
data = stdout.Substr(posValueStart, posValueEnd);WriteLine(data);
real W_mb_akt = data.ToInteger();WriteLine("W_mb_akt");WriteLine(W_mb_akt);
dom.GetObject("W_Luftdruck_akt").State(W_mb_akt);
W_mb_alt = dom.GetObject("W_Luftdruck_alt").Value();WriteLine(W_mb_alt);

if (W_mb_akt > W_mb_old)
{
dom.GetObject("W_Luftdruck_old").State(W_mb_akt);
dom.GetObject("W_Air pressure trend").State("S");
}

if (W_mb_akt < W_mb_old)
{
dom.GetObject("W_Luftdruck_old").State(W_mb_akt);
dom.GetObject("W_Air pressure trend").State("F");
}

if (W_mb_akt == W_mb_old)
{
dom.GetObject("W_Luftdruck_old").State(W_mb_akt);
dom.GetObject("W_Air pressure trend").State("N");
}


Chill temperature

The wind chill depends on the wind speed and the temperature. In water sports, the effect of evaporative cooling due to spray is also increased (but this is not taken into account here). Chill refers to the perceived temperature, which in a very cold environment can be up to one and a half times negative temperature compared to the actual temperature and can lead to rapid frostbite.

Variable to be created:

  • W_chill of type string

Code:

! Chill

pos = 0;
posStart = 'feelslike":';
posEnd = ',"uv_index';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string app_temp_data = stdout.Substr(posValueStart, posValueEnd);
WriteLine("app_temp_data");WriteLine(app_temp_data);
dom.GetObject("W_chill").State(app_temp_data);


UV and light protection recommendation

The UV exposure determined based on the UV index results in a recommendation for the use of light protection measures if necessary.

Variable to be created:

  • W_UV of type string
  • W_LSF of type string

Code:

! UV

pos = 0;
posStart = 'uv_index":';
posEnd = ',"visibility';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
var uv_data = stdout.Substr(posValueStart, posValueEnd);
dom.GetObject("W_UV").State(uv_data);
data = uv_data.Substr(0, (word_position -2));
real number = data.ToInteger();
WriteLine("UV number");WriteLine(number);

string LSF = "";
if (number <3) {LSF = "unnecessary" ;} elseif ((number >= "3") && (number <= "5")) {LSF = "recommended" ;} elseif ((number >= "6 ") && (number <= "7")) {LSF = "required" ;} elseif ((number >= "8") && (number <= "9")) {LSF = "required" ;} elseif ( number >= "10") {LSF = "MUST" ;}
dom.GetObject("W_LSF").State(LSF);WriteLine("LSF");WriteLine(LSF);


wind speed

Variable to be created:

  • W_WdSpd of type number

Code:

! wind speed

pos = 0;
posStart = 'wind_speed":';
posEnd = ',"wind_degree';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
var wind_spd_daten = stdout.Substr(posValueStart, posValueEnd);
real x = wind_spd_data.ToFloat();
dom.GetObject("W_WdSpd").State(x);


Wind speed conversions

Since there are different preferred wind speed measurements in different regions, countries and applications, here is the conversion from m/s to km/h, knots and Beaufort.

Variable to be created:

  • W_Wind_kmh of type number
  • W_Wind_knh of type number
  • W_Wind_Bft of type number

Code:

real W_Wind_kmh = (wind_spd_daten.ToFloat() * 3.6);WriteLine("W_Wind_kmh");WriteLine(W_Wind_kmh);
dom.GetObject("W_Wind_kmh").State(W_Wind_kmh);


real W_Wind_knh = (W_Wind_kmh / 1.852);WriteLine("W_Wind_knh");WriteLine(W_Wind_knh);
dom.GetObject("W_Wind_knh").State(W_Wind_knh);

if (x < 0.30)
{
dom.GetObject(“W_Wind_Bft”).State(0);
}
if ((0.29 < x) && (x < 1.51))
{
dom.GetObject(“W_Wind_Bft”).State(1);
}
if ((1.59 < x) && ( x < 3.31))
{
dom.GetObject(“W_Wind_Bft”).State(2);
}
if ((3.39 < x) && ( x < 5.41))
{
dom.GetObject(“W_Wind_Bft”).State(3);
}
if ((5.49 < x) && ( x < 7.91))
{
dom.GetObject(“W_Wind_Bft”).State(4);
}
if ((7.99 < x) && (x < 10.71))
{
dom.GetObject(“W_Wind_Bft”).State(5);
}
if ((10.79 < x) && (x < 13.81))
{
dom.GetObject(“W_Wind_Bft”).State(6);
}
if ((12.89 < x) && (x < 17.11))
{
dom.GetObject(“W_Wind_Bft”).State(7);
}
if ((17.19 < x) && (x < 20.71))
{
dom.GetObject(“W_Wind_Bft”).State(8);
}
if ((20.79 < x) && (x < 24.41))
{
dom.GetObject(“W_Wind_Bft”).State(9);
}
if ((24.49 < x) && (x < 28.41))
{
dom.GetObject(“W_Wind_Bft”).State(10);
}
if ((28.49 < x) && (x < 32.61))
{
dom.GetObject(“W_Wind_Bft”).State(11);
}
if (x > 32.6)
{
dom.GetObject(“W_Wind_Bft”).State(12);
}

Wind speed – risk of frostbite

Anyone traveling in very cold zones will receive a warning with this script if there is a risk of frostbite due to wind speed and perceived outside temperature if appropriate protective clothing is not used.

The calculation assumes that with skin exposure of 30 minutes or less, the skin temperature can be expected to drop to -4.8 °C and that frostbite will occur in people at 5%.

Variable to be created:

  • W_Wind_Danger type boolean

Code:

if (((app_temp_data == -27.2) && (8 > W_Wind_kmh <10.1)) || ((app_temp_data == -22.9) && (12 > W_Wind_kmh <15.1)) || ((app_temp_data == -24.2) && ( 18 > W_Wind_kmh <20.1)) || ((app_temp_data == -25.2) && (23 > W_Wind_kmh <25.1)) || ((app_temp_data == -26.0) && (28 > W_Wind_kmh <30.1)) || ((app_temp_data == -26.8) && (32 > W_Wind_kmh <35.1)) || ((app_temp_data == -27.4) && (37 > W_Wind_kmh <40.1)) || ((app_temp_data == -28.0) && (42 > W_Wind_kmh <45.1 )) || ((app_temp_data == -28.6) && (47 > W_Wind_kmh <50.1)) || ((app_temp_data == -22.2) && (53 > W_Wind_kmh <55.1)) || ((app_temp_data == -22.6) && (57 > W_Wind_kmh <60.1)))
{
dom.GetObject("W_Wind_Danger").State(true);
}
else
{
dom.GetObject("W_Wind_Danger").State(false);
}


Wind direction (geographic)

Variable to be created:

  • W_wind_dir of type string

Code:

! Wind direction geographically

pos = 0;
posStart = 'wind_dir":"';
posEnd = '","pressure';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string wind_dir_data = stdout.Substr(posValueStart, posValueEnd);
WriteLine("W_wind_dir");WriteLine(wind_dir_daten);
dom.GetObject("W_wind_dir").State(wind_dir_daten);


Wind direction (numerical)

Variable to be created:

  • W_Wind_rchtg of type string

Code:

! Wind direction numerically

pos = 0;
posStart = 'wind_degree":';
posEnd = ',"wind_dir';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string W_wind_rchtg = stdout.Substr(posValueStart, posValueEnd);
WriteLine("W_wind_rchtg");WriteLine(W_wind_rchtg);
dom.GetObject("W_wind_rchtg").State(W_wind_rchtg);


Cloud cover

The cloud cover is also written in English by Weatherstack, which is why the translation into German is made here.

Variable to be created:

  • W_description of type string

Code:

! Cloud cover description

pos = 0;
posStart = 'weather_descriptions":["';
posEnd = '"],"wind_speed';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string clouds_description = stdout.Substr(posValueStart, posValueEnd);
WriteLine("clouds_description_EN");WriteLine(clouds_description);

if (clouds_description == "Cloudy")
{
string clouds_description_DE = "Cloudy";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Light rain")
{
string clouds_description_DE = "Light rain";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Light rain shower")
{
string clouds_description_DE = "Light rain showers";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Light drizzle")
{
string clouds_description_DE = "Drizzle";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Mis")
{
string clouds_description_DE = "Haze";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Light snow showers")
{
string clouds_description_DE = "Light snow showers";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Sunny")
{
string clouds_description_DE = "Heiter";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Overcast")
{
string clouds_description_DE = "Overcast";
WriteLine("clouds_description");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Partly cloudy")
{
string clouds_description_DE = "Partly cloudy";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Clear")
{
string clouds_description_DE = "Clear";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Fog")
{
string clouds_description_DE = "Fog";
WriteLine("clouds_description_DE");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Patchy rain possible")
{
string clouds_description_DE = "Light rain possible";
WriteLine("clouds_description");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}
if (clouds_description == "Moderate rain")
{
string clouds_description_DE = "Moderate precipitation";
WriteLine("clouds_description");WriteLine(clouds_description_DE);
dom.GetObject("W_description").State(clouds_description_DE);
}


Cloud cover

Variable to be created:

  • W_clouds of type string

Code:

! Cloud cover

pos = 0;
posStart = 'cloudcover":';
posEnd = ',"feelslike';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string clouds_data = stdout.Substr(posValueStart, posValueEnd);
WriteLine("clouds_data");WriteLine(clouds_data);
dom.GetObject("W_clouds").State(clouds_data);


Forecast rain

Variable to be created:

  • W_Precipitation of type string

Code:

! Forecast rain

varx;
pos = 0;
posStart = 'precip":';
posEnd = ',"humidity';
posValueStart = stdout.Find(posStart) + posStart.Length();
posValueEnd = stdout.Find(posEnd)-posValueStart;
string precip = stdout.Substr(posValueStart, posValueEnd);
WriteLine("Precipitation");WriteLine(precip);
dom.GetObject("W_Precipitation").State(precip);


Elevation – Azimuth

The script was written by radio lighthouse written and the Homematic Forum taken from page 10 of the linked thread.

Two system variables must be created:

  • sun_elevation n of type Number
  • sun_azimuth of type Number

Why just 4 minutes? Because the Earth completes its 360° circle around the sun once in 24 hours. 360° / 24h = 15° per hour, corresponding to 60 minutes / 15° = 4 minutes.

The script should be used independently of the above scripts or the associated program, provided the update interval is different from 4 minutes.

Program:

Program – elevation/azimuth determination

Variables to be created:

  • sun_azimuth of type number
  • sun_elevation of type number

Code:

! Get latitude
real phi = system.Latitude();
phi = 0.017453292 * phi;


! Conversion to radians
! Calculate sin_phi and cos_phi with Taylor series
real temp = phi * phi;
real sin_phi =phi * ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667));


! sine approximation
real cos_phi = (temp *temp *0.0416667) + 1.0 - (temp * 0.5);


! cosine approximation
! Calculation of solar time, all times in minutes
integer time_min = system.Date("%M").ToInteger() + 60system.Date("%H").ToInteger(); integer start of day_min = system.SunriseTime("%M").ToInteger() + 60system.SunriseTime("%H").ToInteger();
integer end of day_min = system.SunsetTime("%M").ToInteger() + 60* system.SunsetTime("%H").ToInteger();
integer solar time = time_min + 720 - 0.5 *(start of day_min + end of day_min);
if (solar time > 1440) {solar time = solar time -1440;}
if (solar time < 1) {solar time = 1440 + solar time;} boolean afternoon =false; if (solartime > 720) {solartime =solartime - 720; afternoon = true; }
else {solar time =720 -solar time;}


! Calculation sin_tau and cos_tau
real tau = 0.00436332313 * solar time; ! 15/60 * pi /180 * solar time [0 < tau < pi ] if (tau < 1.570796327) {temp = tau * tau; real sin_tau =tau * ((temp * temp * 0.0083334) +1.0 - (temp *0.1666667)); tau= 1.570796327 - tau; temp = tau * tau; real cos_tau =tau * ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667));} else {real tau1 =3.141592654 - tau; temp = tau1 * tau1; real sin_tau =tau1 * ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667)); tau = tau - 1.570796327; temp = tau * tau; real cos_tau = (tau) (-1.0) ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667));}

! Calculation delta
integer day number = system.Date("%j").ToInteger(); day number = day number +10; if (daynumber > 365) {daynumber = daynumber - 365;}
if (day number < 92) {real day = 0.0172142 *day number;temp = day * day; real delta = (-0.410152) *((temp *temp *0.041666) + 1.0 - (temp * 0.5));} if ((day number >91) && (day number < 184)) {day number = 183 - day number; real day = 0.0172142 *day number; temp = day * day; real delta = (0.410152) *((temp *temp *0.041666) + 1.0 - (temp * 0.5));} if ((day number >183) && (day number < 275)) {day number = day number - 183; real day = 0.0172142 *day number; temp = day * day; real delta = (0.410152) *((temp *temp *0.041666) + 1.0 - (temp * 0.5));} if ((day number >274) && (day number < 366)) {day number = 365 - day number; real day = 0.0172142 *day number; temp = day * day; real delta = (-0.410152) *((temp *temp *0.041666) + 1.0 - (temp * 0.5));}

! calculation sin_delta, cos_delta
temp = delta * delta; real sin_delta =delta * ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667)); !sinus approximation real cos_delta = (temp *temp *0.0416667) + 1.0 - (temp * 0.5);

! cosine approximation
! Calculation of tan_delta with piecewise linearization of the tan
boolean vsign = true; if (delta< 0.0) {vsign = false; delta = (-1.0) *delta;} real tan_delta = 1.0233 * delta; if (delta >=0.2618) {tan_delta = (1.1822*delta) - 0.0416;}
if (vsign == false) {tan_delta = (-1.0) * tan_delta;}


! Calculation sin_elevation and tan_azimuth
real sin_elevation = (sin_phi * sin_delta) +( cos_phi * cos_delta * cos_tau);
temp = sin_elevation * sin_elevation;
real sun_elevation = sin_elevation * (1.0 + (0.1666667 * temp) + (0.075 * temp * temp));
sun_elevation = 57.29577951 * sun_elevation;
real denominator = (sin_phi*cos_tau) - (cos_phi * tan_delta);
if (denominator < 0.0) {boolean plus180 = true;} real tan_azimuth = sin_tau / denominator;


! Calculation of sun_azimuth with piecewise linearization of the arctan
boolean sign = true; if (tan_azimuth < 0.0) { sign = false; tan_azimuth = (-1.0)*tan_azimuth;} real sun_azimuth = 0.97723 * tan_azimuth; if ((tan_azimuth >=0.2679)&&(tan_azimuth < 0.5774)) {sun_azimuth = (0.84588* tan_azimuth) + 0.035189;} if ((tan_azimuth >= 0.5774)&&(tan_azimuth < 1.0)) {sun_azimuth = (0.6195* tan_azimuth) + 0.1659;} if ((tan_azimuth >= 1.0)&&(tan_azimuth < 1.3032)) {sun_azimuth = (0.43173* tan_azimuth) + 0.3537;} if ((tan_azimuth >= 1.3032)&&(tan_azimuth < 1.7321)) {sun_azimuth = ( 0.3052* tan_azimuth) + 0.51856;} if ((tan_azimuth >= 1.7321)&&(tan_azimuth < 2.4142)) {sun_azimuth = (0.1919* tan_azimuth) + 0.7148;} if ((tan_azimuth >= 2.4142)&&(tan_azimuth < 2.9459)) {sun_azimuth = (0.123* tan_azimuth) + 0.88115;} if ((tan_azimuth >= 2.9459)&&(tan_azimuth < 3.7321)) {sun_azimuth = (0.083312* tan_azimuth) + 0.9981;} if ((tan_azimuth >= 3.7321)&&(tan_azimuth < 5.0)) {sun_azimuth = (0.050792* tan_azimuth) + 1.1194;} if ((tan_azimuth >= 5.0)&&(tan_azimuth <7.0)) {sun_azimuth = (0.02775* tan_azimuth) + 1.23465;} if ((tan_azimuth >= 7.0 )&&(tan_azimuth <12.0)) {sun_azimuth = (0.01175117* tan_azimuth) + 1.346641;} if ((tan_azimuth >= 12.0)&&(tan_azimuth <20.0)) {sun_azimuth = (0.004147854* tan_azimuth) + 1.437881;} if (( tan_azimuth >= 20.0)&&(tan_azimuth <50.0)) {sun_azimuth = (0.0009987* tan_azimuth) + 1.5008639;} if (tan_azimuth >= 50.0) {sun_azimuth = (0.000099983* tan_azimuth) + 1.54579974;}
if (sun_azimuth > 1.5707963278) {sun_azimuth = 1.5707963278;}
if (sign == false) {sun_azimuth = (-1.0) * sun_azimuth;}
sun_azimuth = 57.29577951 * sun_azimuth;
if (plus180 == true) {sun_azimuth = sun_azimuth + 180.0;}


! Daily correction and save values to system variables
if (afternoon == false)
{sun_azimuth = 180.0 - sun_azimuth; solar time = 720 - solar time;}
else
{sun_azimuth = sun_azimuth + 180.0;solar time = 720 + solar time;}
sun_azimuth = 0.1 ((sun_azimuth10.0) .ToInteger());
sun_elevation = 0.1 ((sun_elevation10.0) .ToInteger());
dom.GetObject("sonne_elevation").State(sonne_elevation);
dom.GetObject("sun_azimuth").State(sun_azimuth);

Leave a Reply

Your email address will not be published. Required fields are marked *

en_USEnglish