BrettSheleski / SmartThingsPublic

36 stars 23 forks source link

New Tasmota SmartApp and Device Handlers #9

Open BrettSheleski opened 6 years ago

BrettSheleski commented 6 years ago

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 commented 6 years ago

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

GeorgeIoak commented 6 years ago

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?

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

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)

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

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 commented 6 years ago

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

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

Should be:

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

BrettSheleski commented 6 years ago

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

(see 7831d14c61341ca12245c286861bd7253d2d4617 )

GeorgeIoak commented 6 years ago

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 commented 6 years ago

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

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

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

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

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 commented 6 years ago

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

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

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

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

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

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

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 commented 6 years ago

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

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

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}} `

BrettSheleski commented 6 years ago

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 commented 6 years ago

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

GeorgeIoak commented 6 years ago

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!

BrettSheleski commented 6 years ago

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.

GeorgeIoak commented 6 years ago

I tried a quick change but it doesn't appear to have worked. In Tasmota-Power I did this:

` def setPowerCallback(physicalgraph.device.HubResponse response){ log.debug "Finished Setting power, JSON: ${response.json}" //def on = response.json.POWER == "ON"; def on = status.Status.Power${state.powerChannel} == "ON";

setSwitchState(on);

} `

BrettSheleski commented 6 years ago

I updated the power device handler, the status should be updating properly now after turning on/off any power device.

GeorgeIoak commented 6 years ago

Yep, I left a comment on the commit

rmcvay30 commented 6 years ago

First off, thank you, the handler works very nicely and great job! one minor issue Using sonoff-tasmota-4ch.groovy at https://github.com/BrettSheleski/SmartThingsPublic/blob/master/devicetypes/BrettSheleski/sonoff-tasmota-4ch.src/sonoff-tasmota-4ch.groovy. I had an issue with the graphics on the phone staying green and never changing to off. I switched the lines starting with attribute "on" and attribute "off" and now the state changes on the phone. just an FYI

BrettSheleski commented 6 years ago

Take a look at the 'Tasmota' device handlers if interested. They're still a work in progress as I'm struggling getting things working right from initial SmartApp/Device installation for some reason. But it's the direction I want to go to hopefully handle all Tasmota-compatible (not just Sonoff) devices.

Also, if you feel inclined, there's plenty of opportunity to contribute to help out for specific module/device implementation.

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

digiblur commented 6 years ago

Very cool! I currently have a few Sonoff basics using that "other" closed source firmware in the Smartthings community. They do work well but I don't like the closed source especially when the author doesn't respond in the thread anymore. Been looking for an alternative such as Tasmota with possibly some added code to work natively in ST and send their power states to ST, etc, and yet still be able to do the MQTT thing for HAS as I use both for many reasons. Definitely going to check your stuff out and see what I can contribute.

BrettSheleski commented 6 years ago

One issue currently with my 'old' device handler is that if you toggle the Sonoff device by other means (not using the SmartThings app) the status does not get synced with SmartThings. Therefore you may turn off a device using MQTT/whatever but the device will still be reported to SmartThings as on.

With the new 'Tasmota' implementation I've been working on there will be a SmartApp driving everything which will end up exposing an HTTP endpoint to update the status from. It would be pretty simple to do something in Node-Red to listen to an MQTT topic for whenever the device/devices update and pass that off to the HTTP endpoint and thus update the SmartThings status of the device(s).

That part currently isnt working now, but it is in the plans.

digiblur commented 6 years ago

Have you tried the port 39500 method? This is what I was planning on doing. Have the smartapp set the DNI to the MAC of each Tasmota and rock on. Of course something would need to be added into Tasmota to talk back to ST but I'm sure the developer of Tasmota wouldn't mind doing something like that.

https://community.smartthings.com/t/how-can-i-receive-lan-messages-on-the-st-hub-when-the-messages-can-come-at-any-point/54912/9

BrettSheleski commented 6 years ago

I have not. However I don't think that will work since in my approach multiple SmartThings devices may be associated to a single Tasmota device (eg: Sonoff 4CH & 4CH Pro). Since network device ID's need to be unique, all 4 devices for the 4CH cannot have the same network device ID, thus this will not work.

digiblur commented 6 years ago

Ahh I bet you are right, I was being short sighted and just thinking about the basic.

Wonder how it was done in this closed source firmware? I don't a have 4CH to see. https://community.smartthings.com/t/release-sonoff-sonoff-th-s20-dual-4ch-pow-touch-device-handler-smartapp-5-10-smart-switches/45957

GeorgeIoak commented 6 years ago

You can just flash a generic ESP8266 module and check it out.

Sorry Brett, been busy messing with Home Assistant and trying to get that working so I haven't pulled your latest commits to test. I was messing with Amazon Alexa integration and I noticed a TON of Sonoff power 1(2,3,4) and Tasmota Switch - Channel 1 (2,3,4) and Tasmota-Power devices. Not sure if they came from our testing or me messing with HA.

BrettSheleski commented 6 years ago

No worries, I haven't made any meaningful progress recently. I'm trying to figure out why things don't work on the initial setup without doing a re-install/update of the smartapp. Also been refactoring some code to do things in other ways too.

I've found the Alexa integration with SmartThings to work pretty solidly. I haven't had issues with it seeing duplicate devices. So long as you got the devices configured in SmartThings you should be good to go.

I personally haven't gone down the Home Assistant route much. I installed it on my Linux box and basically decided to abandon it and stick to one ecosystem (SmartThings). For now at least.

BrettSheleski commented 6 years ago

@georgeloak, check out the latest. I think I got everything working from the simulator. However, when I go to install it for real using the SmartThings app, not so much.

GeorgeIoak commented 6 years ago

Here's what I have in ST IDE right now: image

I think I need to remove the Tasmota-Base now, right?

BrettSheleski commented 6 years ago

It shouldn't hurt if it's there. That file only exists for others to use as a starting point for making additional device handlers. One should copy that file, rename it appropriately, change the device name, etc.

Also, if you don't have an RF bridge device, you won't need that handler either. Basically you only need the 'Tasmota' device handler and any additional handlers appropriate for your hardware. For most devices one would want the Tasmota-Power handler in addition to the Tasmota handler.

GeorgeIoak commented 6 years ago

I haven't touched that Tasmota-Base handler so it's still there for now. I copied in the new codes for the other handlers and the SmartApp and published each item. I then went to the ST Mobile App and tried to toggle one of the channels but it doesn't seem to be working. Here's the log information for the ST IDE:

6:28:19 PM: debug Setting switch to OFF
6:28:19 PM: debug Finished Setting power (channel: null), JSON: [Command:Unknown]
6:28:05 PM: debug Setting switch to OFF
6:28:05 PM: debug Finished Setting power (channel: null), JSON: [Command:Unknown]
6:28:03 PM: debug COMMAND: Powernull (toggle)
6:28:03 PM: debug Setting power to: toggle
6:28:04 PM: debug createCommandAction(Powernull:toggle) to device at 192.168.10.46:80

In the Sonoff Console I see this:

18:28:04 MQT: stat/sonoff/RESULT = {"Command":"Unknown"}
18:28:19 MQT: stat/sonoff/RESULT = {"Command":"Unknown"}
18:31:58 MQT: tele/sonoff/STATE = {"Time":"2018-02-21T18:31:58","Uptime":"2T07:40:13","Vcc":3.026,"POWER1":"OFF","POWER2":"OFF","POWER3":"OFF","POWER4":"ON","Wifi":{"AP":1,"SSId":"TheIoaks","RSSI":100,"APMac":"xx:XX:xx"}}
18:31:58 MQT: tele/sonoff/SENSOR = {"Time":"2018-02-21T18:31:58","DS18B20":{"Temperature":78.1},"TempUnit":"F"}
BrettSheleski commented 6 years ago

I rethought about this last night and reapproached things slightly.

Instead of installing SmartApp which installs a "Master" device, which installs any module-specific children, one should install the "Tasmota" device directly. After installation, it will spawn child devices depending on the module.

If you have multiple Tasmota devices, install them as you did the first.

The SmartApp would be an optional component which one would install and associate it with any previously-configured Tasmota device(s). The SmartApp's purpose would be to expose an HTTP endpoint that something like Node-Red could use to send status changes to SmartThings for SmartThings to update the status of its devices.

The SmartApp isnt fully implemented yet, but you should be able to install the Tasmota device successfully now.

BrettSheleski commented 6 years ago

I think I got things working pretty well now, at least in my situation.

The Tasmota device handler spawns off the child device(s) as necessary allowing the user to toggle on/off the device(s) within the SmartThings App. This seemingly works pretty well.

I just updated the SmartApp to allow for the status of the device(s) to be updated by external trigger. In order to do so, you will have to install the Tasmota SmartApp in the SmartThings IDE. During the installation of the SmartApp, select the Tasmota devices for which the SmartApp should update status for. Once installed, you will need to click the App Settings button, click the OAuth link, and enable OAuth. After doing so you will need to know the Client ID and Client Secret fields (which are auto-generated).

There may be a better option to the following, but here's how I got it working: Open the SmartApp in the simulator. Once the SmartApp is installed in the simulator, it will show you the API Token and API Endpoint. These two values will need to be known. In Node-Red I then created a flow where it would listen to the MQTT topic of stat/<DEVICE-TOPIC>/POWER. Which feeds into a function with the following:

var httpMessage = {}

httpMessage.headers = {};
httpMessage.headers['Authorization'] = 'Bearer <API_TOKEN>';
httpMessage.headers['Content-Type'] = "application/json";

httpMessage.payload = msg;

return httpMessage;

Then feed into an HTTP Request Node with URL set to: <API_ENDPOINT>/status.

Complete Node-Red Flow JSON (Can be copied and pasted into your Node-Red):

[{"id":"fff8714a.4e72a","type":"mqtt in","z":"5bff2855.44a8c8","name":"My Device","topic":"stat/<DEVICE-TOPIC>/POWER","qos":"2","broker":"8833406a.5e73","x":135,"y":779,"wires":[["e6f75503.e3c348"]]},{"id":"15f93bfe.9d8fe4","type":"http request","z":"5bff2855.44a8c8","name":"POST to SmartThings","method":"POST","ret":"obj","url":"<API_ENDPOINT>/status","tls":"","x":503.5,"y":996,"wires":[[]]},{"id":"4a25d9a8.7c09f8","type":"function","z":"5bff2855.44a8c8","name":"Set HTTP Headers","func":"var httpMessage = {}\n\nhttpMessage.headers = {};\nhttpMessage.headers['Authorization'] = 'Bearer <API_TOKEN>';\nhttpMessage.headers['Content-Type'] = \"application/json\";\n\nhttpMessage.payload = msg;\n\nreturn httpMessage;","outputs":1,"noerr":0,"x":383,"y":929,"wires":[["15f93bfe.9d8fe4"]]},{"id":"e6f75503.e3c348","type":"function","z":"5bff2855.44a8c8","name":"If Payload Is NOT JSON","func":"try{\n    JSON.parse(msg.payload)\n}\ncatch(e){\n    return msg;\n}\n\nreturn;","outputs":1,"noerr":0,"x":226,"y":868,"wires":[["4a25d9a8.7c09f8"]]},{"id":"8833406a.5e73","type":"mqtt-broker","z":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]

After doing so, whenever the Tasmota device is triggered (either via SmartThings, or externally), the Node-Red flow kicks in (triggered by the MQTT message) which makes an HTTP request to the SmartThings SmartApp, which parses the message and updates the appropriate device(s).

I will make a write-up on this in the readme.md documenting the necessary steps once things settle into place. I also would like to do the "proper" OAuth handshake instead of copying/pasting stuff from the SmartThings simulator.

jymbob commented 6 years ago

Just a comment on the MAC:PORT update method mentioned by @digiblur - it looks like the other sonoff firmware (erocm123) handles the 4CH use case by having a parent DTH for the 4CH which passes on/off messages to its own children. You can find the relevant groovy code here at lines 167-176. I have a basic, touch and a 4CH pro here which I would be happy to do some testing with.

BrettSheleski commented 6 years ago

I glanced at that device handler and it looks to setting the device network ID to the IP:Port format. This is needed to use the parse() method to handle HTTP responses. My "old" device handler handles HTTP responses in the same manor.

This device handler uses the sendHubCommand() method and specifying a callback method to call with the HTTP response. This gets around needing to set the NetworkDeviceId (which I don't like), and is easier to develop/maintain.

Regardless though, neither case will cause the SmartThings DeviceHandler to update when the device is triggered by means outside of the SmartThings app. The only way I see this happening is having the firmware on the Sonoff device itself make a call to SmartThings telling it it's new state. This would obviously require a change to the device firmware itself.

The Tasmota firmware is already sending off messages via MQTT. One approach I've been successful with so far is using Node-Red and create a flow to make an HTTP call to a SmartThings SmartApp.

If you're able to do some testing, please do. I only have Sonoff Basic and Sonoff RF Bridge models. Both are working with this new Device Handler. @GeorgeIoak seems to have been using a 4CH with this Device Handler and sounds like it is working for him.