NOTE: June 2024
Lets Encrypt upgraded their intermediate certificate chain this month which broke mqtt/tls for me and so I have given up building custom Tasmota binaries. Yes, upgrading is painful since current release images are so bloated (requiring you to first upgrade to a "minimal" image, then the regular one). But giving up encryption to a mosquitto server on my local (and heavily firewalled) network is not much of a step backward given that Tasmota does not support https.
Anyway, I'll leave this page up as there are still useful bits on it that are not about mqtt/tls.
I've been using home automation for a long time. I started with X10 but found its one-way power line control protocol did not work that well for me. Later I switched to Insteon which uses two-way power line and RF control. I only used power line modules and quickly found that they didn't really work all that much better. In the long my experience with Insteon was a failed experiment. Modules are significantly more expensive than X10 and the protocol is proprietary. But my biggest complaint is that the company frequently makes backwards incompatible changes. Several times over the years I bought new hardware that would not inter operate with my existing hardware.
I was seriously considering buying some Zigbee modules and doing research when I found a YouTube rant by Paul Hibbert that compares Zigbee to WiFi: Zigbee Is A Con And The Industry Is Lying To You. I hadn't realized that so many WiFi modules were available and when I looked into them I found that these typically use the cloud for control. But it wasn't difficult to find alternative, open source firmware that would allow me to use my own server. While looking at the list of devices supported by Tasmota I found Sunoff and ordered a S31 smart plug. Once I saw how easy it was to get the S31 working with Tasmota and how well everything worked I ordered more S31's and also some Basic modules. At this point I have more than ten modules in operation.
I recommend the "Getting Started" page on the Tasmota site for instructions on flashing Tasmota over the factory firmware; since Tasmota supports OTA updates via http, this is something you usually only need to do once. When I first tried Tasmota I followed a guide that used version 6.4. Later I built 8.1 from source to gain TLS support (see Building below).
I normal use the Espressif esptool tool.
The recommended USB serial cable is the FTDI RT232R-3V3. These feature 3.3V TTL level UART levels on a 6 pin, 0.1" pitch connector. They supply 5V but the Sonoff boards I've used all have regulators that handle this without damage.
To flash S31 modules I made an adapter cable that plugs into the FTDI cable and temporarily tack the wires to the board. I use the same color codes as the FTDI cable to help insure correct connection. Red for VCC, orange for RX, yellow for TX and black for ground.
To flash using esptool, hold down the button (GPIO0) while applying power and then run:
esptool.py --port /dev/ttyU10 write_flash -fs 1MB -fm dout 0x0 tasmota.bin
Hint: If you're unsure what the serial port is called use:
ls /dev > /tmp/1
[plug in USB cable]
ls /dev > /tmp/2
diff /tmp/1 /tmp/2
Other useful commands:
esptool.py -p /dev/ttyUSB0 read_mac
esptool.py -p /dev/ttyUSB0 flash_id
esptool.py -p /dev/ttyUSB0 erase_flash
To flash Basic modules I usually solder in a 1x4 sip socket and use wires to jumper between the FTDI cable and the module. (Flashing with esptool is the same as with the S31 module.)
Note that the esptool default speed is 115200 baud (the same as all ESP8266 modules I've encountered). And while OTA Tasmota updates support compressed images, you must use an uncompressed image when flashing with esptool.
Some newer home automation products use modules that are incompatible with Tasmota, e.g. WB2S or TYWE2S. The conversion path involves replacing the modules with ESP versions, e.g. the ESP-02S or ESP-12F. You have to be careful with these, they need 3.3V and 5V will destroy them. You also need to tie GPIO0 to ground while programming. I was successful programming a ESP-02S by grounding GPIO0 but had to remove the jumper before it would boot. I also had success with a ESP-12F by pulling GPIO0 to ground with a 10K resistor (which I was able to leave in place).
I wanted TLS support but pre-compiled images do not have it because the feature is large; modules typically have 1M of flash and if your binary is larger than half of this (512K) you won't have enough free space to support OTA upgrades. The strategy is to turn off support for hardware you don't have and features you don't use to make room for TLS.
Hint: After you've built a binary you can see how big is use with:
xtensa-esp32-elf-size .pio/build/tasmota/firmware.elf
Last time I checked the current documentation was brief and lacking. There's also the problem that content frequently moves or completely disappears (!?!?) and I can't find the old version even on archive.org. If you find broken links here please drop me a note.
One procedure I found when I was starting out discussed using Windows 10 but the use of Atom and PlatformIO is similar when using linux. Here's a quick summary of my procedure:
cd tasmota
mv -i my_user_config.h my_user_config.orig
awk -f my_user_config.AWK my_user_config.h.orig > my_user_config.h
I prefer not to embed WiFi credentials in an image but you have the option of editing tasmota/my_user_config.h to doing this.
(Among other things) the script turns on USE_MQTT_TLS and USE_MQTT_TLS_CA_CERT (my MQTT server uses Let's Encrypt certificates) and changes the timezone to Pacific. This is what I use and is meant to be a starting place for customization.
Launch the atom (IDE), open the project, and start the build. The new image ends up in build_output/firmware/tasmota.bin.
Even with TLS enabled you must use http with the OTA firmware upgrades.
Starting Tasmota 8.2 you can do use gzip'ed binary images with OTA firmware upgrades.
rm -rf .cache .pio
Initially I used 6.4 but later upgraded to 8.1 built from source to gain TLS support. Here's how to upgrade the theme to new black background; paste into the web console:
WebColor {"WebColor":["#eaeaea","#252525","#4f4f4f","#000000","#dddddd","#65c115","#1f1f1f","#ff5661","#008000","#faffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#faffff","#999999","#eaeaea"]}
Use the web console to configure the Timezone (this shows Pacific time):
Backlog Timezone 99 ; TimeDST 0,2,03,1,3,-420 ; TimeSTD 0,1,11,1,2,-480
The 99 says to use TimeDST and TimeSTD. Use "time" to check.
I also set ntpserver1 to use a local server and remove the other default servers:
Backlog ntpserver1 203.0.113.123 ; ntpserver2 0 ; ntpserver3 0
My modules are tightly firewalled and cannot connect to the internet.
If you configure your location it can be used to calculate sunrise and sunset:
Backlog Latitude 37.755199 ; Longitude -122.452400
For privacy I like to pick a nearby landmark instead of using my actual location.
This is trivial to do using timers assuming you have configured timezone and location:
You can add a bias (e.g. 30 minutes before sunrise) and even add random fuzz (e.g. ± 10 minutes).
In case it's not obvious you need to enable both arm and repeat or else each timer will only fire once.
I like to turn this on:
SetOption53 1
After years of trouble free service I found that sometimes different modules would lose some or all configuration settings. Eventually I found this post:
Tasmota-based devices losing their settings
Which describes two "interesting" Tasmota features. One is called "Boot loop defaults restoration control" (SetOption36). The idea is when Tasmota is crashing repeatedly due to an exception or watchdog features are disabled, one at a time, eventually reverting to a Sonoff basic config. SetOption36 is a count of the number of boots before triggering this behavior and it defaults to 1. Setting it to 10 prevents power glitches from tripping it:
setoption36 10
The other feature is called "Device recovery using fast power cycle detection" (setoption65). When enabled it resets all settings after 7 power cycles. Setting it to one disables the feature:
setoption65 1
Webbutton1 Destruct
Switchmode2 2
While you can do interesting things without a MQTT broker you'll probably want to use one. I use Eclipse Mosquitto.
PowerRetain 1
This causes the module to come back in the same on/off state after a reboot, crash, or loss of power.
This was difficult to figure out. For whatever reasons there does not appear to be high level documentation or concrete examples out there. The closest thing I found was this block post titled LEGO Nightstand Light Switch.
I was able to make this work using two ESP8266 dev boards. When you configure the module type to Generic you get a configuration page that looks like this:
In my case, the "D" number correspond to Arduino digital pin numbers as well as what is silk screened onto my dev board. The GPIO numbers correspond to Espressif documentation. Notice that next to some of the pins are comments like Button1 and Relay1. These are assumed if they are not explicitly configured with the per-pin pulldown menu items. Let's say you want to have two inputs that are connected to on/off switches. If you configured two pins to be switches (e.g. Switch1 and Switch2) but do not configured any relays then operating either switch will control the default or explicit relay.
Here's an example of a working configuration. There are two ESP8266 modules. Since pins D3 (GPIO0), D4 (GPIO2), and D8 (GPIO15) select different boot modes (e.g. the UART bootloader) I'll avoid using them as inputs. There's also a red LED on D0 (and a blue one on D4).
The first module, livingroom-display, has LEDs connected two four pins: D1, D2, D5, and D6. Each LED has one pin hooked to an I/O pin and the other to a dropping resistor connected to 3.3V. To illuminate the LED we need the I/O pin to be driven low. So we'll configure the pins to use the inverting version of a relay: Relay1i, Relay2i, Relay3i, and Relay4i:
The second module, frontdoor-sensor, has two inputs connected to switches. We want these inputs to control the LEDs/relays on livingroom-display. For inputs we'll use D2 and D5 and configure them as Switch2 and Switch3 (remember we want to control Relay2i and Relay3i on livingroom-display). We also need two dummy relays: Relay2 and Relay3:
We also need to change the SwitchMode from the default of toggle (0), to inverted follow (2):
Backlog SwitchMode2 2 ; SwitchMode3 2
Next we need to change the SwitchTopic:
SwitchTopic livingroom-display
This causes MQTT updates to set the specific topic.
Finally we need some rules so that when an input on frontdoor-sensor changes that module will publish the new MQTT status so that livingroom-display can track the updated values (enter all in one line):
rule on switch2#state=2 do publish cmnd/livingroom-display/power 2 endon; on switch3#state=2 do publish cmnd/livingroom-display/power 2 endon
At this point grounding D2 or D5 on frontdoor-sensor will turn on the 2nd or 3rd LED on livingroom-display.
Some things to keep in mind about all this:
There's no way to map to switch number on one module to a different switch number on the other; if you want to control Switch1 on the target module, you must use Switch1 on the controlling module. Just swap numbers in the config to make this happen.
Since you can only set one SwitchTopic, it's not really possible for one module to control more than one other module.
I found that sometimes GPIO pins programmed as inputs would also trigger Switch1. The only way to solve this appears to use a different GPIO pin.
The most recent Sonoff Basic R2 uses a version of the ESP8255. If you configure the Tasmota module type to "Sonoff Basic" you won't be able to access most of the GPIO pins. The workaround is to set the module type to "Generic" and make GPIO0 Button1, GPIO12 Relay1, and GPIO13 Led1i (inverted).
This preserves the standard functionality of a Basic while making pins including GPIO10, GPIO14 and, GPIO16 usable. While these are not exposed as pads the Sonoff Basic R2 board GPIO14 and GPIO16 are near a corner of the chip and it's not too tricky to tack wires to the pins. In this picture GPIO14 is the top right pin and GPIO16 is the upper right side pin:
The Sonoff Basic R2 uses a QFN-32. It is 5mm square and the center-to-center pin spacing is 0.5mm. GPIO10 is on the left side of the chip, second from the top and would be much more difficult to solder a wire to.
The smallest wire wrap wire I could find for this kind of modification Alpha Wire 2936. It's 36 AWG (0.005") with white insulation.
Copyright © 2020, 2021, 2023
Craig Leres