Фотодатчик для управления ночным освещением - штука, считай, стандартная.
Маленькая коробочка, внутри фоторезистор, реле - да все знают.
Но есть нюанс...
Когда групп освещения больше чем одна - начинается: куда повесить датчики, чтобы они видели дневной свет, но не видели лампы, как решить задачу "добавим еще пару групп, потом уберем", а еще хочется иметь возможность принудительно включать и выключать когда нужно, и при этом не тянуть дополнительных проводов между лампами, сетью, датчиками.
В общем, когда такое понадобилось - заменил датчики на управляемые реле, один датчик остался как сенсор освещенности, он давал команду серверу на включение исполнительных реле, и всё это работало хорошо, пока этот самый сенсор не накрылся.
Дело было вечером, лезть со стремянкой менять датчик было лень...
А собственно, зачем мне этот датчик? Он отправляет сигнал на управляющий сервер, который рассылает команды реле - но ведь можно просто включать вечером и выключать утром, сервер может сделать это сам. От заката - до рассвета.
Реле управляются MQTT, остается просто определить, когда эти самые закаты с рассветами.
Сделал, как обычно, на Perl, потому что это просто и работает без особых плясок с бубном.
Для этого используется библиотека Astro::Sunrise, которая устанавливается как и любая другая подобная, через CPAN:
# cpan Astro::Sunrise
Способы ее использования - man Astro::Sunrise
Оставалось написать скрипт, который бы получал значения восхода-заката "на сегодня", сравнивал с текущим временем и отправлял команды.
Чтобы не возиться лишний раз с минутами их можно просто добавить в часы, как дробную часть.
Запускать по крону раз, скажем, в пять минут - и сравнивать. Неизящно, зато работает как топор.
#!/usr/bin/perl use strict; use warnings; use Astro::Sunrise; use Net::MQTT::Simple; use JSON; $|=1; # задаем координаты точки на карте и смещение таймзоны my $longitude = 37.6173; my $latitude = 55.7558; my $time_zone = 3; # задаем коды реле my $relay1 = "3665288296"; my $relay2 = "2741656981"; my $relay3 = "109410833"; my $relay4 = "2440669403"; ######################################## # подключаемся к MQTT my $mqtt = Net::MQTT::Simple->new("127.0.0.1"); # отправка MQTT message sub pub { my ($topic, $message, $retain) = @_; if($retain){ $mqtt->retain($topic => $message); }else{ $mqtt->publish($topic => $message); } } #------------------------------------------ sub do_on { pub("mesh/to/$relay1","on 1") ; pub("mesh/to/$relay2","on 1") ; pub("mesh/to/$relay3","on 1") ; pub("mesh/to/$relay4","on 1") ; } sub do_off { pub("mesh/to/$relay1","off 1"); pub("mesh/to/$relay2","off 1"); pub("mesh/to/$relay3","off 1"); pub("mesh/to/$relay4","off 1"); } # start ------------------------------- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); # коррекция года и месяца $mon ++; $year += 1900; # получаем времена восхода и заката # alt - высота Солнца над (под) горизонтом. Чем меньше значение - тем темнее my ($sunrise,$sunset) = sunrise( { year => $year , month => $mon , day => $mday, lat => $latitude, lon => $longitude, isdst => 0, alt => -6, # -12, -18 tz => $time_zone } ); # минуты - в дробную часть if($sunrise =~ /(\d+):(\d+)/){ $sunrise = $1 + $2 / 60; } if($sunset =~ /(\d+):(\d+)/){ $sunset = $1 + $2 / 60; } $hour += $min / 60; # проверка интервала if ($hour > $sunrise && $hour < $sunset){ do_off; }else{ do_on; } # ждем пару сек, чтобы сообщения точно отправились sleep(2);
Готово. Когда темнеет - свет включается, когда рассветает - выключается, в зависимости от широты, долготы и времени года.
В этот раз электроника не понадобилась...

