От заката до рассвета…
Фотодатчик для управления ночным освещением - штука, считай, стандартная.
Маленькая коробочка, внутри фоторезистор, реле - да все знают.
Но есть нюанс...
Когда групп освещения больше чем одна - начинается: куда повесить датчики, чтобы они видели дневной свет, но не видели лампы, как решить задачу "добавим еще пару групп, потом уберем", а еще хочется иметь возможность принудительно включать и выключать когда нужно, и при этом не тянуть дополнительных проводов между лампами, сетью, датчиками.
В общем, когда такое понадобилось - заменил датчики на управляемые реле, один датчик остался как сенсор освещенности, он давал команду серверу на включение исполнительных реле, и всё это работало хорошо, пока этот самый сенсор не накрылся.
Дело было вечером, лезть со стремянкой менять датчик было лень...
А собственно, зачем мне этот датчик? Он отправляет сигнал на управляющий сервер, который рассылает команды реле - но ведь можно просто включать вечером и выключать утром, сервер может сделать это сам. От заката - до рассвета.
Реле управляются 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);Готово. Когда темнеет - свет включается, когда рассветает - выключается, в зависимости от широты, долготы и времени года.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.