Qnap TS-112P как костыль для умного дома

Nov 07, 2017 14:53

Этот пост написан в основном для себя любимогою Если вдруг чето, то должно быть место, куда можно прибежать, прочитать и быстренько восстановить :-) Если же кто-то вынесет что-то полезное для себя - я буду только рад.



Итак, есть дома зверушка 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. Не ленитесь, делайте бакапы. :-)

полоумный дом, php, qnap

Up