Alexa, Raspberry Pi and Sonoff

Updated July 26, 2019: I am using a combination of Echo Dot generation 1 and generation 3 here in Spain.

Amazon EchoAmazon insist on using port 80 for gen 3 Echos, a port already used by something else on my Raspberry Pi 3-based home control system.

I  am using port 8980 to avoid being the hated Linux ROOT user and so now, on my main Pi 3,  I moved the web server to port 86 and using “iptables” have redirected port 8980 traffic to port 80 to keep Amazon happy while continuing to use port 8980 to keep Linux happy as user Pi. This all seems to work well.

As a Node-Red fan I am using node-red-contrib-amazon-echo to simulate Amazon Alexa capabilities in some devices – this allows me to easily use a reprogrammed Sonoff mains controller using my own ESP-GO software with a GPIO pin controlling some serial RGB LEDs – and NR with node-red-contrib-amazon-echo to not only turn on and off the LED strip but also to fine-tune the colour by voice alone.

sudo apt-get install iptables-persistent
sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8980
sudo netfilter-persistent save
sudo netfilter-persistent reload

Meanwhile on a different note, I learned that to use Tasmota with Flash-limited Sonoffs – you can flash in 2 stages thanks to a minimal intermediate version which still handles MQTT:

topic: cmnd/my_gadget/OtaUrl
topic: cmnd/my_gadget/Upgrade
payload: 1

Below I’m loading sonoff.bin rather than sonoff-basic.bin – the latter requires this 2-step OTA but has more stuff built into it (sensors).

topic: cmnd/my_gadget/OtaUrl
topic: cmnd/my_gadget/Upgrade
payload: 1

and to change SSIDs on Tasmota-equipped boards….

topic@ cmnd/my_gadget/Backlog
payload: ssid1 whatever; ssid2 mypass

And to monitor all status info for Tasmotas in Node-Red:

topic: cmnd/my_gadget/STATUS
payload: 0

and  subscribe to topic:


See also Andreas Spiess YouTube video here ( for setting up Raspbian with Grafana and InfluxDB using my “the script” which you’ll find referred to around the blog.


17 thoughts on “Alexa, Raspberry Pi and Sonoff

  1. Hi Peter et al,
    I’m playing with Alexa and Node-Red and sending commands to ‘hue’ style devices is peasy. What I want is to tell Alexa that Node-Red has something to announce and get it spoken out. Simple things like “the dishwasher has finished” or “the oil tank is low”.
    Do I need to produce my own skills or is there an easy, albeit limited, way to do this?

    1. You can use routines in the app to setup custom responses – however if you want them triggered by some device you are currently limited to contact and motion sensors that are connected to an Echo Plus Hub or the Smartthings Hub. Other than that you are limited to voice, schedule or echo buttons. Maybe someone will produce a bluetooth echo button emulator that can be triggered from node-red or it may be feasible to cannibalise an existing button and attach it to a relay.

    2. I appreciate this is an old query but in case anyone is looking at this thread for reference purposes you can now have any alexa device on your network make spontaneous announcements without using any third party amazon skill. I use and using the sequence node can then trigger any payload to be spoken by your chosen alexa device. In my case I use Mqtt to trigger but any trigger will work.

        1. My Raspberry Pi can send out announcements from Node-Red at any time either via a hardwired or Bluetooth speaker thanks to Amazon AWS speech.

  2. This is part of my configuration.

    I am sharing the configuration to get access to node-red and echo (Amazon Alexa interface using Node-red).

    In fact I am not using that names for locations. I wrote like that for simplicity here. I prefer to use a long string of random generated characters to try to avoid people hacking my service. I also use fail2ban to block people trying to get access to my service without authorization (Several tries every day).

    This is it:

    http {
    include mime.types;
    default_type application/octet-stream;

    log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
    # ‘$status $body_bytes_sent “$http_referer” ‘
    # ‘”$http_user_agent” “$http_x_forwarded_for”‘;

    access_log /var/log/nginx_access.log main;

    sendfile on;
    #tcp_nopush on;

    #keepalive_timeout 0;
    keepalive_timeout 65;

    #gzip on;

    server {

    # SSL configuration

    listen 443 ssl http2 default_server;
    #listen [::]:443 ssl http2 default_server;
    ssl_certificate /etc/letsencrypt/live/yourdomain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain/privkey.pem;

    # from
    # and

    #ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver valid=300s;
    resolver_timeout 5s;
    # Disable preloading HSTS for now. You can use the commented out header line that includes
    # the “preload” directive if you understand the implications.
    #add_header Strict-Transport-Security “max-age=63072000; includeSubdomains; preload”;
    add_header Strict-Transport-Security “max-age=63072000; includeSubdomains”;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    location /favicon.ico {
    access_log /var/log/host.access.log main;

    location / {
    access_log /var/log/host.access.log main;
    deny all;

    location /nodered/ {
    access_log /var/log/host.access.log main;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    # Following is the “user:password” to access your node-red service
    proxy_set_header Authorization “Basic ‘your user:password base64 encoded string'”;
    auth_basic “Restricted Content”;
    # the following file was created with htpasswd command. This is the user and password that must authenticate from outside your network to get access to /nodered URL. This file can have more than one user.
    auth_basic_user_file /etc/nginx-pw;

    location /echo {
    access_log /var/log/host.access.log main;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header Authorization “Basic ‘your user:password base64 encoded string'”;
    limit_except POST {
    deny all;


    I use LetsEncrypt to generate my SSL certificates.

    You must update entries to ssl_certificate to match your location. You must also update your ‘user:password base64 encoded string’ entries.

    I don’t know how to encode code here to show it better..

  3. Peter. I recommend you to read about NGINX. With its reverse proxy option you could have different URLs to the same port (80, 443, etc) being internally forwarded to different IP addresses and/or ports.

    You could make something like this:

    requests to being forwarded internally to port 8080.
    requests to being forwarded internally to port 8980.
    requests to being forwarded internally to port 1880.

    These are just examples of what you could do.

    One additional benefit to note would be the fact that externally you can use HTTPS but internally just HTTP.

    I have it running on a Raspberry PI 3B and works really well.

  4. **WARNING** Never install sonoff-minimal on a virgin system. It has no way of obtaining your WiFi credentials (no AP mode etc) other than obtaining them from the previous sonoff-XXX.bin install.
    I’ve made that mistake before and had to resort to a soldering iron and serial lead to recover.

    1. AHAH, I was wondering about that… So, for clarity Terry, on a Sonoff BASIC (R2) do we need to flash Sonoff-BASIC – then ota to minimal then ota to sonoff.bin – or is flashing sonoff.bin at the very beginning ok to do?

      May as well have this written down here.

      1. You should be able to flash sonoff.bin straight away. Problems may occur when you update from one version of sonoff.bin to the next version. For example moving from 6.4.1 to 6.4.2 (when it comes out). You might have to follow the path:
        sonoff.bin (6.4.1) -> sonoff-minimal.bin -> sonoff.bin (6.4.2)

      2. never use sonoff-basic.bin firmware, it’s just a crippled down version which just enables to use the stock features of a sonoff basic (NO other sensors or other goodies) allowing you to jump to a new version of the SAME firmware edition without using the minimal one, as the basic firmware is smaller than 500k…

        i always flash sonoff.bin (really, sonoff-IT.bin for italian) on mine… and if you leave the config as it is, and you go into the firmware update page and just hit the ONLINE UPDATE, with the url that’s already there, you can watch how the (Theo’s so called) Ota Magic works: it will download minimal, then it will auto refresh page and download sonoff.bin, all on its own… 🙂

        try for example to flash 6.3.x (now old), then click to update to latest, leave there the browser alone and just watch 🙂

        1. Pete, you can actually automaGically flash minimal then full without doing the 2 steps… Theo calls this OtaMagic:

          “I used this feature by providing the sonoff-minimal.bin firmware image containing only MQTT and a webserver which allows for larger Tasmota images by using a two step OTA approach.

          First OTA upload the sonoff-minimal.bin image in the small free space area
          Then OTA upload the final sonoff.bin image in the larger free space area
          This process is now automated if used with an external OTA server.

          Tasmota now tries to load the requested image and if it notices that the image won’t fit it will load the minimal version first which in turn will load the requested final image. This is OtaMagic.”

          here more info:'s-New#otamagic

Comments are closed.