[Release] Tasmota Sonoff Hubitat Driver & Device Support


#21

You have to use the driver linked above.


#22

I install all the drivers and the discovery not finding anything. i do have the firmeware install and the Hue Bridge is enable, i have the static ip of my hub set up but not discovery


#23

Ahh so we need to download and install this minimal version via OTA THEN come back and is tall this version via OTA? Releases · arendst/Sonoff-Tasmota · GitHub


#24

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.


#25

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.
  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".
  6. Installed Sonoff Connect User App.
  7. Installed Sonoff S20 code. NOTE: You have to change the name in this driver from "Sonoff S20 - Tasmota" to "Sonoff Wifi Switch".
definition (name: "Sonoff Wifi Switch", namespace: "erocm123", author: "Eric      Maycock", vid:"generic-switch") 
  1. Sonoff Connect discover didn't work for me. I did a manual add and it appears to work in Hubitat. Button presses (on/off from device) properly send back to Hubitat to reflect changes and vice versa.

@ericm Should I try using the "Sonoff Wifi Switch" in the same repository vs. changing the name? Other comments in this thread implied that the S20 one was the right one to use. Also, no idea why discovery didn't work but that's not a dealbreaker for me. Be glad to test other versions if you want me to help getting discover working.


#26

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


#27

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?


#28

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.


#30

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
}

#31

Bingo. That worked. Thanks!


#33

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)


#34

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.


#35

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.


#36

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.


#37

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


#38

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


#39

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.


#40

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.


#41

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.


#42

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