Google Assistant switches Sonoff S20

Build a setup where Google Assistant switches Sonoff S20. Switch your light on/off using your voice and the help of Google Assistant. Sure, you can run to the store and purchase a preconfigured light switch, but what’s the fun in that and more importantly these switches with their close-source software require access to your home network.

Achieving this simple level of automation took more doing than I expected. By sharing my notes, I hope you can clear the hurdles with ease.

Goal

Simplified flow diagram
Triggered with the phrase “Hey Google”, the Google Assistant is able to feed the words that follow into its database of applets, one of which we will create. Once the applet recognizes the instruction, it sends a command towards our Sonoff smart outlet. Details of this conversation are something like the one shown in the diagram below.

Design

We use a $10 Sonoff smart outlet and change the firmware so it can be controlled using MQTT. To connect Google Assistant to MQTT, we use Kappelt’s gBridge.

Sonoff S20

Required hardware:

  • Google Assistant enabled device, such as a Google Home or Android Phone.
  • Sonoff S20 smart outlet connected to e.g. a lamp (any model supported by Tasmota will do),
  • a router that can serve as a reverse proxy such as DD-WRT,
  • a lightweight computer such as the Raspberry Pi 3.

Data flow diagram (click to enlarge)

Implementation

We will work our way up starting with the Smart Switch all the way to Google Assistant.

Make Sonoff S20 respond to messages (Tasmota)

The key ingredient of making the Sonoff S20 work with Google Assistant is the MQTT protocol. The abbreviation MQTT stands for Message Queue Telemetry Transport, where the keyword is telemetry, or remote monitoring. By creating topics, you can enable different parts of your application to subscribe to specific streams of data. The Tasmota firmware includes this MQTT protocol.

Tasmato message flow

The process of flashing new firmware is described in videos such on youtube.com and Theo Arend’s Wiki. In turn, my short summary:

Flash the firmware

Here we use the Python based flash tool.

Sonoff S20, FTDI Friend, lab power supply

Follow the steps below.

  1. Make sure Python 2.7 is installed on your computer
  2. Flash tool
    • Download esptool and expand the archive.
    • Install the dependencies: python setup.py install
  3. Connect serial port
    • Unplug the Sonoff S20 from the outlet, take the cover off and connect it to your computer using a USB/Serial adapter. Make sure the USB/Serial adapter can supply enough current to the ESP SoC.
    • Note the serial port that was your operating system assigned (e.g. COM10).
    • Counterintuitive, I had to connect RX-RX and TX-TX.
  4. Tasmota firmware
    • Download the Tasmota firmware sonoff.bin
    • Put the Sonoff S20 in flash mode by holding down the push button while connecting the serial port (and hence its power supply).
    • Clear the flash on the Sonoff S20: esptool.py --port COM10 erase_flash
    • Put the Sonoff S20 back in flash mode.
    • Flash the firmware: esptool.py --port COM10 write_flash -fs 1MB -fm dout 0x0 sonoff.bin
    • Disconnect and reassemble the Sonoff S20.

Boot

The Wifi Credentials for the Tasmota firmware are configured by putting it in Access Point mode.

  1. Plug it into the wall and press its button 5 times.
  2. On a mobile device, connect to ESP_xxxx via WiFi. Make sure the device stays connected (some will auto-connect to a different network if no internet connection is detected).
  3. Configure the Sonoff S20 by connecting to its AP WiFi Network, and use a browser to connect to http://192.168.4.1
  4. Setup the Sonoff S20 by scanning for Wifi networks, and configuring its credentials. While you are at it, set the hostname (e.g. sonoff-socket1). Save and wait for it to reboot.
  5. Connect your mobile device back to your regular WiFi network.

Configure

By now the Sonoff S20 should have connected to your WiFi. We connect to its web interface and finish the configuration.

  1. Open your browser at the IP name/address assigned, http://sonoff-socket1
  2. Test by pressing Toggle what should switch the relay on/off.
  3. Configure module
    • Configuration > Configure Module > Module type = Sonoff S2X
    • Save and wait for reboot
  4. Configure MQTT
    • host = IP name/address of your Raspberry Pi
    • port = 1883
    • topic = sonoff/socket1
    • full topic = %prefix%/%topic%/
    • Save and wait for reboot
  5. MQTT Message Broker (Mosquitto)

    As mentioned before, the key protocol is MQTT. In this example, the message runs on a Raspberry Pi on our LAN).

    Mosquitto message flow

    To start, install the Eclipse Mosquitto implementation:

    sudo apt update
    sudo apt install -y mosquitto mosquitto-clients
    sudo systemctl enable mosquitto.service
    sudo systemctl start mosquitto.service
    netstat -lt  # ensure it listens on port 1883

    Test to see if the MQTT broker is listening on port 1883, using netstat -lt. When you listen to all topics (mosquitto_sub -t '#' -v), you should see a periodic status report from the Sonoff S20, such as tele/sonoff/socket1/LWT Online.

    Control the relay on the Sonoff S20, by publishing values to the topic cmnd/sonoff/socket1/power

    • mosquitto_pub -t 'cmnd/sonoff/socket1/power' -m 1
    • mosquitto_pub -t 'cmnd/sonoff/socket1/power' -m 0

    At this point the roads diverge. The straight and easy path uses the hosted service gbridge.io. You would continue with their Getting Started guide and be done. The other choice is to host the MQTT/Assistant bridge yourself as described in the remainder of this document.

    This other path is windy but might be more interesting. It involves hosting the MQTT/Assistant bridge. This approach is loosely based on Self-Hosted gBridge, with various changes based on e.g. community contributions. Without further adieu, the self-hosted bridge is described in the remainder of this document and requires:

    • A router you have control over, and can function as a reverse proxy (e.g. DD-WRT).
    • A public domain name for your router
    • An SSL certificate for the router (e.g. LetsEncrypt)
    • A computer that is always on (e.g. Raspberry Pi 3)

    Traversing the Router

    Google Assistant accesses our MQTT server through our router using HTTPS. This router therefore must have a public DNS name and a certificate for HTTPS and support reverse proxy. The reverse proxy translates between Google Assistant’s HTTPS and HTTP on our LAN. Instead of the reverse proxy, it might be possible to forward specific ports and do the HTTPS/HTTP conversion on the Raspberry Pi.

    Router message flow

    For this example, we assume a router with DD-WRT firmware that includes dnsmasq and pound.

    Public DNS name

    Start by giving your router a public DNS name. Google Assistant uses this name when sending commands towards our MQTT server. In this example, we make a subdomain under an existing web domain. Another approach would be to use a DDNS service.

    At your DNS provider, use their DNS Zone Editor to add the subdomain mqtt

    mqtt.domainname.com 1440 IN A your_rtr_public_ip_addr
    This may take up to 72 hours to propagate. If you haven’t done so already, convert your domain’s certificate to a wildcard certificate and download it. The wild card certificate can be used for of your subdomains.

    Certificate for HTTPS

    For Google Assistant to be able verify the identity of your MQTT server we need to install the wildcard certificate that we downloaded in the previous step. Concatenate the private key, certificate and CA certificate into /jffs/etc/pound/yourdomain.pem

    Reverse proxy

    As said, the reverse proxy translates between Google Assistant’s HTTPS and HTTP on our LAN. This way only your router needs to understand HTTPS. We will configure it so, that when the router receives an HTTPS (or HTTP) request for URL https://mqtt.yourdomain.com/gapi, it will forward it as HTTP to the Raspberry Pi.

    For the reverse proxy we’ll loosely follow DD-WRT Reverse Proxy and HTTPS.

    To get up and running, we need the binaries, a script that starts it and configuration files. These files are available through this GitHub page. The scripts are based on Frater’s post.

    1. Enable JFFS partition. From the router’s GUI, enable JFFS (Administration » Management). On first use, check the box to “clean internal flash storage”. Reboot as needed.
    2. Configure DNSMasq on your router, to always give the same name and IP address (based on MAC) to the Sonoff S20 and Raspberry Pi. This example assume these names are sonoff-socket1 and mqtt.
    3. Pound binaries. Our router’s firmware didn’t include pound binaries, so we copied it from an older firmware (kongac’s r33010M)
      scp rtr2:/usr/sbin/pound rtr2:usr/sbin/poundctl /jffs/sbin/
      scp rtr2:/usr/lib/libssl.so.1.0.0 rtr2:/usr/lib/libcrypto.so.1.0.0 /jffs/lib
    4. Install startup script. Copy the script /jffs/sbin/pound.sh and its helper write_pound_cfg from GitHub.
    5. Configure ports to listen on. The file /jffs/etc/pound/pound.pt1 specifies what ports to listen at. The example below uses port 80 and 443, so make sure they are not already in use for the DD-WRT UI (change dd-wrt web admin port).
      TimeOut         120
      Alive           30
      Control         "/tmp/pound.ctl"
      
      ListenHTTPS
              Address 0.0.0.0
              Port 443
              xHTTP 1
              Cert "/jffs/etc/pound/yourdomain.pem"
    6. Configure forward rules. The file /jffs/etc/pound/pound.pt2 specifies where to forward the HTTP request to.
      Service "mqtt"
                      HeadRequire "Host:.mqtt.yourdomain.com.*"
                      Url "/gapi.*"
                      BackEnd
                              Address ip_address_of_your_rpi
                              Port 8080
                      End
              End
      End
      ListenHTTP
              Address 0.0.0.0
              Port 80
              xHTTP 1
              Service "mqtt"
                      HeadRequire "Host:.mqtt.yourdomain.com.*"
                      Url "/gapi.*"
                      BackEnd
                              Address ip_address_of_your_rpi
                              Port 8080
                      End
              End
      End
    7. Start pound using /jffs/sbin/pound.sh start
    8. Pointing a web browser to either
      • https://mqtt.yourdomainhome.com/gapi
      • http://mqtt.yourdomainhome.com/gapi
      Since we haven’t setup the HTTP/MQTT bridging software, you will not get the page requested. The name should however resolve and eventually you’ll get The service is not available. Please try again later.

    Adding a skill to Google Assistant

    Before we can setup the HTTP/MQTT bridge, we need to generate some identifiers on Google Cloud. To do so, we roughly follow the guide from Kappelt’s Self-Hosted gBridge.

    Google Assistant message flow

    To get started, head over Google Actions Console using the same account that you use for Google Home.

      • Project name = gBridge
      • Development experience = Smart Home » Smart Home
      • Name your Smart Home action
        • Display name = whatever it accepts is fine. Save
        • Return to previous web page
      • Setup account linking
        • No, I only want to allow account creation on my website Next
        • Linking type = OAuth, Implicit Next
      • OAuth Client Information
        • Client ID issued by your Action to Google = any random id that you generate, write down this Account Linking Client ID
        • Authorization URL = https://mqtt.yourdomain.com/gapi/auth
      • Configure your client (optional)
        • Skip this Next
      • Testing instructions
        • Skip this Save
      • Add action
        • Fulfillment = https://mqtt.yourdomain.com/gapi Save
      • Set your Language

    Continue on Google Cloud with the following steps

      • Select your project (from the All list)
      • Project ID = write down this Google Project ID
      • + ENABLE APS AND SERVICES
      • HomeGraph API
      • ENABLE
      • Create credentials » API Key
      • Your API key = write down this HomeGraph API Hey

    Bridging Google Assistant and MQTT (gBridge)

    Time to install the MQTT/HTTP bridge. Here we use a self hosted Kappelt gBridge. This consist of docker packages that will run on the Raspberry Pi.

    gBridge message flow

    Start with installing Docker

    sudo apt-get install libffi-dev pwgen tzdata 
    sudo pip install docker-compose

    Create a /opt/gbridge/docker-compose.yum, substituting your own , , and .

    version: '3'
    networks:
        backend:
        driver: bridge
        web_frontend:
        driver: bridge
    services:
        database:
        image: 'yobasystems/alpine-mariadb:latest'
        restart: always
        environment:
            MYSQL_RANDOM_ROOT_PASSWORD: 'true'
            MYSQL_ROOT_PASSWORD: 
            MYSQL_DATABASE: gbridge_db
            MYSQL_USER: gbridge_db
            MYSQL_PASSWORD: 
        expose:
            - '3306'
        networks:
            - backend
        cache:
        image: 'redis:4'
        restart: always
        expose:
            - '6379'
        networks:
            - backend
        web:
        image: 'pkap/gbridge-web-nginx:arm32v6-latest'
        restart: always
        ports:
            - '8080:80'
            - '443:443'
        environment: &webapp-environment
            APP_ENV: production
            APP_KEY: 'base64:NTYyZWE3NThjZDYxNzM3Nzg2ZTM2MGQ3NDY5MjY0YTI='
            APP_DEBUG: 'false'
            APP_LOG_LEVEL: warning
            APP_URL: 'http://localhost'
            DB_CONNECTION: mysql
            DB_HOST: database
            DB_PORT: 3306
            DB_DATABASE: gbridge_db
            DB_USERNAME: gbridge_db
            DB_PASSWORD: 
            BROADCAST_DRIVER: log
            CACHE_DRIVER: file
            SESSION_DRIVER: file
            SESSION_LIFETIME: 120
            QUEUE_DRIVER: sync
            REDIS_HOST: cache
            REDIS_PASSWORD: 'null'
            REDIS_PORT: '6379'
            MAIL_DRIVER: smtp
            MAIL_HOST: ERROR
            MAIL_PORT: ERROR
            MAIL_USERNAME: ERROR
            MAIL_PASSWORD: ERROR
            MAIL_ENCRYPTION: ERROR
            GOOGLE_CLIENTID: 
            GOOGLE_PROJECTID: 
        links:
            - database
            - cache
            - web-fpm
        depends_on:
            - database
            - cache
            - web-fpm
        networks:
            - web_frontend
            - backend
        volumes:
            - websrc:/var/www
        web-fpm:
        image: pkap/gbridge-web-fpm:arm32v6-latest
        restart: always
        networks:
            - backend
        volumes:
            - websrc:/var/www
        environment: *webapp-environment
        redis-worker:
        image: 'pkap/gbridge-redis-worker:arm32v6-latest'
        restart: always
        environment:
            GBRIDGE_REDISWORKER_REDIS: 'redis://cache:6379'
            GBRIDGE_REDISWORKER_MQTT: 'mqtt://:1883'
            GBRIDGE_REDISWORKER_MQTTUSER: ""
            GBRIDGE_REDISWORKER_MQTTPASSWORD: ""
            GBRIDGE_REDISWORKER_HOMEGRAPHKEY: 
        networks:
            - backend
        links:
            - cache
        depends_on:
            - cache
    volumes:
        websrc:

    If you tried this before but failed, I suggest to start from scratch (per https://community.gbridge.io/t/nginx-config-for-rpi-self-hosted/115/11)

    sudo su
    cd /opt/gbridge
    docker-compose rm -f web redis-worker web-fpm database cache*
    docker volume rm gbridge_websrc
    reboot

    Continue with a clean slate
    sudo su
    cd /opt/gbridge
    docker system prune -a
    apt-get update
    apt-get upgrade

    Clear the cookies for the site in your browser (I found this the most common source of generic gBridge error messages in the browser)

    Bring up the containers docker-compose up : : database_1 | 2019-09-07 3:40:23 0 [Note] Reading of all Master_info entries succeeded database_1 | 2019-09-07 3:40:23 0 [Note] Added new Master_info ” to hash table database_1 | 2019-09-07 3:40:23 0 [Note] /usr/bin/mysqld: ready for connections. database_1 | Version: ‘10.3.17-MariaDB’ socket: ‘/run/mysqld/mysqld.sock’ port: 3306 MariaDB Server

    Meanwhile in a browser, access mqtt.vonk:8080/ should show the login page

    ^c out of docker-compose up, and instead start it detached using docker-compose up --detach

    Setup user and password using docker-compose exec web-fpm php artisan migrate. Should reply with a password and a bunch of Migrating *table messages.

    Login from browser, in my case at http://mqtt.vonk:8080 gives the login page. Login with and passwd 123456, don’t remember me.

      • Use a password with at least one number and at least one special char.
      • Create a device
        • Name = soft light
        • Device Type = Light
        • Traits = Select Supported Traits, On and Off
        • + Add

    MQTT forward

    The MQTT topics used by the Tasmota firmware and the gBridge don’t match. Solve this by

    • forwarding traffic for gBridge/u1/# to cmnd/, and
    • from stat/# to gBridge/u1/.
    here “gBridge/u1” is the the user id of your gBridge account as listed in the http://mqtt:8080/profile.

    Mosquitto message flow

    To do so, on the Raspberry Pi, create /etc/mosquitto/conf.d/gbridge.conf as

    connection gBridge
    address 127.0.0.1:1883
    topic cmnd/# in 0 "" gBridge/u1/
    topic stat/# out 0 "" gBridge/u1/
    Restart the MQTT services, sudo service mosquitto restart.

    Log the messages, mosquitto_sub -v -t '#'.

    Add the device to Google Home Hub

    The final step is done on a mobile device using the Google Home App.

      • Set up a new device.
        • Works with Google
        • Have something already set up?
        • Select the Google Display Name for your project (that is prefixed with [test]

Talk to your old CD player

Have you ever wondered why you should buy new devices just because the old ones don’t support IoT? Any device controlled by an infrared remote can be transferred into an IoT device with a Adafruit ESP8266, an infrared receiver and LED, and your remote control. With the help of an IR code library, I was able to make a program that does just that.

Triggered with the phrase “Hey Google”, the Google Assistant is able to feed the words following the trigger phrase into its database of applets, one of which is IFTTT. Once one of the applets recognizes the phrase, it responds with a statement showing that it has acknowledged the command. In this case the answer phrase is set by the user. The Google Assistant will respond by saying the term set in IFTTT. I set it to “IR Code Sent.” The conversation will be something like the one shown in the conversation above.

Problem analysis

Our goal is to teach the Google Assistant to control a device with an IR signal. In this case we use a Panasonic SC-HC20 CD player.

We need a device, controlled by Google Assistant that can mimic an infrared remote control. In this project we will try to build that device and hook it up to Google Assistant using IFTTT (If This Then That). We build this so people do not have to buy new devices just so they can be controlled by “smart” devices.

Design considerations

Considerations

We will give an overview of what we found and explain some of the trade-offs that we made.

Teaching Google Assistant skills

Adding Skills to the Google Assistant can be challenging, but IFTTT simplifies the process by setting up the api.ai (Google’s Voice Recognition Platform) part of the equation. This was normally the tricky part of teaching the Google Assistant, and IFTTT makes this much simpler. Now all we need to do is configure IFTTT and code the transmitting device.

  • If This Then That (IFTTT) adds custom voice commands to Google Assistant and can sent information to a device using HTTP
  • Actions on Google adds a dialog to Google Assistant and supports sending and reading information to/from devices.

Infrared Interface platform

We need to make a device that can accept commands over WiFi and relay them as infrared commands to the CD player.

  • Requirements: small, low power, WiFi, GPIO (general purpose i/o pins)
  • Contestants: Arduino, ESP8266, Arduino 101, ESP32
  • Winner: Adafruit Feather Huzzah ESP8266. 1 MByte flash enough for over the air updates. Micro USB for code upload / debugging.Y

Infrared Interface infrared codes

Our device needs to be able to mimic the remote as to control the CD player.

  • Requirements: must support the platform; it ideally should recognize the device codes so we don’t have to use raw IR timings.
  • Contestants: A fork from Chris Young’s IRlib;
  • Winner:A fork from Chris Young’s IRlib;

Traversing the WiFi router

The access router in our home is a jack-of-all-trades. Among its many duties it protects the home network from outside intruders. This comes with a catch: Google Assistant needs access to our home network to control the CD player. This means we need to provide a mechanism in which Google Assistant can contact the CD device.

Like with anything else on the internet, there are many choices to consider. The two trains of thought are:

  • Make an exception in the firewall to accept and forward incoming commands to the IR interface. We can also use this router to handle the more resource intense encryption and scrutinize the commands to prevent code injection. Problem is that anything on the internet can access our webserver, so we need an authentication mechanism. There are two protocols that come to mind: HTTP and MQTT. HTTP is the protocol that brings the web pages that you visit to you. We can use it to push messages from Google Assistant to our IR interface. The other protocol, MQTT, is designed to provide low latency, assured messaging over fragile networks and efficient distribution to one or many receivers. It is less known but powers Facebook, and is supported by AWS IoT.
  • Maintain a connection to a web service, so that it can send messages to the IR interface over that existing connection. When using the HTTP protocol, we need a kludges like long polling or websocket. A more elegant solution is Firebase Cloud messaging, but that requires a substantial amount of memory to handle HTTPS and identifiers. It appears to run on ESP8266. The memory is used for HTTPS, UID and authToken. Problem is that it causes a lot of idle traffic and requires an intermediate server (because IFTTT doesn’t support it directly).

IoT devices are characterized by a small processor, little memory and low power usage. In this respect MQTT would be ideal. However, this requires a bridge such as Ponte or web service to translate between HTTP and MQTT. Instead, we decided to go with the more common HTTPS protocol.

Design, development and unit testing

Data flow for Infrared Interface

The design consists of various blocks as illustrated below. We will describe the design, development and the unit testing for these blocks. We will start the Infrared Interface and work our way up to integrating it with the Google Assistant ecosystem.

All code is available through the repository:

Infrared Interface

We go straight to the exciting part: the infrared interface.

Data flow for Infrared Interface

Design

The hardware for this project is straightforward. The microcontroller is an ESP8266-based Feather HUZZAH that already has an USB interface for programming and debugging.

The software uses a framework that provides: online WiFi SSID/passwd configuration, saves fatal exception details to non-volatile memory and supports over-the-air (OTA) software updates.

Development

The ESP8266 is connected to an Infrared Receiver to decoding signals from the original remote control of the CD player. To send infrared codes to the CD player it uses a transistor to drive an IR LED.

Hardware

WiFi/IR interface schematic

Build the circuit as shown in the schematic above.

  1. Gather the parts shown in the table below. Be careful to use the PN2222A or 2N222A transistor (not the P2N2222A).
    Label Part# Description Information We paid
    IR1 Vishay TSOP38238 Infrared Receiver 38kHz datasheet $ 1.08
    D1 Everlight EL-SIR333-A Infrared Diode 875nm 1.5Vdrop datasheet $ 0.39
    T1 PN2222Atfr NPN Transistor datasheet $ 0.49
    PCB1 Feather HUZZAH ESP8266 Microcontroller board detail $ 16.95
    R1 1kΩ ¼W Resistor $ 0.02
    R2 68Ω ¼W Resistor $ 0.02
    Feather Proto board detail $ 4.95
  2. Assemble the circuit using a breadboard or prototyping board. The illustration below shows the pinouts.
    Semiconductor pinouts
  3. Test T1 and D1. Disconnect R1 from the ESP8266 module, and connect it to the 3.3V rail to verify that the voltage drop over R1 is approximately 3.4 V, indicating that the current through the infrared diode is 3.4V/68Ω=50mA. Reconnect the resistor to the ESP8266. Alternatively you can use camcorder to view the infrared light.
  4. Note that we used the 5 Volt rails (labeled USB to supply the Infrared LED with sufficient current.

We assemble it for prosperity on a prototyping board

Software

When IFTTT makes the web request via Webhooks, the host of the website, in this case an Adafruit Huzzah Feather ESP8266 receives the command, and checks the command against its list of valid commands. If the command checks out, then it is matched to the corresponding IR command. It then sends the value out to the CD player, which completes the action.

  1. Prepare your Arduino IDE or Microsoft Visual Studio environment. Install the board support and libraries listed in the table below.
    IDE, board support and external libraries
    Type Component Author Version tested
    IDE Arduino arduino.cc and community 1.8.5
    Board support ESP8266 esp8266 community 2.4.0
    Library WiFiManager tzapu 0.12.0
    Library ESP8266 Framework Coert Vonk 1.0.0
    Library ESP8266 Fatal Coert Vonk, forked from Krzysztof 1.0.0
    Library IRremoteESP8266 Sebastien Warin et al. 2.3.1
  2. Training is required so that the device issues the correct infrared codes to the CD player. to capture the infrared codes from the existing remote control, we used the example IRrecvDumpV2 from the IRremoteESP8266 library.
    1. Compile and upload it to the device over USB Serial, then open the Serial Monitor.
    2. Press the relevant buttons and note the button pressed and codes generated. E.g. for my CD player it shows the the manufacture’s address as 0x4004 (Panasonic) and the code for “play” as 0x05505005.
  3. Program the device using the code from GitHub.
    1. Copy or clone ir-interface.c.
    2. Update the code with your own codes.
    3. Compile and upload it to the device over USB Serial. Subsequent uploads may be performed using over-the-air (OTA) updates.
    4. The first time the board starts up it will be in Access Point mode. Use a computer or phone to connect to WiFi network. If it doesn’t automatically connect you to the device, use a browser with any address. Use the browser to configure your networks SSID and password. These values will be saved in EEPROM so next time the device can connect directly.
    5. Open a serial monitor and note the IP address assigned to the device.

Unit testing

  1. Test the webserver pointing a webbrowser at http://ir-interface.local/ir/ir. You should see the infrared menu.
  2. Test a keyword by pointing a webbrowser at e.g. http://ir-interface.local/ir?req=play. The CD player should start playing. The image below shows the pulse train on an oscilloscope
    Infrared pulse train
  3. Test the remaining keywords

Access router

The design relies on the router as an integral part of the solution. It functions as a remote proxy and translates between HTTPS used on the internet and HTTP on the local area network.

Design

Reverse proxy messages

Development

Install a reverse-proxy and TLS-certificates on your WiFi router. Detailed instructions for routers with DD-WRT firmware can be found at DD-WRT Reverse Proxy and HTTPS. Alternatively, you can configure port forwarding on your WiFi router. In that case you need to use http instead of https.

Unit testing

Drumroll please …

  1. Use a webbrowser to access https://ir.home.domain.com/ir. It should respond with a list of valid commands.
  2. Use a webbrowser to issue https://ir.home.domain.com/ir?req=play. It should respond with “Sending play”.
  3. Continue with testing the other keywords.

If This Then That

If This Then That, commonly referred to as IFTTT, is a web service that preforms actions through multiple services when a applet is triggered, you can customize both the trigger and the action using their interface. In this project we use the Google Assistant as the trigger and Webhooks to preform the web request.

Design

Data flow from Google Home to If This Then That

Development

The tricky part is setting up IFTTT. To do this go to the IFTTT site; click on Continue with Google and create a new applet (Profile Dropdown » New Applet)

  1. Start by specifying a trigger by clicking the +this and selecting “Google Assistant” from the list of services.
    1. Click Connect to authorize IFTTT to manage voice commands
    2. Click Say a phrase with a text ingredient, and fill in the trigger fields:
      • What do you want to say? = CD $
      • What’s another way to say it? = remote $
      • What do you want the Assistant to say in response? = Sending IR Code
      • Press Create Trigger
  2. Specify the Action by clicking the +that.
    1. Choose action service = Select “Webhooks” and press Connect
    2. Choose action = Make a web request
    3. Fill in the action fields
      • URL = https://ir.home.domain.com/ir?req={{TextField}}
      • Method = GET
      • Content Type = text/plain
      • Press Create Action
    4. Press Finish

Testing

Now for the fun part:

  1. Prepare
    • While still on the IFTTT site at the My Applets > Google Assistant, click Check now.
    • Connect to the serial port of the ESP8266 using the Serial Monitor on the Arduino IDE
  2. Give it a shot
    • Use a Google Home (or on another Assistant enabled device), and say “Hey Google CD Play”.
    • The Google Home should reply with “Sending IR Code”.
    • On the Serial Monitor, you should see “Sending Play”.
    • The CD player should start.
    • Give yourself a pat on the back and continue with testing the other keywords.

I hope this device will help you modernize your home without spending hundreds on replacement devices. To further modernize your home you can build your own smart alarm clock that syncs alarms and events from Google Calendar ESP8266 reads Google Calendar

Copyright © 1996-2022 Coert Vonk, All Rights Reserved