image

Именно столько стоит WiFi реле SONOFF (от компании ITEAD) которое являеться сердцем данного устройства.

«У меня не было неудач. Я всего лишь нашёл 10 тысяч способов, которые не работают» — Томас Альва Эдисон.

Это невероятно, еще не в таком далеком прошлом люди в школах перьями писали. А сегодня у каждого в кармане есть волшебный кирпич с картинками, который позволяет получить доступ к информации со всего мира. Отправлять мгновенные сообщения любому человеку на планете. У нас есть голосовое управление, распознавание лиц и, как люди говорят, угроза всему человечеству со стороны искусственного интеллекта. Совсем недавно эти технологии казались невообразимой фантастикой. Однако сегдня я вам покажу как, имея базовые навыки программирования, абсолютно каждый может использовать голосовое управление. Итак, давайте начнем!

ВНИМАНИЕ!!! Работа с высоким напряжением. Будьте осторожны во всем, что вы делаете! Автор статьи не несет ответственности за совершаемые Вами действия и любой материальный или физический ущерб, который может возникнуть в результате использования информации из этой статьи! Если Вы в чем-то не уверены, попросите Вам помочь более опытного человека.

Главная схема работы устройства.

image

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

1 — нам необходимо перепрограммировать WiFi реле Sonoff


Для этого необходимо разобрать реле и припаять к нему контакты для перепрошивки. По умолчанию он настроен на работу через китайский сервер. Лично мне не шибко понятно почему лампочку в туалете необходимо включать аж через сервер из Поднебесной.

image


image


Теперь мы можем подключить модуль cp2102 от Silicon Labs для перепрошивки Sonoff. Я его еще использую для работы с arduino mini.

image

image

ПРЕДУПРЕЖДЕНИЕ!!! При перепрограммировании не подключайте WiFi реле к сети 220/110 вольт!

Перепрограммировать реле очень просто. Это обычный модуль esp8266. Я взял стандартный скетч сервера точки доступа из Arduino IDE и немного его изменил.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
 
// name and password from WiFi network
const char* ssid = "Your access point (router) name";
const char* password = "router password";


IPAddress ip(192,168,1,112); // enter static ip
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

 
// Создаем сервер и порт для прослушки 80
 
WiFiServer server(80);
 
void setup() {
 Serial.begin(115200);
 delay(100);
 
 //preparing GPIO

 pinMode(12, OUTPUT);
 digitalWrite(12, 1);

 pinMode(13, OUTPUT);
 digitalWrite(13, 1);


 
 // connecting to WiFi
 Serial.println();
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);
 WiFi.begin(ssid, password);
 WiFi.config(ip, gateway, subnet);
 
 // waiting for connection
 while (WiFi.status() != WL_CONNECTED) {
 delay(500);
 Serial.print(".");
 }
 Serial.println("");
 Serial.println("WiFi connected");
 
 // run server
 server.begin();
 Serial.println("Server started");
 
 // show ip
 Serial.println(WiFi.localIP());
}
 
void loop() {
 
 // connection check
 WiFiClient client = server.available();
 if (!client) {
 return;
 }
 
 // Waiting for data
 Serial.println("new client");
 while (!client.available()) {
 delay(1);
 }
 
 // Reading the first line of the query
 String req = client.readStringUntil('\r');
 Serial.println(req);
 client.flush();

 // works with GPIO
 if (req.indexOf("/12/0") != -1)
 digitalWrite(12, 0);
 else if (req.indexOf("/12/1") != -1){
 digitalWrite(12, 1);
 Serial.println("TEST OK");
 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nTest OK. Uptime: ";


 // UpTime
 int Sec = (millis() / 1000UL) % 60;
 int Min = ((millis() / 1000UL) / 60UL) % 60;
 int Hours = ((millis() / 1000UL) / 3600UL) % 24;
 int Day = ((millis() / 1000UL) / 3600UL / 24UL);
 s += Day;
 s += "d ";
 s += Hours;
 s += ":";
 s += Min;
 s += ":";
 s += Sec;
 s += "</html>\n";
 client.print(s);
 client.stop();
 return;
 }
 else
 // If an invalid query write error
 {
 Serial.println("invalid request");
 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nInvalid request";
 s += "</html>\n";
 client.print(s);
 client.stop();
 return;
 }
 
 client.flush();
 
 
 // Response formation
 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO set OK";
 s += "</html>\n";
 
 // Send the response to the client
 client.print(s);
 delay(1);
 Serial.println("Client disonnected");
 
}


Вам нужно будет указать название вашей точки доступа (маршрутизатора/роутера), пароль и статический IP-адрес для лампочки. Управление реле находится на выводе 12. Обязательно установите размер флэш-памяти на 1 МБ в IDE.

Нажмите и удерживайте кнопку на плате Sonoff. Вставьте конвертер cp2102 USB в компьютер (удерживая нажатой кнопку). Через 2–3 секунды отпустите кнопку. Теперь реле в режиме программирования. Загрузите файл скетча из Arduino IDE. Нажмите на Подтвердить / Компилировать. После того, как вы его перепрограммируете, перезагрузите модуль.

2 — теперь давайте создадим мобильное приложение, чтобы управлять этим реле через Wi-Fi. (Android)


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

// Main code to start speech recognition.
// You can put it's execution, on some button in your app.

Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak please");
startActivityForResult(speechIntent, RESULT_SPEECH_TO_TEXT);


// Then on onAcivityResult we will get result
@Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == RESULT_SPEECH_TO_TEXT && resultCode == RESULT_OK) {

  ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

        if (!matches.isEmpty()) {

                String result_recognition_string = matches.get(0);

          // convert to lower case, since google speech recognition
          // returns "different" results. For example: youtube defines as YouTube
            result_recognition_string = result_recognition_string.toLowerCase(Locale.getDefault());

          if (result_recognition_string.contains("lamp on") ) {
			// lamp on 
			new LightOn().execute();
                }
             }
    }
}

Затем вы можете сравнить его с командами, которые вы хотите реализовать.

Это код для работы с Wi-Fi. Отправка сообщения на сервер.

public class LightOn extends AsyncTask<Void,Void,Void> {

    private static final String LOG_TAG = "MyLog";

    @Override
    protected Void doInBackground(Void... params) {

        URL url;
        HttpURLConnection urlConnection = null;
        try {
            url = new URL("http://192.168.1.112/12/1"); // "0" to turn off 

            urlConnection = (HttpURLConnection) url
                    .openConnection();

            InputStream in = urlConnection.getInputStream();

            InputStreamReader isw = new InputStreamReader(in);

            int data = isw.read();
            while (data != -1) {
                char current = (char) data;
                data = isw.read();
                System.out.print(current);
                Log.e(LOG_TAG, "Reply from server - " + current);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }

        return null;
    }
}

// run it
new LightOn().execute();

Это очень просто. «1» включить лампочку, «0» выключить лампочку. Вы можете добавлять по желанию любые проверки, получать ответ от сервера и тд. тп. Я для себя создал две программы. Первая — это виджет голосового управления, который находится на рабочем столе и всегда под рукой. Вторая — это простое приложение для включения / выключения лампочки нажатием кнопки.

image

Предполагаю, что вы уже устали читать всевозможные тексты, поэтому предлагаю вам узреть видео о том, как это было.


Как сказал Альберт Эйнштейн: «ваши возможности ограничены только вашим воображением».

Желаю хорошего Вам дня и только умных устройств!

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


  1. Sound_cULT
    13.12.2018 01:31
    +1

    Отличная идея, нетривиальная реализация.


  1. firk
    13.12.2018 02:36

    Лампа не деревянная.
    Управление (железо) не DIY.
    Вся идея в целом нелепа и является надругательством над целесообразностью.

    Краткая суть статьи: плату «умного реле» запихали в деревянную коробку и подключили к нему лампочку. Зато пафоса выше крыши.


    1. o-pod
      13.12.2018 20:11

      Идея нелепа только если смотреть не дальше деревянной коробки.
      По мне так автор сделал прекрасный «Hello, world», который можно положить в основу для создания умного дома — т.е. управления фактически всеми электрическими устройствами с мобильного телефона!


      1. firk
        14.12.2018 02:49

        Ну, если б статья называлась «переделываем китайское умное реле новой прошивкой и пишем к нему голосовое управление со смартфона» (т.е. чисто софтовая задача) — претензий бы не было (хотя скорее всего я б не стал её читать даже). Тут же претензия (уже со стороны автора статьи всмысле) на нечто большее.

        Т.к. у меня лимит на 1 сообщение в сутки то отвечу тут и Mobile1
        Под DIY подразумевается обычно железо, а в случае в софтом это называется «программированием», про которое и так половина хабра безо всяких спец. меток.


    1. Mobile1
      13.12.2018 21:21

      Вообще сам Sonoff из коробки поддерживает и Alexa Echo и Google Асистант.
      Т.е. для того чтобы включать и выключать голосом лампочку вообще ничего ни делать, ни программировать не надо — это стандартная процедура для железки.

      Поэтому то что описал автор, как раз самое настоящее DIY — несмотря на то что уже есть голосовое управление, он взял и сделал его по своему — это заслуживает уважения.


  1. Dioxin
    13.12.2018 07:19

    Hello, world


  1. sainomori
    13.12.2018 08:44
    +1

    Позвольте позанудствовать.
    Знак доллара ставится перед суммой — $5


    1. mistergrim
      13.12.2018 15:13

      Нет такого правила.

      Ещё вот Тёма пишет (и тут я с ним совершенно согласен):

      Как бы соблазнительно ни выглядел доллар слева от суммы, писать его в русских текстах можно только справа. (Исключение могут составлять финансовые и биржевые тексты, но это отраслевой стандарт, который не может распространяться на остальные области.)

      В русском языке единица измерения, стоящая перед значением, означает примерно столько: «долларов сто». А не писать пробел перед знаком доллара, это все равно что писать 50руб. Так себе может позволить упражняться в типографике только продавщица продмага с трафаретом и шариковой ручкой. (Исключение тут составляют финансовые документы, где отсутствие пробела страхует от приписки лишних цифр.)


      1. BalinTomsk
        13.12.2018 22:45

        ---писать его в русских текстах можно только справа.

        Не можно справа, а нужно слева, ибо справа пишут тип валюты: $5 USD.


  1. Vlad_fox
    13.12.2018 11:51

    «У меня не было неудач. Я всего лишь нашёл 10 тысяч способов, которые не работают»

    Рецепт успеха от Эдисона — У меня не было не успешных попыток. Я всего лишь сделал 10 тысяч попыток, которые не принесли успеха.


  1. rvbglas
    13.12.2018 12:06

    Может, кому пригодится, чтоб на каждый случай новую прошивку не плодить: github.com/arendst/Sonoff-Tasmota


  1. aivs
    14.12.2018 00:34

    Мне нравится!
    А о лобзике вообще давно мечтаю