{"id":138,"date":"2013-12-01T22:00:40","date_gmt":"2013-12-01T20:00:40","guid":{"rendered":"http:\/\/www.anginf.de\/?p=138"},"modified":"2016-04-01T10:08:03","modified_gmt":"2016-04-01T08:08:03","slug":"sonnenaufgang-und-sonnenuntergang-in-bash-skript-berechnen","status":"publish","type":"post","link":"https:\/\/www.anginf.de\/?p=138","title":{"rendered":"Sonnenaufgang und Sonnenuntergang in Bash-Skript berechnen"},"content":{"rendered":"<p>Um ein <a title=\"Fritz!DECT 200\" href=\"http:\/\/www.avm.de\/de\/Produkte\/Hausautomation\/FRITZDECT_200\/index.php\" target=\"_blank\">Fritz!DECT 200<\/a>, welche eine Au\u00dfenbeleuchtung steuern soll, so anzusprechen, wie ich es mir vorgestellt habe, brauche ich eine automatisierte Steuerung. Die von AVM mitgelieferten Einstellm\u00f6glichkeiten auf der Fritz!Box sind schon recht umfangreich, bilden aber leider genau meinen Anwendungsfall nicht ab.<\/p>\n<ul>\n<li>Schalte morgens ab 07:00 Uhr bis Sonnenaufgang die Au\u00dfenbeleuchtung ein. Falls der Sonnenaufgang vor 07:00 Uhr war, schalte die Beleuchtung nicht ein.<\/li>\n<li>Schalte abends ab Sonnenuntergang bis 23:00 Uhr die Au\u00dfenbeleuchtung ein. Falls der Sonnenuntergang nach 23:00 Uhr war (ich wei\u00df, ist hier nicht m\u00f6glich, aber die Schaltzeit k\u00f6nnte ja auch fr\u00fcher sein), schalte die Beleuchtung nicht ein.<\/li>\n<li>&#8222;G\u00e4ste-Schaltung&#8220;: Wenn nach 23:00 Uhr (und nach Sonnenuntergang) der Schalter manuell bet\u00e4tigt wurde, dann spende f\u00fcr 10-20 Minuten Licht, schalte danach das Licht wieder aus. (Pr\u00fcfe alle 10 Minuten den Stand, wenn er zweimal hintereinander &#8222;eingeschaltet&#8220; ist, obwohl laut Zeitplan eigentlich &#8222;ausgeschaltet&#8220; sein sollte, schalte ab.)<\/li>\n<\/ul>\n<p>Die erste Herausforderung f\u00fcr ein solches Skript ist zun\u00e4chst, den korrekten Zeitpunkt des Sonnenaufgangs bzw. -untergangs zu berechnen. Dazu muss man wissen, dass nat\u00fcrlich die D\u00e4mmmerung vom Wetter abh\u00e4ngig ist, aber der Erdtag auch gar nicht exakt 24 Stunden lang ist, sondern sich nur &#8222;im Jahresmittel&#8220; ausgleicht. Das f\u00fchrt zu Abweichungen, welche man &#8211; zumindest bis 2027 &#8211; recht exakt berechnen kann.<\/p>\n<p>Das nachfolgende Skript berechnet f\u00fcr den aktuellen Tag die Zeitpunkte und gibt diese gerundet auf Minuten aus. Man sollte vorher seine Position in den Variablen <code>posLaenge<\/code> und <code>posBreite<\/code> korrigieren, denn 51\u00b0\/10\u00b0 ist grob in der Mitte Deutschlands, zwischen der westlichsten Stadt Deutschlands Isenbruch\/Selfkant (51.05\u00b0, 5.866944\u00b0) und der \u00f6stlichsten Stadt Deutschlands Nei\u00dfeaue (51.247\u00b0, 14.975\u00b0) liegen ca. 35 Minuten.<\/p>\n<p>Das Skript nutzt f\u00fcr die detaillierten Berechnungen bc, welches auf dem eingesetzten Unix-System vorhanden sein sollte. Da bc kein arccos(x) kann, musste ich mir mit der Umrechnung <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-166\" alt=\"acos\" src=\"https:\/\/www.anginf.de\/wp-content\/uploads\/acos.png\" width=\"281\" height=\"31\" \/> helfen.<\/p>\n<p>Wer das Skript \u00fcbrigens alle Vorberechnungen erledigen l\u00e4sst, um darauf sp\u00e4ter zur\u00fcckzugreifen, sollte das per \u00fcbergebene Datum wie <code>date --date=\"+1year\"<\/code> immer mit einer Uhrzeit nach 3 Uhr nachts versehen, damit die Berechnung der Winter- bzw. Sommerzeit mit greift. Sonst findet die Berechnung einen Tag zu sp\u00e4t statt. Die Uhren werden ja um 2 bzw. 3 Uhr nachts umgestellt, nicht bereits um Mitternacht.<\/p>\n<pre lang=\"bash\">#!\/bin\/bash\r\n# Unsere Position\r\nposLaenge=\"10.0\"\r\nposBreite=\"51.0\"\r\n\r\n# Notwendige Vorberechnungen\r\nzoneinfo=$(date +%z) # Zeitzone\r\nT=`date +%j` # Tag im Jahr\r\npi=\"3.14159265358979323844\" # pi=`echo \"4*a(1)\" | bc -l`\r\nrad=$(echo \"${pi}\/180\" | bc -l)\r\nh=$(echo \"-(5\/6)*(${rad})\" | bc -l) # H\u00f6he des Sonnenmittelpunkts bei Aufgang: Radius+Refraktion\r\nBreiteRAD=$(echo \"${posBreite}*${rad}\" | bc -l)\r\n\r\n# Welcher Tag ist heute?\r\necho \"Heute ist $(date +%d.%m.%y), der $(date +%j). Tag im Jahr\"\r\n\r\necho -n \"Wir nutzen die Zeitzone $(date +%Z), dies entspricht $(date +%z) und damit \"\r\necho \"${zoneinfo:0:3}\"\r\n\r\nsonnendekl=`echo \"0.409526325277017*s(0.0169060504029192*(${T}-80.0856919827619))\" | bc -l`\r\nsonnendeklDEG=$(echo \"${sonnendekl} \/ ${rad}\" | bc -l)\r\n\r\narccosint=$(echo \"(s(${h})-s(${BreiteRAD})*s(${sonnendekl}))\/(c(${BreiteRAD})*c(${sonnendekl}))\" | bc -l)\r\narccosintsign=${arccosint:0:1}\r\nif [ ${arccosintsign} == \"-\" ]; then\r\n  usesign=\"+\"\r\nelse\r\n  usesign=\"-\"\r\nfi\r\narc2cosint=$(echo \"(${arccosint}) * (${arccosint})\" | bc -l)\r\nacoszeit=$(echo \"${pi}\/2 ${usesign} a(sqrt(${arc2cosint} \/ (1 - (${arc2cosint}) ) ) ) \" | bc -l)\r\n\r\nzeitdiff=$(echo \"12*${acoszeit}\/${pi}\" | bc -l) # KORREKT!\r\n\r\nzeitgleich=$(echo \"-0.170869921174742*s(0.0336997028793971 * ${T} + 0.465419984181394) - 0.129890681040717*s(0.0178674832556871*${T} - 0.167936777524864)\" | bc -l)\r\naufgang=$(echo \"12-(${zeitdiff})-(${zeitgleich})-(${posLaenge}\/15)${zoneinfo:0:3}\" | bc -l)\r\nuntergang=$(echo \"12+(${zeitdiff})-(${zeitgleich})-(${posLaenge}\/15)${zoneinfo:0:3}\" | bc -l)\r\n\r\nif [ ${aufgang:1:1} == \".\" ]; then\r\n  # Ist ein einstelliges Ergebnis der Form x.xxxx, wir brauchen noch eine 0 vorne\r\n  aufgang=$(echo 0${aufgang})\r\nfi\r\n# Fuer unsere Breitengrade ueberfluessig, nur der Vollstaendigkeit halber:\r\n#if [ ${untergang:1:1} == \".\" ]; then\r\n# Ist ein einstelliges Ergebnis der Form x.xxxx, wir brauchen noch eine 0 vorne\r\n#  untergang=$(echo 0${untergang})\r\n#fi\r\n\r\n# Umrechnung in Stunden (trivial) und Minuten (runden!)\r\nAufgangMinute=$(echo \"(${aufgang} - ${aufgang:0:2}) * 60\" | bc | xargs printf \"%02.0f\\n\")\r\nif [ ${AufgangMinute} == \"60\" ]; then\r\n  AufgangMinute=\"00\"\r\n  AufgangStunde=$(echo \"${aufgang:0:2} + 1\" | bc | xargs printf \"%02.0f\")\r\nelse\r\n  AufgangStunde=${aufgang:0:2}\r\nfi\r\necho \"Aufgang (hh:mm): ${AufgangStunde}:${AufgangMinute}\" # Immer ein zweistelliges Ergebnis\r\n\r\n\r\nUntergangMinute=$(echo \"(${untergang} - ${untergang:0:2}) * 60\" | bc | xargs printf \"%02.0f\\n\")\r\nif [ ${UntergangMinute} == \"60\" ]; then\r\n  UntergangMinute=\"00\"\r\n  UntergangStunde=$(echo \"${untergang:0:2} + 1\" | bc | xargs printf \"%02.0f\")\r\nelse\r\n  UntergangStunde=${untergang:0:2}\r\nfi\r\necho \"Untergang (hh:mm): ${UntergangStunde}:${UntergangMinute}\" # Immer ein zweistelliges Ergebnis\r\n\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Um ein Fritz!DECT 200, welche eine Au\u00dfenbeleuchtung steuern soll, so anzusprechen, wie ich es mir vorgestellt habe, brauche ich eine automatisierte Steuerung. Die von AVM mitgelieferten Einstellm\u00f6glichkeiten auf der Fritz!Box sind schon recht umfangreich, bilden aber leider genau meinen Anwendungsfall nicht ab. Schalte morgens ab 07:00 Uhr bis Sonnenaufgang die Au\u00dfenbeleuchtung ein. Falls der Sonnenaufgang &hellip; <a href=\"https:\/\/www.anginf.de\/?p=138\" class=\"more-link\"><span class=\"screen-reader-text\">Sonnenaufgang und Sonnenuntergang in Bash-Skript berechnen<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-138","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"_links":{"self":[{"href":"https:\/\/www.anginf.de\/index.php?rest_route=\/wp\/v2\/posts\/138","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.anginf.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.anginf.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.anginf.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.anginf.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=138"}],"version-history":[{"count":38,"href":"https:\/\/www.anginf.de\/index.php?rest_route=\/wp\/v2\/posts\/138\/revisions"}],"predecessor-version":[{"id":450,"href":"https:\/\/www.anginf.de\/index.php?rest_route=\/wp\/v2\/posts\/138\/revisions\/450"}],"wp:attachment":[{"href":"https:\/\/www.anginf.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.anginf.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=138"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.anginf.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}