W każdym Wiser for KNX (LSS100100) oraz spaceLYnk (LSS100200) wbudowana jest funkcja rscalc. Funkcja ta oblicza moment wschodu słońca i jego zachodu podając go w specyficzny sposób – jest to liczba minut liczona od północy do świtu i zmierzchu.

-- obliczanie momentu wschodu / zachodu
-- pobrano z thinkofhome.pl

function rscalc2(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 wschod, zachod = equation - ha, equation + ha

  if wschod > 24 then
    wschod = wschod - 24
  end

  if zachod > 24 then
    zachod = zachod - 24
  end

  return math.floor(wschod * 60), math.ceil(zachod * 60)
end

Z pozoru mało użyteczna informacja, więc jak ją można wykorzystać?

Wyświetlanie godziny wschodu i zachodu słońca na wizualizacji

Aby wyświetlić w wizualizacji KNX godziny wschodu i zachodu wykorzystamy 2 tekstowe obiekty komunikacyjne, np. 10/1/1 i 10/1/2. Utwórzmy je na karcie Obiekty, nadając im typ danych DPT16. Jest to 14-bajtowy typ danej, w zupełności wystarczający do zmieszczenia 5 znaków .

Załóżmy, że punktem odniesienia będzie Warszawa, ale można podać długość i szerokość geograficzną dowolnego innego miasta (lub wsi) w Polsce.

Utwórzmy skrypt harmonogramowy, uruchamiający się codziennie o godz. 02:01:

Okno tworzenia skryptu uruchamianego zgodnie z harmonogramem. Przykładowa konfiguracja skryptu korzystającego z funkcji rscalc.

W treści skryptu wklejamy poniższy kod, dostosowując go do swoich potrzeb:

szerokosc_geograficzna = 52.13
dlugosc_geograficzna = 21.00

wschod, zachod = rscalc(szerokosc_geograficzna, dlugosc_geograficzna)

wschod_godzina = math.floor(wschod / 60)
wschod_minuta = wschod % 60

zachod_godzina = math.floor(zachod / 60)
zachod_minuta = zachod % 60

grp.write('10/1/1','Wschód: ' .. string.format('%02d:%02d', wschod_godzina, wschod_minuta))
grp.write('10/1/2','Zachód: ' .. string.format('%02d:%02d', zachod_godzina, zachod_minuta))