Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/tclsh
- #Version 1.5 with wunderground patch and acosinus fix
- #param 0 = Breitengrad (noerdlich)
- #param 1 = Laengengrad (oestlich)
- #param 2 = kuenstlicher Horizont
- #param 3 = PLZ
- #
- # !!! Please change the API Key and City in Line 119 (and remove <>) !!!
- #
- #only run once, check if locking port 60 is opened
- if {[catch {socket -server unknown -myaddr 127.0.0.1 60} locksock]} then {
- exit 0
- }
- source /www/addons/lcd_msg/daemonize.tcl
- load tclrega.so
- proc showTime x {
- if {$x && $x != 2000000000} then {
- clock format $x -format "%H:%M:%S"
- } else {
- return "--:--:--"
- }
- }
- proc log x {
- puts $::logfile "[showTime [clock seconds]]: $x"
- flush $::logfile
- }
- #define constants for the list access to make review easier
- set NIGHT 0
- set SR_ASTRONOMICAL 1
- set SR_NAUTICAL 2
- set SR_CIVIL 3
- set SR_SUNRISE 4
- set SR_INDOOR 5
- set SR_WEATHER 6
- set SS_WEATHER 7
- set SS_INDOOR 8
- set SS_SUNRISE 9
- set SS_CIVIL 10
- set SS_NAUTICAL 11
- set SS_ASTRONOMICAL 12
- proc getTimeDiff {dayofyear} {
- return [expr {-0.171*sin(0.0337 * $dayofyear + 0.465) - 0.1299*sin(0.01787 * $dayofyear - 0.168)}]
- }
- #proc calcTwilightTimes {latitude longitude timezone dayofyear horizon sunrisevar sunsetvar} {
- # upvar $sunrisevar sunrise
- # upvar $sunsetvar sunset
- #
- # if {[catch {
- # set timediff [getTimeDiff $dayofyear]
- # set declination [expr {0.4095 * sin(0.016906 * ($dayofyear - 80.086) ) }]
- # set suntime [expr {12*acos((sin($horizon/57.29578) - sin($latitude/57.29578)*sin($declination)) / (cos($latitude/57.29578)*cos($declination)))/3.141592}]
- # set sunrise [expr {[clock scan "0"] + round((12 - $timediff - $suntime - $longitude/15.0 + $timezone)*3600)}]
- # set sunset [expr {[clock scan "0"] + round((12 - $timediff + $suntime - $longitude/15.0 + $timezone)*3600)}]
- # }] } then {
- # set sunrise 0
- # set sunset 2000000000
- # }
- #}
- proc calcTwilightTimes {latitude longitude timezone dayofyear horizon sunrisevar sunsetvar} {
- upvar $sunrisevar sunrise
- upvar $sunsetvar sunset
- set timediff [expr {-0.171*sin(0.0337 * $dayofyear + 0.465) - 0.1299*sin(0.01787 * $dayofyear - 0.168)}]
- set declination [expr {0.4095 * sin(0.016906 * ($dayofyear - 80.086) ) }]
- set acosvar [expr ((sin($horizon/57.29578) - sin($latitude/57.29578)*sin($declination)) / (cos($latitude/57.29578)*cos($declination)))]
- if {$acosvar <-1} {
- set acosvar -1
- log "Die Variable acosvar wurde auf -1 gesetzt, da ihr ursprünglicher Wert kleiner -1 war"
- }
- if {$horizon == -18} {
- log "Die Variable acosvar muss zwischen -1 und 1, liegen und ist momentan $acosvar"
- }
- set suntime [expr {12*acos($acosvar)/3.141592}]
- set sunrise [expr {[clock scan "0"] + round((12 - $timediff - $suntime - $longitude/15.0 + $timezone)*3600)}]
- set sunset [expr {[clock scan "0"] + round((12 - $timediff + $suntime - $longitude/15.0 + $timezone)*3600)}]
- }
- #proc getTwilightHorizon {logfile plz base_horizon} {
- #
- # set url http://www.google.com/ig/api?weather=$plz-Germany&hl=de
- # set twilightHorizon [expr {$base_horizon + 5.0}]
- # catch {
- # exec /usr/bin/wget -q -O /tmp/twilightweather.xml $url
- # set f [open "/tmp/twilightweather.xml"]
- # set a [read $f]
- # close $f
- # regexp "<current_conditions>(.*)</current_conditions>" $a dummy current
- # foreach tag [split $current >] {
- # regexp {<([^=>]*) data="([^=>"]*)"/} $tag dummy key value
- # #" for editor
- # set aCurrent($key) "$value"
- # }
- # ::log "current condition is \"$aCurrent(condition)\""
- # file delete /tmp/twilightweather.xml
- # switch $aCurrent(condition) {
- # "Klar" {set twilightHorizon [expr {$base_horizon + 0.2}]}
- # "Meist sonnig" {set twilightHorizon [expr {$base_horizon + 1.5}]}
- # "Teils sonnig" {set twilightHorizon [expr {$base_horizon + 3.0}]}
- # }
- # }
- # ::log "twilight horizon set to $twilightHorizon"
- # return $twilightHorizon
- #}
- #
- #modifizierter Teil w/ GOOGLE Wetterdienstabdankung. Jetzt wunderground.com
- #
- proc getTwilightHorizon {base_horizon} {
- set url http://api.wunderground.com/api/<YOUR API KEY>/conditions/lang:DL/q/germany/<CITY>.xml
- set twilightHorizon 5.0
- exec /usr/bin/wget -q -O /tmp/twilightweather.xml $url
- set f [open "/tmp/twilightweather.xml"]
- set input [read $f]
- close $f
- regexp "<current_observation>(.*?)</current_observation>" $input dummy current ; #get current observation
- regexp "<weather>(.*?)</weather>" $current dummy weather ; #get current weather
- log "current condition is \"$weather\""
- file delete /tmp/twilightweather.xml
- switch $weather {
- "Klar" {set twilightHorizon [expr {$base_horizon + 0.2}]}
- "Meist sonnig" {set twilightHorizon [expr {$base_horizon + 1.0}]}
- "Teils sonnig" {set twilightHorizon [expr {$base_horizon + 1.7}]}
- "Heiter" {set twilightHorizon [expr {$base_horizon + 1.8}]}
- "Wolkig" {set twilightHorizon [expr {$base_horizon + 1.9}]}
- "Meistens bewölkt" {set twilightHorizon [expr {$base_horizon + 2.0}]}
- "Leichtes Nieseln" {set twilightHorizon [expr {$base_horizon + 4.0}]}
- }
- log "twilight horizon set to $twilightHorizon"
- return $twilightHorizon
- }
- proc getDayOfYear {timestamp} {
- set dayofyear [string trimleft [clock format $timestamp -format "%j"] "0"]
- #subtract the fractional part to the next leap-year february 29th from the current day of the year
- set dayofyear [expr {$dayofyear - ([clock format $timestamp -format "%Y"]%4)/4.0 - ($dayofyear)/365.25/4.0}]
- return $dayofyear
- }
- proc waitToTime {logfile destTime} {
- set waittime [expr {1000*($destTime - [clock seconds])}]
- if {$waittime > 0} then {
- log "waiting [expr $waittime/1000] s until [clock format $destTime]"
- #after is off of several seconds (exactly 1/1000?) after long waits, so wait 1% shorter and then wait again
- after [expr { 990*($destTime - [clock seconds])}]
- after [expr {1000*($destTime - [clock seconds])}]
- } else {
- log "not waiting [expr $waittime/1000] s until [clock format $destTime]"
- }
- }
- proc displayValues {} {
- uplevel {
- set display "s. folgende Tabelle vom [clock format [lindex $twilight_times 6] -format "%d.%m."]"
- append display "</div><br/><table border=\"1\" bordercolor=\"#000000\" style=\"background-color:#5d6373\" width=\"100%\">\r\n"
- append display "<tr><td><b>Daemmerung</b></td><td><b>Morgens</b></td><td><b>Abends</b></td></tr>\r\n"
- for {set j 1} {$j <= 6} {incr j} {
- set insert "[lindex $twilight_descr $j]:"
- if {$j == $i || $j == 12-$i} then {set insert "<b>$insert</b>"}
- append display "<tr><td>$insert</td>"
- set insert "[showTime [lindex $twilight_times [expr $j-1]]]"
- if {$j == $i} then {set insert "<b>$insert</b>"}
- if {$j == 6 && !$srw_set} then {set insert "<i>$insert</i>"}
- append display "<td>$insert</td>"
- set insert "[showTime [lindex $twilight_times [expr 12-$j]]]"
- if {$j == 13-$i} then {set insert "<b>$insert</b>"}
- if {$j == 6 && !$ssw_set} then {set insert "<i>$insert</i>"}
- append display "<td>$insert</td></tr>\r\n"
- #log "updating twilight time table: [showTime [lindex $twilight_times [expr $j-1]]] [showTime [lindex $twilight_times [expr 12-$j]]] [string map {: { }} [lindex $twilight_descr [expr $j-1]]]"
- }
- append display "</table></td>"
- rega_script "dom.GetObject('Daemmerungszeiten').State('$display');"
- }
- }
- #
- # Main execution
- #
- set latitude [lindex $argv 0]
- set longitude [lindex $argv 1]
- set indoor_horizon [lindex $argv 2]
- set plz [lindex $argv 3]
- #some vars we need
- set horizon_values [list 0 -18 -12 -6 [expr {- 50.0 / 60.0}] $indoor_horizon [expr {$indoor_horizon + 5.1}]]
- set twilight_names [list night astronomical nautical civil standard indoor weather]
- set twilight_descr [list Nacht Astronom. Nautisch Buergerlich Standard Indoor Wetterabh.]
- while {1} {
- set timezone [expr {([clock scan "0 UTC"] - [clock scan "0"]) / 3600.0}]
- set now [clock seconds]
- set twilight_midnight [expr {[clock scan "0"] + round((0 - [getTimeDiff [getDayOfYear $now]] - $longitude/15.0 + $timezone)*3600)}]
- #get the day of the year as numeric value based on twilight midnight (time between midnight and twilight midnight belongs to day before)
- set yesterday_offset 0
- if {$now < $twilight_midnight} then {
- #use time table from day before
- set yesterday_offset 86400
- }
- set dayofyear [getDayOfYear [expr $now-$yesterday_offset]]
- catch {file delete "/tmp/twilight.[expr int($dayofyear)-3].log"}
- set logfile [open "/tmp/twilight.[expr int($dayofyear)].log" w]
- log "args: $argv"
- if {$now < $twilight_midnight} then {log "twilight midnight not reached, using yesterdays time table"}
- log "timezone: $timezone, twilight midnight: [showTime $twilight_midnight], dayofyear: $dayofyear"
- set twilight_times ""
- for {set i 1} {$i <= 6} {incr i} {
- calcTwilightTimes $latitude $longitude $timezone $dayofyear [lindex $horizon_values $i] sunrise_time sunset_time
- if {$sunrise_time == 0} then {
- log "no [lindex $twilight_names $i] twilight here and now"
- } elseif {$i != 6} then {
- log "calculated twilight times: sunrise [clock format $sunrise_time -format "%d., %H:%M:%S"], sunset [clock format $sunset_time -format "%d., %H:%M:%S"] for [lindex $twilight_names $i] ($i)"
- }
- #do not append weather sunrise
- if {$i != 6} then {
- lappend twilight_times [expr $sunrise_time-$yesterday_offset]
- }
- #append indoor sunrise again to replace weather sunrise
- if {$i == 5} then {
- lappend twilight_times [expr $sunrise_time-$yesterday_offset+1]
- }
- #always append sunset
- lappend twilight_times [expr $sunset_time-$yesterday_offset]
- }
- set twilight_times [lsort $twilight_times]
- log "calculated twilight times: sunrise [clock format [lindex $twilight_times 5] -format "%d., %H:%M:%S"], sunset [clock format [lindex $twilight_times 6] -format "%d., %H:%M:%S"] for [lindex $twilight_names 6] (6)"
- set srw_set 0
- set ssw_set 0
- displayValues
- #in the following calculation, assume that the weather sunrise and sunset are always subsequently on the current dayofyear
- for {set i 0} {$i < 12} {incr i} {
- set next_time [lindex $twilight_times $i]
- if {$i == 5 && [clock seconds] < [lindex $twilight_times 6]} then {
- #sunrise weather
- log "retrieving weather condition for sunrise"
- # calcTwilightTimes $latitude $longitude $timezone $dayofyear [getTwilightHorizon $logfile $plz $indoor_horizon] sunrise_weather dummy
- calcTwilightTimes $latitude $longitude $timezone $dayofyear [getTwilightHorizon $indoor_horizon] sunrise_weather dummy
- set next_time $sunrise_weather
- set srw_set 1
- set twilight_times [lreplace $twilight_times 5 5 $sunrise_weather]
- displayValues
- log "weather sunrise at [showTime $next_time]"
- }
- if {[clock seconds] < $next_time && $next_time != 2000000000} then {
- log "current twilight state $i ([lindex $twilight_descr [expr {6-abs($i-6)}]]), sunlight state [expr {6-abs($i-6)}], next at [showTime $next_time]"
- rega_script "dom.GetObject('Daemmerung').State('$i');"
- rega_script "dom.GetObject('Tageslicht').State('[expr {6-abs($i-6)}]');"
- displayValues
- waitToTime $logfile $next_time
- }
- if {$i == 6 && [clock seconds] < [lindex $twilight_times 7]} then {
- #sunset weather
- log "retrieving weather condition for sunset"
- #calcTwilightTimes $latitude $longitude $timezone $dayofyear [getTwilightHorizon $logfile $plz $indoor_horizon] dummy sunset_weather
- calcTwilightTimes $latitude $longitude $timezone $dayofyear [getTwilightHorizon $indoor_horizon] dummy sunset_weather
- set next_time $sunset_weather
- set ssw_set 1
- set twilight_times [lreplace $twilight_times 6 6 $sunset_weather]
- displayValues
- log "weather sunset at [showTime $next_time]"
- waitToTime $logfile $next_time
- }
- }
- rega_script "dom.GetObject('Daemmerung').State('12');"
- rega_script "dom.GetObject('Tageslicht').State('0');"
- log "twilight cycle completed for day of year $dayofyear, waiting until twilight midnight for next run"
- waitToTime $logfile [expr {$twilight_midnight + 86400 - $yesterday_offset}]
- close $logfile
- }
- if {[file exists /var/run/twilight.tcl.pid]} then {
- catch {
- set f [open /var/run/twilight.tcl.pid]
- set filepid [read $f]
- close $f
- if {[pid] == $filepid} then {
- file delete /var/run/twilight.tcl.pid
- }
- }
- }
- close $locksock
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement