[Release] Tasmota Sonoff Hubitat Driver & Device Support

Yes. Otherwise it will not update the firmware OTA because there isn't enough space of the sonoff for the active firmware and the new firmware.

So here's what I did to get this working on generic wifi plugs that are compatible with Sonoff/Tasmota:

  1. Bought these on Amazon. They are AWP02L-N plugs. $16 bucks for 2 isn't bad. No idea how long they will be compatible with Tuya-convert, but the ones I received within the past month are. (FYI, still working as of 8/3/2019 from items received from Amazon).
  2. Followed this guide to use Tuya-Convert to install Tasmota on them.
  3. Did file-based update to Tasmota-minimal.
  4. Did file-based update to above firmware.
  5. This reset the device, so had to connect to sonoff-xxx wifi device and reconfigure wifi settings. Then go to Configuration -> Configuration Other and copy/paste template data and click Activate. Also turn on "SmartThings/Hubitat" and "Hue Bridge". And then go into Console and do this to turn off the LED SetOption31 1
  6. This driver ([Release] Tasmota Sonoff Hubitat Driver & Device Support - #30 by Ryan780) works but
    Sonoff Connect did not. See also this new thread and related drivers that work great with the new and old tasmota versions: [DEPRECATED] Tasmota 7.x/8.x firmware for Hubitat + Tuya, Sonoff and other drivers - #131 by markus

FYI, these CYYLTD Mini Wifi Socket devices are also cheap and work fine and they have a USB port with 2.1A: https://www.amazon.com/gp/product/B078H4SNST

Same setup as above using Tuya-convert; here is the template data:

{"NAME":"CYYLTD BIFANS J23","GPIO":[56,0,0,0,0,0,0,0,21,17,0,0,0],"FLAG":1,"BASE":18}

These plugs also work: https://www.amazon.com/dp/B074576LSB

EDIT: 03JAN20 And these work and have Hubitat-compatible energy monitoring: https://www.amazon.com/dp/B07HBTSG76 and use this template: https://templates.blakadder.com/awp04l.html

2 Likes

Any ideas why my devices show up as question marks in the Dashboard? I tried template switch and template outlet.

They are showing up as ?? when using the Switch template? What driver are they assigned to? Can you give a screenshot of your dashboard setup?

Here you go. They are setup as "Sonoff Wifi Switches" (which is the S20 driver renamed per my post above). The buttons work great in the view to turn the outlet on/off, but it's almost like the dashboard doesn't know the status, so it always turns it off (I'm also still on 2.1.1.122 in case that matters).

The other thing I noticed is there are a ton of events in the logs for the device. It's like they are super chatty:

Let me know if I can give any additional information.

It has to be something with the driver your are using. This is the one that I am using for my basics and it works perfectly. Although, you have to set the Network ID yourself manually. It has to be the MAC address of your sonoff for local changes on the Sonoff to work correctly.

Just save the driver, create a virtual device and pick this driver, setting the correct Network ID. Then set the preferences and it should work and report local changes in the device. Should work for all single switch sonoff tasmota devices.

// Original driver developed by Brett Sheleski.
// Ported to Hubitat and updated to include switchNumber by ryan780.
metadata {
definition(name: "Sonoff-Tasmota RPC", namespace: "ryan780", author: "ryan780") {
capability "Actuator"
capability "Switch"
capability "Momentary"
capability "Polling"
capability "Refresh"
}

preferences {		
	section("Sonoff Host") {
    input(name: "ipAddress", type: "string", title: "IP Address", displayDuringSetup: true, required: true)
	input(name: "port", type: "number", title: "Port", displayDuringSetup: true, required: true, defaultValue: 80)
    input(name: "switchNumber", type: "number", title: "Switch Number", displayDuringSetup: true, required: false, defaultValue: null)
	}

	section("Authentication") {
		input(name: "username", type: "string", title: "Username", displayDuringSetup: false, required: false)
		input(name: "password", type: "password", title: "Password (sent cleartext)", displayDuringSetup: false, required: false)
	}
	section("Logging"){
		input(name: "logEnable", type: "bool", title: "Debug Logging", required: false, defaultValue: false)
    }
}
}
 

def parse(String description) {
def message = parseLanMessage(description)

// parse result from current and legacy formats
def resultJson = {}
if (message?.json) {
	// current json data format
	resultJson = message.json
if (logEnable) log.debug resultJson
}
else {
	// legacy Content-Type: text/plain
	// with json embedded in body text
	def STATUS_PREFIX = "STATUS = "
	def RESULT_PREFIX = "RESULT = "
	if (message?.body?.startsWith(STATUS_PREFIX)) {
		resultJson = new groovy.json.JsonSlurper().parseText(message.body.substring(STATUS_PREFIX.length()))
	}
	else if (message?.body?.startsWith(RESULT_PREFIX)) {
		resultJson = new groovy.json.JsonSlurper().parseText(message.body.substring(RESULT_PREFIX.length()))
	}
	/* else if (message?.header?.contains("HTTP/1.1 200 OK")) {
		if (logEnable) log.debug $message?.header
	}*/
}

// consume and set switch state
if ((resultJson?."POWER$switchNumber" in ["ON", 1, "1"])) {
	setSwitchState(true)
}
else if ((resultJson?."POWER$switchNumber" in ["OFF", 0, "0"])) {
	setSwitchState(false)
}
else if ((resultJson?."POWER" in ["ON", 1, "1"])) {
	setSwitchState(true)
}
else if ((resultJson?."POWER" in ["OFF", 0, "0"])) {
	setSwitchState(false)
}
else {
//	log.error "can not parse result with header: $message.header"
//	log.error "...and raw body: $message.body"
}
}

def setSwitchState(Boolean on) {
if (logEnable) log.info "switch is " + (on ? "ON" : "OFF")
sendEvent(name: "switch", value: on ? "on" : "off")
}

def push() {
sendCommand("Power$switchNumber", "Toggle")
}

def on() {
sendCommand("Power$switchNumber", "On")
}

def off() {
sendCommand("Power$switchNumber", "Off")
}

def poll() {
sendCommand("Power$switchNumber", null)
}

def refresh() {
sendCommand("Power$switchNumber", null)
}

private def sendCommand(String command, String payload) {
if (logEnable) log.debug "sendCommand(${command}:${payload}) to device at $ipAddress:$port"

if (!ipAddress || !port) {
	log.warn "aborting. ip address or port of device not set"
	return null;
}
def hosthex = convertIPtoHex(ipAddress)
def porthex = convertPortToHex(port)

def path = "/cm"
if (payload){
	path += "?cmnd=${command}%20${payload}"
}
else{
	path += "?cmnd=${command}"
}

if (username){
	path += "&user=${username}"
	if (password){
		path += "&password=${password}"
	}
}

def result = new hubitat.device.HubAction(
	method: "GET",
	path: path,
	headers: [
		HOST: "${ipAddress}:${port}"
	]
)
return result
}

private String convertIPtoHex(ipAddress) {
String hex = ipAddress.tokenize( '.' ).collect { String.format( '%02x', it.toInteger() ) }.join()
return hex
}

private String convertPortToHex(port) {
String hexport = port.toString().format('%04x', port.toInteger())
return hexport
}
3 Likes

Bingo. That worked. Thanks!

1 Like

I keep seeing this error when I use your code

ev:992019-07-11 08:44:22.192 am errorgroovy.lang.MissingMethodException: No signature of method: user_driver_ryan780_Sonoff_Tasmota_RPC_417.update() is applicable for argument types: () values: [] Possible solutions: putAt(java.lang.String, java.lang.Object), parse(java.lang.String), isCase(java.lang.Object), split(groovy.lang.Closure), use([Ljava.lang.Object;), use(java.lang.Class, groovy.lang.Closure) (update)

To fix that error just add the following to the driver.

def update() { }

You may also want to add

def installed() { }

These are functions that are called when the device is 'installed' initially, as well as when 'updated' (i.e. you press the save button). If these are not defined in the driver, those errors will be thrown. I believe the errors are harmless, but it is better to have them defined, IMHO.

Thank you I will try that and see, do you know why I'm getting all this errors event tho the tastoma switch working correctly
807D3A43F398 or C0A801B7.

sys:12019-07-11 09:00:49.185 am warnReceived data from 192.168.1.183, no matching device found for 192.168.1.183, C0A801B7:FBF6, 807D3A43F398 or C0A801B7.

Sorry, I don't use any tasmota devices at all. I just know about writing Hubitat Drivers... :wink:

@Ryan780 will hopefully be able to answer your tasmota device specific questions.

@ogiewon Thank you i was able to figure that part out no more errors.

1 Like

You have to set the Network ID for the device to the MAC address of the device manually. I don't know enough about hubitat drivers to get it to set it to that by itself. :slight_smile:

In your case, that is 807D3A43F398

I'm really interested in trying to get my Smartthings world moved over Hubitat to get rid of the latency.

I bought a Hubitat Hub a month ago and proceeded to get distracted by other things haha. When I got back to looking at it I quickly realized I was not equipped to take on the Tasmota part of the migration then I noticed this thread.

Is it possible to implement the "expanded" features that Tasmota offers? For example the MP3 player implementation? I use that for door open/close announce.

I'm not familiar with that function within the Tasmota firmware. Are you saying you hook a speaker to a Sonoff device in some way? If you have a link to the area in the Sonoff wiki that talks about this function or some more details, that would be helpful.

I can't post a link here but if you search for

arendst Sonoff-Tasmota commands

on the first link go torward the bottom and you will find an MP3 section. There's a link to the actual MP3 player in the text. I connected it up like the documentation says and it works like a charm.

Those are commands within Tasmota? You would have to build a driver to support those commands. One does not exist to my knowledge.

Yeah... that's what I was afraid of.
Unless someone comes along and builds the right drivers it looks like I won't be Hubitat-ing any time soon haha.

Controlling your MP3 player from your Home Automation system is that important to you? And you can only do it with Tasmota? Well, then yeah, HE isn't the right platform for you then. Best of luck.

Oops, I deleted my post by accident. I was trying to correct a spelling mistake.

Here's what I was saying before I deleted it.

Every time we open a door or window we hear a "beep" for 'open' and a "beep-beep" for 'closed' so, yeah, I guess that's a big part of our daily experience (the biggest?) with home automation. The kids are gone so it's just the wife and I in a big house so that part was not negotiable.

I wanted to remove our existing security system and add smart switches, dimmers, sensors, garage door opener, etc. and Tasmota helped me solve a major piece of that puzzle.

If there is another way to do that with Hubitat I'm very interested.