Skip to content
ggodart edited this page Dec 15, 2020 · 51 revisions

Introduction

Tasmota is custom firmware that is available for ESP8266 based devices allowing for web, timer, OTA firmware updates and sensor support. Tasmota allows for ESP8266 based devices such as the Sonoff family or dev boards like the Wemos D1 mini to be controlled via HTTP, MQTT and KNX.

This page describes how to use Misterhouse with Tasmota devices via both HTML and MQTT.

Please be patient as it is currently a work-in-progress, we hope to be able to introduce the Misterhouse changes described below into a future release of the core product in due course.

Installation and Configuration

How to flash you device with Tasmota is well documented on the internet, so I wont duplicate it here, however the following are useful resources;

Controlling Tasmota from Misterhouse, the HTML Method

Tasmota devices respond to the following html http://your_device_ip_address/cm?cmnd=Power%20on or http://your_device_ip_address/cm?cmnd=Power%20off
Implement the following in order to simplify this interface.

Work in progress

Controlling Tasmota from Misterhouse,MQTT method

MQTT Installation

First you will need to install an MQTT Broker and note down its IP address and port. These instructions were tested with Mosquitto on a raspberry PI.

Misterhouse Configuration

Next you need to add the following to your mh.ini file;

# mandatory parameters for MQTT
CODE, require mqtt; #noloop
mqtt_host=192.168.100.64
mqtt_server_port=1883
mqtt_topic=stat/#
mqtt_debug=0

#optional parameters for MQTT
mqtt_LWT_topic=tele/Misterhouse/LWT
mqtt_LWT_payload=offine
mqtt_user=user 
mqtt_password=password 
mqtt_keepalive=120 

Next make sure your lib/read_table_A.pl contains the following in amongst all the other device configurations;

#-------------- MQTT Objects -----------------  
	elsif ( $type eq "MQTT_GATEWAY" ) {
 		# there must be one record for the gateway above any MQTT_DEVICE definitions
		# it takes the following format
		# MQTT_GATEWAY, name_of_gateway
		# e.g.MQTT_GATEWAY, mqtt_1
		require 'mqtt.pm';
		( $name ) = @item_info;
		$code .= sprintf( "\n\$%-35s = new mqtt(\"%s\", \$config_parms{mqtt_host},
				\$config_parms{mqtt_server_port},
				\$config_parms{mqtt_topic},
				\$config_parms{mqtt_username}, 
				\$config_parms{mqtt_password}, 121);\n",
			$name,
			$name
		);
	}
	elsif ( $type eq "MQTT_DEVICE" ) {
        # there is one record per mqtt device and it must be below the MQTT_GATEWAY definition
        # it takes the following form
		# MQTT_DEVICE, name_of_device, groups, name_of_gateway, topic
		# e.g. MQTT_DEVICE, MQTT_test, Kitchen, mqtt_1, stat/mh_mqtt_test/SENSOR 
		# if the device is to transmit to MH, its topic must match the 
		# config parameter mqtt_topic in the mh.ini file	
		require 'mqtt.pm';
		my ($MQTT_gateway_name, $MQTT_topic);
		( $name, $grouplist, $MQTT_gateway_name, $MQTT_topic ) = @item_info;		
		$code .= sprintf( "\n\$%-35s = new mqtt_Item(\$%s\,\"%s\");\n",
			$name, $MQTT_gateway_name, $MQTT_topic );		
	}
#-------------- End MQTT Objects ----------------

Then you can add MQTT items to your items.mht file as in the example below;

# MQTT_GATEWAY, name_of_gateway
MQTT_GATEWAY, mqtt_1
# MQTT_DEVICE, name_of_device, groups, name_of_gateway, topic
MQTT_DEVICE, MQTT_test, Gym, mqtt_1, cmnd/MQTT_test/power 

Tasmota Configuration

Point your browser at the Tasmota MQTT web interface on your device http://device_ip_address/mq? and add the mqtt broker's ip address, port and the Topic (MQTT_test in this example), leave the rest to default values. Then enable MQTT on the configure other page of the device http://device_ip_address/co?. Its a good idea to set a nice friendly name here at the same time, especially if you plan to have a number of devices.

You should now be able to control the device by any of the normal Misterhouse techniques, however there is no feedback about the initial state of the device. There is a number of ways to do this described below.

More advanced implementation notes

Sonoff switches

Most Sonoff devices actually have 2 devices, a switch and a relay. By default the switch just toggles the relay locally and sends an mqtt message with a topic of stat/yourdevicetopic/POWER with a payload of ON or OFF. The simple way to handle this to ensure that your MH switch value correctly reflects the actual state of the device is to add another MH device e.g. MQTT_DEVICE, MQTT_test_status, Gym, mqtt_1, stat/MQTT_test/POWER. then have a state change handler in MH that syncs the two, e.g.

if ( $state = state_now $MQTT_test_status ) {
	my $new_state = $state;
	print_log("MQTT_test_status Switch changed to $new_state when relay is at " . $MQTT_test->{state});
	if ($new_state ne $MQTT_test->{state}) {
		$MQTT_test->set($new_state,"Local switch toggled");
	}
}

You can of course simplify this with a group if you have a lot of devices.

Home grown detectors, e.g. PIR Motion detectors

By default Tasmota only sends on and off commands when switches change state, so if you connect a PIR to a Tasmota device, it will just send on and off whereas you probably want it to send motion and still. This Tasmota rule overcomes the problem and is a good example of a very simple Tasmota Rule.

Rule1 
on Switch1#state=1 do 
   Backlog LedPower1 1; 
   Publish stat/%topic%/PIR1 motion
endon 
on Switch1#state=0 do 
   Backlog LedPower1 0; 
   Publish stat/%topic%/PIR1 still 
endon
Rule1 1

This page has a more advanced rule that uses a timer to makes sure the motion command isn't sent too often.

Other Sensors

Tasmota has a huge number of drivers for different sensors (e.g. 1-wire temperature), however they usually publish status changes via a tele/... topic rather than a stat/... one.

Unfortunately the current Misterhouse MQTT implementation can only subscribe to one topic at a time. There are 2 solutions to this, one is to use a Tasmota rule to publish stat/... instead of tele/... and the other is to have a separate MQTT listener daemon that listens for tele/... topics and re-publishes them as stat/....

Many of the sensors report status as a JSON encoded payload, e.g. the 1-wire temperature interface reports {"Time":"2020-12-15T13:49:58","DS18S20-1":{"Id":"0008019F33E0","Temperature":16.7},"DS18B20-2":{"Id":"000001888F60","Temperature":22.6},"DS18B20-3":{"Id":"0000026B7E32","Temperature":18.5},"DS18B20-4":{"Id":"0000026B9275","Temperature":13.1},"DS18B20-5":{"Id":"0000026BA8B6","Temperature":9.3},"DS18B20-6":{"Id":"0000026BAECC","Temperature":18.7},"TempUnit":"C"} so you will need to use json_decode to get at the values.

Crafting your own MQTT clients

The Misterhouse implementation uses the perl modules IO::Socket::INET, Net::MQTT::Constants and Net::MQTT::Message;. When crafting your own clients, not surprisingly, Net::MQTT::Simple is much simpler, especially for subscribing to multiple topics.

Last Will and Testament (LWT)

MQTT Last will and testament is an extremely useful feature for detecting when devices go bad.
By default Tasmota devices set their LWT with a topic of tele/devicename/LWT and a payload of offline when they connect to the broker. and send a message of tele/devicename/LWT and a payload of online as soon as they start. MQTT devices continually ping the broker with a keep alive message, if the broker doesn't get these messages it publishes the LWT message, so if you want to know if your device has gone bad, all you need to do is to subscribe to the LWT topic and wait. I have a separate perl process that subscribes to all LWT topics using the topic tele/+/LWT which emails me if it gets any offline messages; I also use it to re-publish tele/... topics as stat/... as described above.

If you want to have your Misterhouse instance support LWT, then do the following;

Firstly add the topic and payload to your mh.ini e.g.

mqtt_LWT_topic=tele/Misterhouse/LWT
mqtt_LWT_payload=offine

Next change /lib/mqtt.pm to include the LWT when it connects. Look for MQTT_CONNECT and add the 2 extra parameters (it occurs twice in /lib/mqtt.pm) e.g.

$self->send_mqtt_msg(
        message_type     => MQTT_CONNECT,
        keep_alive_timer => $self->{keep_alive_timer},
        user_name        => $self->{user_name},
        password         => $self->{password},
        will_topic       => $::config_parms{mqtt_LWT_topic},
	will_message     => $::config_parms{mqtt_LWT_payload}
);

Next you need to transmit the online message as soon as it starts e.g. place the following code in you initilisation scripts

print_log( "sending LWT online message topic="
    . $config_parms{mqtt_LWT_topic}
    . " payload="
    . "online" );
$mqtt_1->pub_msg(
    message_type => MQTT_PUBLISH,
    retain       => 1,
    topic        => $config_parms{mqtt_LWT_topic},
    message      => "online"
);

Useful MQTT utilities

The Tasmota web Console is extremely useful for finding out whats going on with a device, simply point your browser at http://device_ip_addres/cs.

The following tools are also handy;

Activity Tool
Flashing devices via USB/FTDI Tazmotizer
Managing multiple tasmota devices TDM
Monitoring MQTT traffic MQTT.fx

Acknowledgements

Thanks to;
Neil Cherry for creating the Misterhouse MQTT interface
Jeff Siddall for his work on the HTML interface
Theo Arends for starting the Tasmota project
Andy Stanford-Clark and Arlen Nipper for creating MQTT.

Clone this wiki locally