
Всем привет!
Сегодня я расскажу, как сделать простую PHP-страницу, закинуть ее на Omega2, и управлять на этой странице подключенным светодиодом (а по сути GPIO пинами).
Для начала обязательно расширьте память омеги, если вы это еще не сделали, инструкция здесь. Также рекомендую установить какой-нибудь файл-менеджер по типу WinSCP, инструкция здесь.
Итак, приступим.
Для чистоты эксперимента, я сделал полный сброс омеги до системных настроек, для этого я через терминал выполнил поочередно три команды (либо можно было зажать на 10 секунд кнопку перезагрузки на док-станции):
firstboot -y sync reboot
1. Устанавливаем PHP на Omega2
Я постараюсь написать все понятно, но если что, вот официальная документация: https://docs.onion.io/omega2-docs/installing-and-using-php.html
Для начала обновляем список пакетов:
opkg update
И за тем устанавливаем необходимые пакеты:
opkg install php7 php7-cgi
2. Настраиваем PHP на Omega2
Отлично, теперь идем и открываем файл /etc/config/uhttpd (еще раз напоминаю про файловый менеджер WinSCP из начала статьи). Добавляем в раздел config uhttpd ‘main’ две строчки, которые содержат адрес расположения PHP-интерпретатора, а также имя страницы по-умолчанию.
list interpreter ".php=/usr/bin/php-cgi" option index_page 'index.php'
Должно получиться примерно так:
config uhttpd 'main' list listen_http '0.0.0.0:80' list listen_http '[::]:80' list listen_https '0.0.0.0:443' list listen_https '[::]:443' option redirect_https '1' option home '/www' option rfc1918_filter '1' option max_requests '3' option max_connections '100' option cert '/etc/uhttpd.crt' option key '/etc/uhttpd.key' option cgi_prefix '/cgi-bin' option script_timeout '60' option network_timeout '30' option http_keepalive '20' option tcp_keepalive '1' option ubus_prefix '/ubus' list interpreter ".php=/usr/bin/php-cgi" option index_page 'index.php' config cert 'defaults' option days '730' option bits '2048' option country 'ZZ' option state 'Somewhere' option location 'Unknown' option commonname 'LEDE'
Сохраняем файл и перезапускаем WEB-сервер Omega2 через консоль следующей командой:
/etc/init.d/uhttpd restart
3. Тестируем
Если вы знакомы с серверами, хостингами и прочими словами, то знаете, что все файлы хранятся в папке www. Omega2, как маленький сервер не стал исключением.
Заходим в папку /www , создаем там папку test, и в ней файл index.php cо следующим содержимым:
<?php echo "Hello, World!"; ?>
Все, теперь открываем браузер, переходим по адресу http://192.168.3.1/test/ и видим следующее:
Если нет, возможно вы допустили ошибку где-то здесь:
- Не сделали рестарт сервера (описано выше)
- Не туда дописали код в файле uhttpd (надо писать не в конец файла, а в конец первого блока)
- По каким-то причинам выставлены не те права доступа на папку test, они должны быть 755 (можно задавать в том же WinSCP либо через терминал)
Поздравляю, PHP успешно установлено и функционирует на вашей омеге. Теперь переходим к практическому применению.
4. Управляем светодиодом через PHP
Для начала соберем супер сложнейшую схему:
Как видите, плюс светодиода подключили на первый GPIO-контакт Omega 2, а минус на землю (GND). Соответственно включать/выключать светодиод мы будем устанавливая логические 0 и 1 на первом пине омеги.
4.1 Создаем Python файл для вкл/выкл светодиода
Если вы ранее не устанавливали питоновский интерпретатор, то сделайте это последовательно введя 3 команды в консоль (посмотреть установленные пакеты можно командой opkg list-installed):
opkg update opkg install python opkg install pyOnionGpio
Заходим в папку /root и в ней создаем файл text.py. Пишем в него следующий код:
import onionGpio # define pins PIN_NUMBER = 1 # define states ON = 1 OFF = 0 # instantiate gpio objects NASH_PIN = onionGpio.OnionGpio(PIN_NUMBER) # initialize to output status = int(NASH_PIN.getValue()) NASH_PIN.setOutputDirection(status) # body if status == 1: status = OFF else: status = ON NASH_PIN.setValue(status) print "LED Status = "+str(status)
Сохраняем файл.
Краткое описание кода: подключаем библиотеку onionGpio, затем устанавливаем 3 константы (номер пина и статусы ON, OFF), обзываем объект третьего пина как NASH_PIN, считываем уровень третьего пина, указываем OUTPUT направление третьего пина (в скобках указано значение по-умолчанию, если не указать будет ошибка). Ну и на последок узнаем статус пина (0 или 1) и устанавливаем обратное.
Распространенные ошибки:
- Иногда требуется добавлять str() и int(), чтобы преобразовать переменные в текстовые и числовые. Если это не сделать, в чем ошибка, иногда можно не понять.
- В языке Python условия и циклы создаются не с помощью символов { } или begin end, а с помощью равных отступов, то есть если внутри IF’а будет одна строка с отступом в 4 пробела, а другая в 1 таб (что визуально выглядит одинаково), то условие работать не будет.
Чтобы проверить код, открываем консоль и пишем:
python /root/test.py
Должно получиться так:
4.2 Создаем HTML и PHP файлы
Отлично, научились включать светодиод скриптом. Теперь открываем папку /www и создаем там 2 файла go.html – по сути оболочка, и knopka.php – файл, который будет связывать «оболочку» и файл test.py. Сразу скажу, что в JavaScript я не силен, поэтому заимствовал код с просторов интернета и подкорректировал под свои нужды.
Содержимое go.html:
<title>Omega2 Control</title> <script type="text/javascript"> function getXmlHttpRequestObject() // функция создания нового объекта XMLHttpRequest { var x; if (window.XMLHttpRequest) // мы в нормальном браузере? { // если в нормальном (IE7+, Firefox,Chrome, Opera, Safari) - создаём объект x=new XMLHttpRequest(); // создаём объект XMLHttpRequest } else x=false; // если в ненормальном - болт return x; // возвращаем указатель на созданный объект } // глобальные переменные var top_http; // здесь будем хранить указатель на объект XMLHttpRequest var stat; // эта переменная нужна чтобы опознать, что ответ получен и обработан var elements_col; // количество переменных, которые мы будем запрашивать/получать function handleTop() // обработчик ответа сервера { if(top_http.readyState == 4) // если запрос выполнен (4 - состояние complete) { if(top_http.status == 200) // если статус ответа - 200 ( Ok! ) { var value = top_http.responseText; // получаем в переменную текст ответа var ArrVal=value.split(';'); // разделяем ответ на массив параметров (параметры пришли через var obj_tag; // здесь будет указатель на контейнер var i=0; // это просто счётчик elements_col=ArrVal[0]; // количество элементов, которые нужно обработать // первый переданный элемент - это общее кол-во параметров // (пар id/значение), а далее сами пары id/значение while(i<elements_col) { // проверяем, есть ли на странице контейнер с нужным id? obj_tag=document.getElementById(ArrVal[2*i+1]); if(obj_tag) // если есть { // меняем текст внутри него на принятый от сервера obj_tag.innerHTML = ArrVal[2*i+2]; } i=i+1; // проверяем следующий элемент } stat=1; // меняем статус (1 - ответ получен и обработан) } } } function sendTop() // В этой функции мы формируем запрос и отправляем его на сервер { stat=0; // сбрасываем статус (0 - ответ не получен и не обработан) top_http = getXmlHttpRequestObject(); // вызываем функцию создания объекта XMLHttpRequest top_http.onreadystatechange = handleTop;// цепляем на onreadystatechange обработчик ответа // (когда он придёт - автоматически запустится функция handle_top) var url='/knopka.php'; // строка запроса (запустить на сервере файл /knopka.php) top_http.open('GET', url, true); // настраиваем асинхронный запрос с адресом url // (это url от корня того сервера, с которого загружена страница) top_http.setRequestHeader('If-Modified-Since','0'); // добавляем заголовки top_http.setRequestHeader('Cache-Control','no-cache'); top_http.send(null); // отправляем пустой запрос (поскольку у GET запроса // нет тела, всё, что нужно, - запихано в url) } </script> <!-- добавим глобальный стиль для таблиц и для кнопок --> <style type="text/css"> td { border: 1px solid blue; padding: 10px; } td.button { background-color: #CF12F1; box-shadow: 0 -3px #35A76E inset; } td.button:hover { background-color: #35A76E; } td.button:active { background-color: #21935A; box-shadow: 0 3px #21935A inset; } </style> <table style="border: 1px solid blue"> <tbody> <tr> <td class="button" onclick="sendTop()">Omega2 LED Click</td> <td id="result"></td> </tr> </tbody> </table>
Содержимое knopka.php:
<?php $result = shell_exec('python /root/test.py'); $answer = "1;result;".$result; // записываем в переменную строку ответа echo $answer; // вывод ответа (он будет отправлен обратно на страницу, с которой вызван скрипт) ?>
Сохраняем файлы.
5. Запуск!
Теперь открываем браузер, переходим по адресу http://192.168.3.1/go.html и молимся
После нажатия кнопки должно получиться так:
Таким образом, go.html при нажатии кнопки вызывает knopka.php, а та в свою очередь инициализирует запуск test.py, получает от нее ответ и передает его обратно в go.html (текст “LED Status = …”).
Для закрепления результата еще приконектился с телефона:
На этом все! Надеюсь у вас все получилось!
- Read more...
- 0 comments
- 2037 views