Этот пост написан в основном для себя любимогою Если вдруг чето, то должно быть место, куда можно прибежать, прочитать и быстренько восстановить :-) Если же кто-то вынесет что-то полезное для себя - я буду только рад.
Итак, есть дома зверушка Qnap TS-112P
https://qnap.ru/ts-112p . Это простенький однодисковый NAS. Используется в основном для заливания бакапов с работы и как замена флешки. Захотелось кино, засунул ему торрент файл, добрел домой, включил телевизор и смотришь. Т.е. ftp и dlna серверы. Появилась проблема - обеспечить попугайца в доме светом. По осени ночи становятся все длинее и длинее, а у птиц обмен веществ быстрый, он должен с минимальными перерывами жрать, срать и орать. Раньше использовал простейшее электронное реле для этого, но задалбывает. Рассветы с закатами каждый день на пару минут то туда, то оттуда перемещаются. Опять же переносы выходных на понедельник-пятницу (радости проснуться в 5 утра в выходной от яркого света и воплей попугайца - немного). В общем вроде как все автоматически, но постоянно то сюда добавть, то отсюда убавь.
Делай раз: покупается вот такой вот девайс
wi-fi розетка Это розетка, включать которую можно с помощью http запросов. Например,
http://192.168.0.111/gpio?st=1&pin=0 - включить,
http://192.168.0.111/gpio?st=0&pin=0 - выключить.
Дополнительные команды: &flash=1 - настройка запишется в энергонезависимую память, &click=10 - инвертирует состояние через указанный промежуток времени в секундах,mclick -аналогично в миллисекундах.
Дальше ставим задачу для "полоумного" таймера.
1. Включаемся в по рабочим дням в 5 утра (если не было еще рассвета). По выходным в 9 утра.
2. Выключаемся на рассвете +10 минут
3. Включаемся за 15 минут до заката и выключаемся в 22:00.
4. Все нестандартные дни: понедельник-пятница, которые выходные лежат рядышком в тестовом файле с буквкой o. Например, вчера был выходной понедельник o06.11.2017, если наоборот, суббота-воскресенье рабочие, то там же, аналогично с буковки w. Файлик создать просто. Пишем яндексу "производственный календарь за 2018" и на сайте консультатн плюс очень наглядно.
5. http запросы на включение/выключение будут посылаться средствами cron'a (планировщик задач по виндусячи). Соответственно, моя программулька должна запускаться при загрузке, править cron файл в зависимости от текущего времени суток, прописывать себя в крон на следующий день и умирать. Ничего постороннего в памяти не должно болтаться.
5. Самое главное. Хотелось добиться результата один раз настроил и забыл, т.е. перезагрузки устройства в любое время должны проходить без вопрсов. Свет должен быть в свое время и свое время не быть :-)
Первая проблема. Как добавить свой скрип в автозагрузку. Бился долго. Помог вот этот рецепт
фак по qnap Именно первый вариант. Только в моем случае путь не /share/MD0_DATA, а /share/HDA_DATA
На qnap'е уже есть
php . Будем пытаться писать на нем. Гулим, дерем куски из рецептов, допиливаем по месту. Php своей свободой малость подутомил. Забыл поставить $ перед переменной или ошибся в написании переменной - он слова не скажет, но ни хрена не работает. Особенно по первости было туго, но чья-та умная мысль в очередной раз подтвердилась "Компьютер делает не то что вы хотите, а то что ему приказываете".
Домучал. Все работает. Несколько дней проверял, наблюдал, расставлял костылики. Ну вроде все работает. В голове крутилась мысль, о том, что надо бы сохранить написанное где-то еще. Все ща, да ща. Вот тут только это еще отлакирую. Все. Придраться не к чему и тут мне qnap пишет, что новая прошивка вышла. Надо бы обновиться. Ну а чего, раз 50 уже делал. Ну Вы уже поняли. Установилось, перезагрузилось и все чистенькое. Ничего нет. Второй раз писалось конечно быстрее :-)
Ну и сами результаты мучений:
[~] # cat /share/HDA_DATA/.qpkg/autorun/autorun.sh
#!/bin/sh
tmpfile=/tmp/crontab.tmp
tmpfile1=/tmp/crontab1.tmp
# удалем себя из крона, т.к. фиг знает в какое время стоит запуск
crontab -l | grep -vi "/autorun.sh" > $tmpfile
# удалем из крона все записи о включении-выключении света. Может они вчерашние?
cat $tmpfile | grep -vi "192.168.128.32" > $tmpfile1
# Добавляем себя в крон обратно, на 0:25 ежедневно
echo "25 0 * * * /share/HDA_DATA/.qpkg/autorun/autorun.sh > /dev/null" >> $tmpfile1
# Запускаем php скрип, который рассчитывает восходы и закаты...
/mnt/ext/opt/apache/bin/php /share/HDA_DATA/.qpkg/autorun/setsvet.php
# Кормим полученный файл крону
crontab $tmpfile1
# cat $tmpfile1
# Удаляем временные файлы
rm $tmpfile
rm $tmpfile1
# Дергаем кроном
/etc/init.d/crond.sh restart
===========================================
cat /share/HDA_DATA/.qpkg/autorun/setsvet.php
# Файл, куда писать сформированные задачи для cron'а
$tmpfile1 = "/tmp/crontab1.tmp";
# Устанавливаем временную зону
date_default_timezone_set('Europe/Moscow');
# Устанавливаем значения переменных
$seychas = time();
#$seychas = mktime(21,0,0,11,07,2017);
# H:M:S M:D:Y
# Файл с датами переносов дней
$file_perenos = "/share/HDA_DATA/.qpkg/autorun/days";
$rassvet = date_sunrise($seychas, SUNFUNCS_RET_TIMESTAMP, 56.21, 37.8, 90, 3); # расвет для моего колхоза
$zakat = date_sunset($seychas, SUNFUNCS_RET_TIMESTAMP, 56.21, 37.8, 90, 3); # закат для моего колхоза
$diff_rassvet = 10*60; # 10 мин переводим в секунды
$diff_zakat = 10*60; # 10 мин переводим в секунды
$utro_start = mktime(5,0,0,date('m',$seychas),date('d',$seychas),date('Y',$seychas));
$utro_start_otdyh = mktime(9,0,0,date('m',$seychas),date('d',$seychas),date('Y',$seychas));
$noch_stop = mktime(22,0,0,date('m',$seychas),date('d',$seychas),date('Y',$seychas));
echo "\n";
# Ищем в файле, не перенесен ли рабочий день и выходной
$file = file($file_perenos); // Считываем весь файл в массив
for($i = 0; $i < sizeof($file); $i++)
{ $pos = strpos($file[$i],date("d.m.Y",$seychas));
if ($pos === false) {}
else
{$st = $file[$i];
break;
}}
# Если сегодня суббота или воскресенье или день найден в файле с o, то это выходной
if ($st[0] == 'w') {}
else {if (($st[0] == 'o') or (date('w',$segodnya) == 0) or (date('w',$segodnya) == 6)) {$utro_start = $utro_start_otdyh;}}
#
$rassvet = $rassvet + $diff_rassvet; # добавляем 10 минут кл времени работы
$zakat = $zakat - $diff_zakat;
echo "*************************************************\n";
echo "Сейчас ".date("H:i d.m.Y",$seychas)."\n";
echo "Рассвет ".date("H:i d.m.Y",$rassvet)."\n";
echo "Закат ".date("H:i d.m.Y",$zakat)."\n";
echo "Утро ".date("H:i d.m.Y",$utro_start)."\n";
echo "*************************************************\n";
# Утренний промежуток
if ($seychas < $rassvet) {
if ($seychas > $utro_start){
echo "Включаем курлом свет\n";
$output = `/mnt/ext/usr/local/sbin/curl --silent --output /dev/null -u admin:admin http://192.168.128.32/gpio?st=1&pin=0`;
}
else {echo "Формируем задание кроном на утреннее включение света\n";
$buff[] = date('i',$utro_start).' '.date('H',$utro_start).' * * * /mnt/ext/usr/local/sbin/curl --silent --output /dev/null -u admin:admin http://192.168.128.32/gpio?st=1&pin=0';}
echo "Формируем задание кроном на утреннее выключение света\n";
$buff[] = date('i',$rassvet).' '.date('H',$rassvet)
.' * * * /mnt/ext/usr/local/sbin/curl --silent --output /dev/null -u admin:admin http://192.168.128.32/gpio?st=0&pin=0';}
# Вечерний промежуток
if ($seychas < $noch_stop){
if ($seychas > $zakat) {
echo "Включаем курлом свет\n";
$output = `/mnt/ext/usr/local/sbin/curl --silent --output /dev/null -u admin:admin http://192.168.128.32/gpio?st=1&pin=0`;
}
else {echo "Формируем задание кроном на вечернее включение света\n";
$buff[] = date('i',$zakat).' '.date('H',$zakat)
.' * * * /mnt/ext/usr/local/sbin/curl --silent --output /dev/null -u admin:admin http://192.168.128.32/gpio?st=1&pin=0';}
echo "Формируем задание кроном на вечернее выключение света\n";
$buff[] = date('i',$noch_stop).' '.date('H',$noch_stop)
.' * * * /mnt/ext/usr/local/sbin/curl --silent --output /dev/null -u admin:admin http://192.168.128.32/gpio?st=0&pin=0';}
for($i = 0; $i < sizeof($buff); $i++)
echo $buff[$i]."\n";
$fp = fopen($tmpfile1, "a+");
for($i = 0; $i < sizeof($buff); $i++)
fputs($fp, $buff[$i]."\n");
fclose($fp);
?>
p.s. Не ленитесь, делайте бакапы. :-)