Фотодатчик для управления ночным освещением — штука, считай, стандартная.
Маленькая коробочка, внутри фоторезистор, реле — да все знают.
Но есть нюанс…
Когда групп освещения больше чем одна — начинается: куда повесить датчики, чтобы они видели дневной свет, но не видели лампы, как решить задачу «добавим еще пару групп, потом уберем», а еще хочется иметь возможность принудительно включать и выключать когда нужно, и при этом не тянуть дополнительных проводов между лампами, сетью, датчиками.
В общем, когда такое понадобилось — заменил датчики на управляемые реле, один датчик остался как сенсор освещенности, он давал команду серверу на включение исполнительных реле, и всё это работало хорошо, пока этот самый сенсор не накрылся.
Дело было вечером, лезть со стремянкой менять датчик было лень…
А собственно, зачем мне этот датчик? Он отправляет сигнал на управляющий сервер, который рассылает команды реле — но ведь можно просто включать вечером и выключать утром, сервер может сделать это сам. От заката — до рассвета.
Реле управляются 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/