IoT за копейки: делаем устройство с веб-интерфейсом

в 16:05, , рубрики: cloud, dataart.интернет вещей, devicehive, DIY, diy или сделай сам, esp8266, IoT, Блог компании DataArt, Интернет вещей

IoT за копейки: делаем устройство с веб-интерфейсом - 1
Автор: Николай Хабаров, Senior Embedded Developer, DataArt

В этой статье мы расскажем, как создать собственное устройство с веб-интерфейсом в домашней сети, используя новейшую версию 0.5 прошивки DeviceHive для микросхемы ESP8266. Но для начала, давайте разберем, что нового появилось в самой прошивке: основные нововведения связаны с возможностью автономной работы в локальной сети.

IoT за копейки: делаем устройство с веб-интерфейсом - 2

Предыдущие статьи цикла:

IoT за копейки, или Что может DeviceHive.
IoT за копейки: практическое руководство. Часть 1-я, аппаратная.
Беспроводная настройка ESP8266 в прошивке DeviceHive v 0.3.
IoT за копейки: практическое руководство. Часть 2, софтварная.

Отличные новости — у нас обновилась прошивка DeviceHive для ESP8266 до версии 0.5. Для тех, кто подзабыл или не знал совсем, напоминаю, эта прошивка является реализацией подключения к серверу DeviceHive внутри микросхемы ESP8266. Новые возможности прошивки позволяют работать чипу в локальной сети в качестве оконечного устройства с собственным веб-интерфейсом. При этом вам необязательно использовать сервер даже для размещения веб-страницы, хотя весь функционал подключения к удаленному серверу сохранен и может быть использован совместно с локальным решением.

Скачать последнюю версию прошивки, как всегда, можно на GitHub. Там же можно ознакомиться с исходными кодами прошивки.

Итак, что же у нас новенького.

1. Локальный RESTful API

Теперь на каждом чипе на 80 порту расположен простенький HTTP-сервер с RESTful API. Команды полностью повторяют облачные команды за исключением возможности использовать прерывания. С полным списком команд можно ознакомиться в этом документе. Например, если вы хотите узнать состояние всех выводов микросхемы, то нужно использовать команду 'gpio/read'. В случае клауда мы просто отправляли эту команду на сервер, а теперь мы можем попросту обратиться к локальному RESTful API по адресу 'http://device-id.local/api/gpio/read' и в ответ получим JSON, содержащий состояние всех выводов. Если на чипе не задан ключ доступа (AccessKey), то это можно сделать даже из браузера:

IoT за копейки: делаем устройство с веб-интерфейсом - 3

Или с помощью утилиты curl.

curl -i -X POST  
    -H "Authorization: Bearer YourAccessKeyHere="  
    http://esp-demo.local/api/gpio/read

При наличии ключа доступа, он должен быть передан в HTTP-заголовке. Ключ используется как для авторизации на облачном сервере, так и для локальной работы. Для локального использования ключ следует трактовать как простую строку, т. е. пароль. Метод может быть как GET, так и POST — на функционал команд это не влияет. Команда передается в адресе запроса, а параметры, при их наличии, в теле запроса в виде JSON.

2. mDNS

Вы, наверное, заметили, что в примере выше используется доменное имя esp-demo.local. Теперь на чипе реализован Multicast Domain Name System, и все устройства, поддерживающие mDNS в пределах локальной сети, могут резолвить доменные имена в IP-адреса. Более того, имеется возможность обнаруживать все устройства в пределах сети, при этом локальный DNS-сервер не требуется.

mDNS работает по протоколу, полностью повторяющему классический DNS, но запросы отправляются по UDP на широковещательный адрес. Устройства слушают тот же широковещательный адрес и отвечают на запросы самостоятельно. В качестве доменного имени используется DeviceId чипа (который конфигурируется во время настройки прошивки). Полное доменное имя будет выглядеть как DeviceId.local.

Существует RFC6763, описывающий процедуру обнаружения сервисов, в том числе внутри mDNS. Это можно использовать для обнаружения чипов с нашей прошивкой. Существует множество утилит и библиотек, реализующих обнаружение сервисов с помощью mDNS. Например, вот так будет выглядеть чип с DeviceId 'esp-demo', обнаруженный утилитой 'avahi-discovery':

IoT за копейки: делаем устройство с веб-интерфейсом - 4

Некоторые современные операционные системы умеют резолвить такие доменные имена из любого приложения, например, из браузера. Некоторым нужно будет доустановить специализированный софт.

3. Поддержка популярных датчиков

Раньше для работы с датчиками требовалось реализовать протокол общения самого датчика. Теперь в список команд включена поддержка чтения данных с популярных датчиков одной командой. Например, чтобы получить температуру с датчика DS18B20, нужно в начале инициализировать процедуру измерения температуры, выждать, пока измерение закончится, и считать результат. И это далеко не самая сложная из возможных процедур. Теперь для того чтобы узнать температуру у датчика достаточно просто отправить команду 'devices/ds18b20/read' и в ответ получить JSON вида '{«temperature»:24.5000}'. Полный список поддерживаемых датчиков смотрите в списке команд.

Пример вывода данных с MPU-6050(акселерометр, гироскоп, плюс на чипе есть датчик температуры):

IoT за копейки: делаем устройство с веб-интерфейсом - 5

4. Локальный веб-сервер

Раз у нас есть RESTful API на HTTP-сервере, то почему бы ему не отдавать просто веб-страницы. И, конечно, он это умеет. После установки прошивки на чип, откройте в браузере 'http://deviceid.local/', и вы увидите веб-интерфейс чипа. По умолчанию он содержит небольшую справку по использованию прошивки, инструменты для работы с локальным RESTful API (страницу, на которой можно попробовать вызывать различные команды и конвертер base64), несколько примеров веб-страниц, использующих RESTful API (вы можете посмотреть исходные коды страниц прямо из браузера) и пока совсем простенький, но текстовый редактор веб-страницы. С помощью этого редактора можно изменить главную страницу чипа на любой ваш собственный код прямо из браузера. Размер страницы ограничен 64КиБ.

Вы можете разместить на чипе страницу наподобие встроенных примеров, которая будет реализовывать на JavaScript какие-либо операции с чипом и отображать их пользователю в веб-браузере. Более того, никто не запрещает с одной и той же страницы обращаться ко всем чипам в пределах локальной сети.

IoT за копейки: делаем устройство с веб-интерфейсом - 6

Практическая часть

А теперь давайте подключим датчик температуры DS18B20 и оснастим его веб-интерфейсом. Датчик должен быть запитан от выводов GND и 3V3 и подключен к какому-нибудь GPIO-выводу. Прямо рядом с выводами питания есть GPIO2, давайте используем его. Подключение может быть выполнено следующим образом:

IoT за копейки: делаем устройство с веб-интерфейсом - 7

На фото один из популярных вариантов реализации платы разработчика для ESP8266, которая сразу включает в себя блок питания от microUSB, переходник USB-TTL. Это очень удобно. Используя такую плату, даже не нужно зажимать никакие выводы при прошивке, последняя версия флешера прошивки все сделает сама. Достаточно просто подключить Micro-USB и запустить утилиту. Отметим, что розничная стоимость таких плат для разработчиков на китайских торговых площадках с учетом доставки опустилась до 3-4 долларов.

Но вернемся к веб-интерфейсу. На самом чипе уже есть веб-страница с примером использования DS18B20. Она располагается по адресу 'http://deviceid.local/ds18b20.html'. Откроем её, введем при необходимости ключ доступа и увидим температуру, которая считывается с датчика:

IoT за копейки: делаем устройство с веб-интерфейсом - 8

Исходный код страницы можете посмотреть прямо в браузере. Если вам не нравится оформление, хочется отображения данных с нескольких датчиков, или вам нужно подключить какой-либо другой датчик, вы можете сделать и загрузить на чип свою веб-страницу, как мы описывали выше.

Например, давайте сделаем простую веб-страницу, которая будет управлять подключенным реле.

Код будет выглядеть следующим образом.

<html>
 <head>
 <script type="text/javascript">
    function send(onOff) {
      localStorage['accesskey'] = document.getElementById('accesskey').value;
      var xmlhttp = new XMLHttpRequest();  
      xmlhttp.open('POST', "http://" + window.location.hostname + '/api/gpio/write', true);
      xmlhttp.setRequestHeader("Authorization", "Bearer " + localStorage['accesskey']);
      xmlhttp.onreadystatechange = function() {
        if(xmlhttp.readyState == 4){
          if(xmlhttp.status < 200 || xmlhttp.status > 299) {
            alert('ERROR: Command return ' + xmlhttp.status + ' ' + xmlhttp.responseText, true);
          }
        }
      }
     var json = {}
     json["5"] = onOff ? 1 : 0;
     xmlhttp.send(JSON.stringify(json));
   }
   function init() {
     document.getElementById('accesskey').value = localStorage['accesskey'];
   }
 </script>
 </head>
 <body onload="init()">
  <label>AccesKey: </label><input type="password" id="accesskey"><br><br>
  <input type="button" value="On" onclick="send(true);">   <input type="button" value="Off" onclick="send(false);">
 </body>
</html>

Данный код, используя localStorage, хранит ключ доступа к чипу, чтобы его не пришлось вводить каждый раз. При нажатии на кнопки включения/выключения вызывается XMLHttpRequest(), которая отправляет запрос на локальный RESTful API.
Теперь загрузим эту страницу на чип. Подключим твердотельное реле SSR-40DA, с помощью которого будем включать электродвигатель, запитываемый от переменного напряжения 220 Вольт, т. е. от розетки. Естественно, вместо электромотора можно подключить другую нагрузку, такое реле выдерживает до 40 Ампер. На видео вы можете посмотреть, как подключить такое реле и как оно включает электромотор:

На этом все, спасибо всем за внимание. Любая критика и пожелания только приветствуются, пишите!

Автор: DataArt

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js