SmartThingsPublic icon indicating copy to clipboard operation
SmartThingsPublic copied to clipboard

New Tasmota SmartApp and Device Handlers

Open BrettSheleski opened this issue 7 years ago • 70 comments

I've started implementation of a new SmartApp and necessary child Device Handlers.

See https://github.com/BrettSheleski/SmartThingsPublic/tree/master/smartapps/BrettSheleski/tasmota.src for more details.

BrettSheleski avatar Feb 14 '18 15:02 BrettSheleski

@GeorgeIoak, check this out. You may be interested in testing this SmartApp and Device Handlers.

BrettSheleski avatar Feb 14 '18 15:02 BrettSheleski

OK, I was a little confused when I saw your pushes yesterday but I see what you're doing now. I assume it's probably better if I delete the original device handler and start from scratch?

GeorgeIoak avatar Feb 14 '18 16:02 GeorgeIoak

Yes, that is probably best.

However I don't see why they won't both work at the same time. It may just be a little weird and/or confusing to you.

BrettSheleski avatar Feb 14 '18 16:02 BrettSheleski

Got to the part where I was creating a SmartApp and when I tried to save the code I see this error:

No signature of method: script_app_metadata_84333d84_746d_430a_ad01_7b1f57149862.metadata() is applicable for argument types: (script_app_metadata_84333d84_746d_430a_ad01_7b1f57149862$_run_closure1) values: [script_app_metadata_84333d84_746d_430a_ad01_7b1f57149862$_run_closure1@d545146] Possible solutions: getMetadata(), getState(), setState(java.lang.Object), metaClass(groovy.lang.Closure)

GeorgeIoak avatar Feb 14 '18 16:02 GeorgeIoak

Sounds like in the SmartThings IDE you went to create a new Device Handler instead of a new SmartApp (it's different than the others). I assumed this would trip some people up.

BrettSheleski avatar Feb 14 '18 16:02 BrettSheleski

No, it says New SmartApp at the top of the page

I see all 3 new device handlers listed and they were all published

GeorgeIoak avatar Feb 14 '18 16:02 GeorgeIoak

I think your link for the SmartApp is wrong, looks to be the same as 1 of the Device Handlers:

https://github.com/BrettSheleski/SmartThingsPublic/blob/master/devicetypes/BrettSheleski/tasmota.src/tasmota-power.groovy

GeorgeIoak avatar Feb 14 '18 17:02 GeorgeIoak

Then it sounds like you tried pasting in the code for a device handler in where you should have pasted in the code for the SmartApp.

There's a SmartApp and Device Handler both named 'Tasmota'. This may be a source of confusion and may end up renaming one.

BrettSheleski avatar Feb 14 '18 17:02 BrettSheleski

Should be:

https://raw.githubusercontent.com/BrettSheleski/SmartThingsPublic/master/smartapps/BrettSheleski/tasmota.src/tasmota.groovy

GeorgeIoak avatar Feb 14 '18 17:02 GeorgeIoak

Crap, the URL in the readme.md file was wrong.

(see 7831d14c61341ca12245c286861bd7253d2d4617 )

BrettSheleski avatar Feb 14 '18 17:02 BrettSheleski

I assume when you add the SmartApp inside the ST mobile app the IP address you enter is your local IP address? I'm a little confused on how ST Mobile can link an inside IP with the outside world

GeorgeIoak avatar Feb 14 '18 17:02 GeorgeIoak

I entered the local IP address and I see Tasmota listed under the SmartApps section now but I don't see a new device(s) even if I scan. When I go back into the Tasmota SmartApp (in the ST Mobile App) to verify that it saved the IP address I see a blank Username but a string in the Password field yet I didn't enter either of those when I added the SmartApp

GeorgeIoak avatar Feb 14 '18 17:02 GeorgeIoak

Yes, enter your local IP address of the Sonoff.

You shouldn't have to scan for new devices. They should just show up after installing the SmartApp. Go to your list of Devices and verify.

BrettSheleski avatar Feb 14 '18 17:02 BrettSheleski

Something is up with the SmartApp. I added it again and went to look for devices and it didn't list a new thing. I closed the ST Mobile App and when I opened it again Tasmota is not listed under the SmartApps.

I've tried this a few times. When I go back to look at the Tasmota SmartApp The Username is empty but the password has a string in it. If I delete the password the Tasmota SmartApp disappears from the list of SmartApps

GeorgeIoak avatar Feb 14 '18 17:02 GeorgeIoak

Open the Simulator for the SmartApp, in the IDE. That might shed some light on the situation.

I've noticed that password fields appear to have value when going through the settings of stuff in the web IDE. It seems to be a strange side effect with the web IDE.

BrettSheleski avatar Feb 14 '18 17:02 BrettSheleski

OK, a bit odd but nothing happened when working with the Web IDE. I had tried the following in the Mobile ST App with no results but when using the Web IDE and the simulator I entered a username of "admin" (since that is what the default Tasmota uses without a password). When I did that the console showed that child devices were found and then they showed up in the My Devices tab of the Web IDE as well as in the Mobile ST App.

When I check the Sonoff Web Interface Page only Channel 1 is ON but the ST Mobile APP shows all 4 channels ON.

When I toggle the Tasmota-Power Thing in the ST Mobile App the button changes from ON to OFF and it changes the display on the Sonoff Web Page but they are not in sync correctly.

As a side note all the new Things listed in the ST Mobile App (and ST Web IDE) list the same name for all devices so you don't know which channel you are working with

GeorgeIoak avatar Feb 14 '18 17:02 GeorgeIoak

The behavior is similar to before. Sonoff gets a command from the ST App but the ST App doesn't sync properly. Also, oddly enough I see that the devices listed in the ST App are in 4-1-3-2 order rather than in a sequential order

Playing around some more and tapping the Tasmota-Master Thing I can sometimes get the ST App to be in sync but it's not consistent. It's almost like the Tasmota-Master has a timeout so the display of the correct mode in the ST App only happens for a certain time after you tap the Tasmota-Master button.

Not sure if this makes sense but it also seems that going from ON to OFF is much more consistent than trying to go from OFF to ON. By that I mean if the ST App is displaying a channel as OFF and you tap it, the command is sent to the Sonoff but the ST App doesn't change from OFF to ON. BUT if the ST App is displaying a channel as being ON and you tap it I think it always will change to OFF

GeorgeIoak avatar Feb 14 '18 18:02 GeorgeIoak

I wasn't aware of the default username being admin. I wonder if it's somewhat of a new change to the Tasmota firmware. I could default the username to 'admin' of the SmartApp for convenience.

Updating the Tasmota device outside of the SmartThings app currently will not update the status of the SmartThings devices. The purpose of the SmartApp is to provide an endpoint one could do an HTTP Post providing the status JSON, but that is not implemented yet. Simply put: syncing the status is just not a priority at this point, but if you are using solely the SmartThings app, the statuses should be accurate.

Giving each child device a distinguishing name should be easy enough to do.

There is a refresh command on the Master device which retrieves the latest status from the Sonoff device and passes that along to all child devices.

BrettSheleski avatar Feb 14 '18 18:02 BrettSheleski

OK, thanks for the clarification on the syncing side of things. If I just use the ST App and watch the Sonoff Web page I'm still not getting consistent results, both in the ST app and on the web page. The Master refresh doesn't always update the status correctly. Almost all of the time using the ST App will toggle the Sonoff Web Page but then almost all of the time the ST App will not toggle the state when you touch it.

I just started trying to track this down by using the simulator. One thing I found is that the 1st push on the Tasmota-Master does not issue a refresh, yet the next 2 times did:

` 1fb2e376-5f52-4d96-9e1e-088a50248371 12:27:53 PM: debug JSON: [Status:[ButtonTopic:0, FriendlyName:Sonoff1, SaveState:1, Power:8, ButtonRetain:0, LedState:1, Topic:sonoff, PowerRetain:0, SaveData:1, Module:23, PowerOnState:3]]

1fb2e376-5f52-4d96-9e1e-088a50248371 12:27:53 PM: debug createCommandAction(Status:null) to device at 192.168.10.46:80 1fb2e376-5f52-4d96-9e1e-088a50248371 12:27:53 PM: debug REFRESH 1fb2e376-5f52-4d96-9e1e-088a50248371 12:27:48 PM: debug JSON: [Status:[ButtonTopic:0, FriendlyName:Sonoff1, SaveState:1, Power:8, ButtonRetain:0, LedState:1, Topic:sonoff, PowerRetain:0, SaveData:1, Module:23, PowerOnState:3]] 1fb2e376-5f52-4d96-9e1e-088a50248371 12:27:47 PM: debug createCommandAction(Status:null) to device at 192.168.10.46:80 1fb2e376-5f52-4d96-9e1e-088a50248371 12:27:47 PM: debug REFRESH 1fb2e376-5f52-4d96-9e1e-088a50248371 12:27:38 PM: debug createCommandAction(Status:null) to device at 192.168.10.46:80 1fb2e376-5f52-4d96-9e1e-088a50248371 12:27:38 PM: debug REFRESH ` In this case the returned Power:8 is correct (Sonoff only has Channel 4 ON) but the display in the ST App did not change when this was received. When I changed to just having Channel 1 on the correct response was also received (Power:1) when I hit refresh on Tasmota-Master

GeorgeIoak avatar Feb 14 '18 20:02 GeorgeIoak

It may be an issue with the Tasmota-Power device handler where it creates a bitmask to determine the status. It does so by bit-shifting a certain number of times.

BrettSheleski avatar Feb 14 '18 20:02 BrettSheleski

I'll run some additional experiments and see if I can catch the bug...

GeorgeIoak avatar Feb 14 '18 21:02 GeorgeIoak

Do you by chance have your device setup to only be on for a certain duration?

Right now, when a "power device" (a single channel in your case) turns on/off it only updates the status of itself via the returned json string. If you have a pulse-time configured for example, it will not update again after the pulse duration has elapsed.

You had mentioned previously something like that only a single channel will be on at a time. Currently the device handler will not account for that sort of custom configuration.

I may be wise for me to add a call to parent.refresh() after handling the call back to ensure all child devices are updated after any one child changes state.

BrettSheleski avatar Feb 14 '18 22:02 BrettSheleski

No, that shouldn't be the case. I'm not actually running firmware on the Sonoff 4CH PRO at the moment. I have a ESP8266 module flashed with the Tasmota firmware (env_default = sonoff) while I do all of this testing.

When you asked about the pulse-time I believe you were referring to the DIP switch settings on the actual unit, right? If so then that shouldn't be a factor since I'm running the firmware on a module. Good thought though...

GeorgeIoak avatar Feb 14 '18 22:02 GeorgeIoak

Well now when I use the simulator in the ST IDE for Tasmota-Power and I use the ST Mobile App to refresh (Tasmota-Master) I see this in the IDE:

2803ceaf-859b-4b36-9cda-e9be73c4d208 4:21:22 PM: error java.lang.NullPointerException: Cannot invoke method minus() on null object @line 62 (updateStatus) Nothing seems to be working right now so I think somewhere something got hosed up so I'll remove the Things and start over

GeorgeIoak avatar Feb 15 '18 00:02 GeorgeIoak

I know exactly where that error is even while I sit here on the toilet 😎

Which channel the power switch is set to is stored in state. When it creates the bitmask it takes the channel number, subtracts 1, and shifts left that many bits.

The state.channelNumber is not being set properly. That gets done when the master device spawns child devices.

In the SmartThings simulator, open the master device, select your physical device, and press the reload command. That may re-set the channel number to the child devices.

BrettSheleski avatar Feb 15 '18 01:02 BrettSheleski

Getting closer. That seemed to wake things up (I did remove and reinstall prior to this). From my initial testing the Tasmota-Master Refresh appears to be working but still when I touch a channel the command is sent but the ST App is not updated (so if a channel is OFF and I touch it the command ON is sent but the button still displays OFF). Here's some ST Simulator Console messages:

` 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:15:44 PM: debug JSON: [Status:[ButtonTopic:0, FriendlyName:Sonoff1, SaveState:1, Power:9, ButtonRetain:0, LedState:1, Topic:sonoff, PowerRetain:0, SaveData:1, Module:23, PowerOnState:3]]

50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:15:43 PM: debug createCommandAction(Status:null) to device at 192.168.10.46:80 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:15:43 PM: debug REFRESH 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:15:26 PM: debug createCommandAction(Power4:toggle) to device at 192.168.10.46:80 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:15:16 PM: debug createCommandAction(Status:null) to device at 192.168.10.46:80 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:15:16 PM: debug REFRESH 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug CHILD OPTIONS: [namespace:BrettSheleski, type:Tasmota-Power, options:[powerChannel:4]] 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug Existing Child DEVICE : Tasmota-Power 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug CHILD OPTIONS: [namespace:BrettSheleski, type:Tasmota-Power, options:[powerChannel:3]] 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug Existing Child DEVICE : Tasmota-Power 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug CHILD OPTIONS: [namespace:BrettSheleski, type:Tasmota-Power, options:[powerChannel:1]] 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug Existing Child DEVICE : Tasmota-Power 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug CHILD OPTIONS: [namespace:BrettSheleski, type:Tasmota-Power, options:[powerChannel:2]] 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug Existing Child DEVICE : Tasmota-Power 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug Module: 23 (Sonoff 4CH Pro) 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:14:00 PM: debug GPIO: [GPIO3:0 (None), GPIO2:0 (None), GPIO1:0 (None)] 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:13:59 PM: debug createCommandAction(gpio:null) to device at 192.168.10.46:80 50e53a65-d9fe-4caf-a7a0-94e0caf0dd9a 5:13:59 PM: debug createCommandAction(module:null) to device at 192.168.10.46:80 ` And here's the Sonoff MQTT Console to see the commands:

` 02:02:00 MQT: tele/sonoff/UPTIME = {"Time":"2018-02-15T02:02:00","Uptime":"0T03:27:44"}

02:04:30 MQT: tele/sonoff/STATE = {"Time":"2018-02-15T02:04:30","Uptime":"0T03:30:14","Vcc":3.033,"POWER1":"ON","POWER2":"OFF","POWER3":"OFF","POWER4":"OFF","Wifi":{"AP":1,"SSId":"TheIoaks","RSSI":100,"APMac":"xXx"}}

02:09:30 MQT: tele/sonoff/STATE = {"Time":"2018-02-15T02:09:30","Uptime":"0T03:35:14","Vcc":3.029,"POWER1":"ON","POWER2":"OFF","POWER3":"OFF","POWER4":"OFF","Wifi":{"AP":1,"SSId":"TheIoaks","RSSI":100,"APMac":"xXx"}} 02:13:59 MQT: stat/sonoff/RESULT = {"Module":"23 (Sonoff 4CH Pro)"} 02:13:59 MQT: stat/sonoff/RESULT = {"GPIO1":"0 (None)","GPIO2":"0 (None)","GPIO3":"0 (None)"} 02:14:30 MQT: tele/sonoff/STATE = {"Time":"2018-02-15T02:14:30","Uptime":"0T03:40:14","Vcc":3.025,"POWER1":"ON","POWER2":"OFF","POWER3":"OFF","POWER4":"OFF","Wifi":{"AP":1,"SSId":"TheIoaks","RSSI":100,"APMac":"xXx"}} 02:15:15 MQT: stat/sonoff/STATUS = {"Status":{"Module":23,"FriendlyName":"Sonoff1","Topic":"sonoff","ButtonTopic":"0","Power":1,"PowerOnState":3,"LedState":1,"SaveData":1,"SaveState":1,"ButtonRetain":0,"PowerRetain":0}} 02:15:26 MQT: stat/sonoff/RESULT = {"POWER4":"ON"} 02:15:26 MQT: stat/sonoff/POWER4 = ON 02:15:43 MQT: stat/sonoff/STATUS = {"Status":{"Module":23,"FriendlyName":"Sonoff1","Topic":"sonoff","ButtonTopic":"0","Power":9,"PowerOnState":3,"LedState":1,"SaveData":1,"SaveState":1,"ButtonRetain":0,"PowerRetain":0}} `

GeorgeIoak avatar Feb 15 '18 01:02 GeorgeIoak

02:15:26 MQT: stat/sonoff/RESULT = {"POWER4":"ON"}

There's the magic ticket. When parsing the response within the callback function, it's simply looking if status.Power == "ON". Me not having a 4CH I thought this was good. I will have to change that comparison according to the power channel.

Something like def on = status."Power${state.powerChannel}" == ""ON" ...

But I'm on my phone. Not sure if I'll get to it tonight.

Oh yeah, and there is the special case if power channel is channel 1 (and no other channels) it would also have to do the comparison as the way it is now.

BrettSheleski avatar Feb 15 '18 01:02 BrettSheleski

If you're following what I said above feel free to make a pull request with the fix. It should be simple.

BrettSheleski avatar Feb 15 '18 01:02 BrettSheleski

I'm following what you're saying but I might not get to it tonight. Mental note that "we" need to change the Thing name from all being "Tasmota-Power" to something TasPower-1, TasPower2, ...

I see that you have GPIO interface thrown in there too so tomorrow I'll hook up a DS18B20 temp sensor on one of the GPIO pins and see if we can get that data to pass through too!

GeorgeIoak avatar Feb 15 '18 02:02 GeorgeIoak

Yeah, naming needs to be implemented yet. Should be simple, just gotta do it.

The master device will need to actually to parse the gpio configuration. Currently it's just doing per-module configuration.

Also, for temperature sensor a new device handler will be needed. It should also be able to be used by the Sonoff-TH modules as well.

Give it a shot at creating the handler. I created a stub of a device handler to base things off of, it may help.

BrettSheleski avatar Feb 15 '18 02:02 BrettSheleski