package POEDaemon::Sunrise; use strict; use warnings FATAL => 'all'; no warnings 'redefine'; use Astro::Sunrise; use POSIX qw(mktime); use POE; use POEDaemon; sub states { return $_[0], [qw( sunrise_start sunrise_periodic60s_check )]; } sub sunrise_start { my ($kernel, $heap) = @_[KERNEL, HEAP]; $heap->{periodic}->{sunrise_periodic60s_check} = 60; unless (cfg->{sunrise}->{longitude} && cfg->{sunrise}->{latitude} && cfg->{sunrise}->{timezone}) { log_enabled && logline 'config error'; return; } $kernel->yield('sunrise_periodic60s_check'); } sub sunrise_periodic60s_check { my ($kernel, $heap) = @_[KERNEL, HEAP]; my $ts = time; my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $ts; my $mon_full = $mon + 1; my $year_full = $year + 1900; my $longitude = cfg->{sunrise}->{longitude}; my $latitude = cfg->{sunrise}->{latitude}; my $timezone = cfg->{sunrise}->{timezone}; my $sun_altitude_degrees = -0.833; my $sunrise_plus_seconds = 3600; my $sunset_minus_seconds = 3600; my ($sunrise, $sunset) = sunrise $year_full, $mon_full, $mday, $longitude, $latitude, $timezone, $isdst, $sun_altitude_degrees, 1; my ($sunrise_hour, $sunrise_min) = split ':', $sunrise; my ($sunset_hour, $sunset_min) = split ':', $sunset; my $sunrise_ts = mktime $sec, $sunrise_min, $sunrise_hour, $mday, $mon, $year, $wday, $yday, $isdst; my $sunset_ts = mktime $sec, $sunset_min, $sunset_hour, $mday, $mon, $year, $wday, $yday, $isdst; my $sunrise_ts_modified = $sunrise_ts + $sunrise_plus_seconds; my $sunset_ts_modified = $sunset_ts - $sunset_minus_seconds; my $value; my $prev_sun = $heap->{sun}->{status}; my $sun_logval = 'n/a'; #log_enabled && logline "if (%s >= %s && %s <= %s)", # $ts, # $sunrise_ts_modified, # $ts, # $sunset_ts_modified; if ($ts >= $sunrise_ts_modified && $ts <= $sunset_ts_modified) { unless (defined $prev_sun && $prev_sun == 1) { #log_enabled && logline 'sun is up'; $sun_logval = 'up'; $heap->{sun}->{status} = 1; $value = 1; } } else { unless (defined $prev_sun && $prev_sun == 0) { #log_enabled && logline 'sun is down'; $sun_logval = 'down'; $heap->{sun}->{status} = 0; $value = 0; } } log_enabled && logline "sun is %s->%s, rise=%s+%s set=%s-%s @ lon=%s lat=%s timezone=%s DST=%s", (defined $prev_sun ? uc $prev_sun : 'n/a'), (defined $sun_logval ? uc $sun_logval : 'n/a'), $sunrise, concise_duration_exact $sunrise_plus_seconds, $sunset, concise_duration_exact $sunset_minus_seconds, $longitude, $latitude, $timezone, $isdst; if (defined $value) { $kernel->yield(eventsystem_input => { type => 'sun', value => $value, prev_value => $prev_sun, time => time_hires, }); } my $day_length = $sunset_ts - $sunrise_ts; my $night_length = 86400 - $day_length; $heap->{sun}->{info} = { sunrise => $sunrise, sunset => $sunset, longitude => $longitude, latitude => $latitude, timezone => $timezone, isdst => $isdst, sun_altitude_degrees => $sun_altitude_degrees, value => $value, day_length => concise_duration_exact $day_length, night_length => concise_duration_exact $night_length, day_length_seconds => $day_length, night_length_seconds => $night_length, sunrise_plus_seconds => $sunrise_plus_seconds, sunset_minus_seconds => $sunset_minus_seconds, year_full => $year_full, mon_full => $mon_full, mday => $mday, } } 1;