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

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

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

Реле управляются 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);

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

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

Комментарии (2)


  1. qwe101
    19.09.2026 05:32

    Вопрос только, кто надёжней - сервер или сенсор? Да и потребление электричества у них, скорее всего, разное.


    1. qwe101
      19.09.2026 05:32

      Ещё - есть вопрос с облачностью. Плотные облака дают ощутимое затенение.