От заката до рассвета…

от автора

Фотодатчик для управления ночным освещением — штука, считай, стандартная.
Маленькая коробочка, внутри фоторезистор, реле — да все знают.
Но есть нюанс…

Когда групп освещения больше чем одна — начинается: куда повесить датчики, чтобы они видели дневной свет, но не видели лампы, как решить задачу «добавим еще пару групп, потом уберем», а еще хочется иметь возможность принудительно включать и выключать когда нужно, и при этом не тянуть дополнительных проводов между лампами, сетью, датчиками.
В общем, когда такое понадобилось — заменил датчики на управляемые реле, один датчик остался как сенсор освещенности, он давал команду серверу на включение исполнительных реле, и всё это работало хорошо, пока этот самый сенсор не накрылся.

Дело было вечером, лезть со стремянкой менять датчик было лень…
А собственно, зачем мне этот датчик? Он отправляет сигнал на управляющий сервер, который рассылает команды реле — но ведь можно просто включать вечером и выключать утром, сервер может сделать это сам. От заката — до рассвета.

Реле управляются MQTT, остается просто определить, когда эти самые закаты с рассветами.
Сделал, как обычно, на Perl, потому что это просто и работает без особых плясок с бубном.
Для этого используется библиотека Astro::Sunrise, которая устанавливается как и любая другая подобная, через CPAN:

# cpan Astro::Sunrise

Способы ее использования — man Astro::Sunrise
Оставалось написать скрипт, который бы получал значения восхода-заката «на сегодня», сравнивал с текущим временем и отправлял команды.

Чтобы не возиться лишний раз с минутами их можно просто добавить в часы, как дробную часть.
Запускать по крону раз, скажем, в пять минут — и сравнивать. Неизящно, зато работает как топор.

#!/usr/bin/perluse 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";######################################### подключаемся к MQTTmy $mqtt = Net::MQTT::Simple->new("127.0.0.1");# отправка MQTT messagesub 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);

Готово. Когда темнеет — свет включается, когда рассветает — выключается, в зависимости от широты, долготы и времени года.

В этот раз электроника не понадобилась…

ссылка на оригинал статьи https://habr.com/ru/articles/1084054/