SmartThings Community

Shelly wifi device integration


(JP) #41

Hi Patrick.
Yes is something like that.
Y have one shelly working with your device handler perfect.
And I have a Shelly 2, so I make a change on you device handler to be able to use the relay1.
When I create two switches on with relay 0 and other with relay1 the switch pointing to the relay1 sometimes work and sometimes no.
I change the network Id an everything but I was not able to have that working 100% of the time.

Copy of the device handler.


(JP) #42

/**

  • Shelly1
  • Copyright 2018
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.

*/
metadata {
definition (name: “Shelly1or2”, namespace: “patrickkpowell”, author: “Patrick Powell”) {
capability “switch”
attribute “ip”, “string”
}

simulator {
// TODO: define status and reply messages here
}

tiles(scale: 2) {
// standard tile with actions named
standardTile(“switch”, “device.switch”, width: 2, height: 2, canChangeIcon: true) {
state “off”, label: ‘{currentValue}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff" state "on", label: '{currentValue}’, action: “switch.off”,
icon: “st.switches.switch.on”, backgroundColor: “#00a0dc
}

  // the "switch" tile will appear in the Things view
  main("switch")
}

preferences {
    input("ip", "string", title:"Address", description:"Please enter your Shelly's I.P. address", defaultValue:"" , required: false, displayDuringSetup: true)
    input(name: "Relay", type: "enum", title:"Relay", options: ["0","1"], displayDuringSetup: true)
	section() {
		input("HTTPAuth", "bool", title:"Requires User Auth?", description: "Choose if the HTTP requires basic authentication", defaultValue: false, required: true, displayDuringSetup: true)
		input("HTTPUser", "string", title:"HTTP User", description: "Enter your basic username", required: false, displayDuringSetup: true)
		input("HTTPPassword", "string", title:"HTTP Password", description: "Enter your basic password", required: false, displayDuringSetup: true)
	}
}

}

def parse(description) {
log.debug “Parsing result”
def msg = parseLanMessage(description)

def headersAsString = msg.header // => headers as a string
def headerMap = msg.headers      // => headers as a Map
def body = msg.body              // => request body as a string
def status = msg.status          // => http status code of the response
def json = msg.json              // => any JSON included in response body, as a data structure of lists and maps
def xml = msg.xml                // => any XML included in response body, as a document tree structure
def data = msg.data              // => either JSON or XML in response body (whichever is specified by content-type header in response)
//log.debug data.ison

//log.debug "Message Headers String "+headersAsString
//log.debug "Message Headers Map "+headerMap
//log.debug "Body "+body
//log.debug "Status "+status
//log.debug "JSON "+json
//log.debug "XML "+xml
//log.debug "Data "+data

if ( data.ison == true ) {
  log.debug "TRUE"
  sendEvent(name: "switch", value: "on", isStateChange: true, displayed: false)
}
if ( data.ison == false ) {
  log.debug "FALSE"
  sendEvent(name: "switch", value: "off", isStateChange: true, displayed: false)
}

}

// handle commands
def off() {
log.debug “Executing ‘off’”
toggleRelay “turn=off”
}

def on() {
log.debug “Executing ‘on’”
toggleRelay “turn=on”
}

def toggleRelay(action) {
sendHubCommand(new physicalgraph.device.HubAction(
method: “POST”,
path: “/relay/”+Relay,
body: action,
headers: [
HOST: getHostAddress(),
“Content-Type”: “application/x-www-form-urlencoded”
]
))
result
}

private getHostAddress() {
log.debug “Using IP: ip and PORT: 80 for device: {device.id}”
device.deviceNetworkId = convertIPtoHex(ip)+":"+convertPortToHex(8+Relay)
log.debug device.deviceNetworkId
return ip+":80"
}

private String convertIPtoHex(ipAddress) {
String hex = ipAddress.tokenize( ‘.’ ).collect { String.format( ‘%02x’, it.toInteger() ) }.join()
log.debug “IP address entered is $ipAddress and the converted hex code is $hex”
return hex

}

private String convertPortToHex(port) {
String hexport = port.toString().format( ‘%04x’, port.toInteger() )
log.debug hexport
return hexport
}

def updated() {
log.debug “updated()”
unschedule()
runEvery1Minute(“poll”)
poll()
}

def refresh() {
getStatus()
}

def poll() {
getStatus()
}

def getStatus() {
log.debug “Polling”
sendHubCommand(new physicalgraph.device.HubAction(
method: “GET”,
path: “/relay/”+Relay,
headers: [
HOST: getHostAddress(),
“Content-Type”: “application/x-www-form-urlencoded”
]
))
}

def push() {
sendEvent(name: “switch”, value: “on”, isStateChange: true, displayed: false)
sendEvent(name: “switch”, value: “off”, isStateChange: true, displayed: false)
sendEvent(name: “momentary”, value: “pushed”, isStateChange: true)
}


(Patrick Powell) #43

JP,
Thanks for the mods. I noticed that you pass the Relay variable in for the second digit of the port. Is that how the Shelly 2 works? To access Relay 1 you connect to port 81? I thought it was just the rest endpoint being /relay/[0|1].

Was suddenly having an issue with parse() not getting called. The hexIP:hexPort need to be all upper case (or maybe just the same case). I saw this in a post earlier and thought I had done that but apparently I hadn’t. The .toUpperCase() calls below fixed the issue.

private String convertIPtoHex(ipAddress) {
String hex = ipAddress.tokenize( ‘.’ ).collect { String.format( ‘%02x’, it.toInteger() ) }.join().toUpperCase()
log.debug “IP address entered is $ipAddress and the converted hex code is $hex”
return hex
}

private String convertPortToHex(port) {
String hexport = port.toString().format(’%04x’, port.toInteger()).toUpperCase()
log.debug hexport
return hexport
}

Also, I don’t see a reference in the Shelly2 API docs that show that the port is ever anything other than 80 so I am going to leave that part set to port 80 for the time being.


(JP) #44

Hi Patrick,
Yes the port is 80, I add the 8+relay on the networkId only because if you add 2 device handler with the same network ID the 2 devices stop working or send you an error.
Because the idea was to create 2 different devices if you have the shelly 2 one with relay 0 and other with relay 1.
I use actiontiles and Google home and if I add the 2 switch on the same device works perfect but actiontiles only show me one and google home the same.

Let me know if it works for you.
Regards


(jason ) #45

I purchased 4 of the Shelly1 switches. I would love to get them working in ST, I see Ryan780 has updated an ino file to include the shelly1 but not sure what to do with it.

I have flashed sonnoff basic switches before and all went well. But its been a while and would like to know what firmware to use on these shelly switches etc…

any help would be appreciated

https://github.com/erocm123/SmartThingsPublic/tree/master/devicetypes/erocm123/sonoff-wifi-switch.src


(Patrick Powell) #46

Gotcha, I’ll take another look at that. I only have Shelly 1s right now so I can’t test it.


(jason ) #47

Patrick, is there any downside to using the shelly1 switches the way you are vs the firmware method?

thanks


#48

The file i put together is the firmware.


(jason ) #49

Thanks Ryan, I just got confused when it wasn’t a bin file. So I just flash it and should be basically the same as the sonoff from there on?


#50

No, you have to use the Arduino IDE to send the file to your Sonoff.


(jason ) #51

Yes thats what I used to send files to the sonoff. Thanks I will give it a try.


(Patrick Powell) #52

Joson,
Honestly I haven’t flashed tasmota on the Shelly although I have done other devices so I can’t really compare apples to apples. I do have some limitations with this device handler at this time as stated above. Most notably for me is the Shellys are not discoverable from within Smartthings and there is some manual setup for each one. Also the refresh only happens once per minute. Not sure if this is the case with other methods. I basically learned how to write device handlers doing this one so I’m sure there is a way to rectify these issues. I just haven’t had the time. JP has been helpful in modifying it to support the Shelly 2 as well. Hopefully Shelly will officially support Smartthings integration in the future and this won’t be an issue anymore.

I did tasmota on some sonoffs a while back.

I found that there are different flashing methods that need to be used depending on the firmware of the device. They didn’t allow stock downgrades so after researching and trying multiple different methods I boiled it down to the one for my set of sonoffs firmware. Once I got that done tasmota itself needed to be adjusted correctly and a few other nit-noid things that I can’t remember at the moment.

I felt like I was going to have to chase that firmware issue for every set I bought so I try to stay native on the devices where I can. Shelly offers a nice API for that so I figured I’d use it.

Hope that helps explain my logic for going this route although if you prefer another it’s all good.


(jason ) #53

Thanks Patrick

I would love to hear from anyone who has successfully flashed Ryan’s bin file to a shelly. But I dont mind being the guinea pig just need to find the time:)


#54

I’m interested in using the shelly 4 pro and that isnt ESP based. So the REST api will be the best/only way to use it.
There was a great video of someone explaining how to use the REST api to create seamless integration with HOME ASSISTANT. Reading Patrick’s code it looks like how he is writing the solution and for me the simplest solution for what we need in smartthings. Re people using Tasmota; tasmota needs a different device handler which is pointed to on the tasmota wiki and that works fine with smartthings. BUT tasmota doesnt use REST (afaik) and so it wont work with patrick’s device handler.

Ive already got sonoff touches with tasmota; custom esp devices for milights and for my own switches and sensors that I built, but something for wifi control on a DIN rail would be useful for another project I have. So this device handler would be perfect to enable me to justify the shelly devices.

@patrickpowell - two things…

  1. the guys says in the video about poling to get the status… he recommends around 5 seconds (if I remember correctly!) @ around 3’30 into the video.
  2. are you looking to poll the power useage on the shelly 2?
    when you get this all working, I should have got my Shelly 4 Pro (havent ordered yet as out of stock till jan) and to I’ll take a branch then and see if I can get it to work on the 4 pro.

Curious about the fact you cant operate Relay/1 and instead use ports… wonder if it is a bug in the IDE have you contacted support to see if it is expected behaviour?

keep up the good work.

R.


(Patrick Powell) #55

Richierich,
I watched this video and I think your right but here I am right now:

  1. the guys says in the video about poling to get the status… he recommends around 5 seconds (if I remember correctly!) @ around 3’30 into the video.

ST/groovy seems to offer some helper scheduling methods like runEvery1Minute(“poll”) which is what I’m using right now. There was also some cron style scheduling capabilities but I still was only able to check every minute. I think that maybe doing something like staggering 6 scheduled polls within 10 seconds of each other to poll may be the only way to do this but not sure.

  1. are you looking to poll the power useage on the shelly 2?
    when you get this all working, I should have got my Shelly 4 Pro (havent ordered yet as out of stock till jan) and to I’ll take a branch then and see if I can get it to work on the 4 pro.

I haven’t looked at this yet since I only have Shelly 1’s at the moment.


(Patrick Powell) #56

JP,
I added the 8+Relay variable back into the code on github

Same link as before.


(Duccio) #57

Hi all,

starting from the work of PatrickPowell (thanks a lor!) I wrote a device handler for the Shelly 2 configured as a roller shutter for curtains or garage doors.

It works but it still has issues with refreshing… can’t manage to update the current status when the smartthings app is opened

You can find the source code here:

Duccio


#58

Hi
I have just ordered my shelly 1 and shelly pro 4 and should get them with the next batch in mid jan.
I can do any testing so I cant really do much with the code, however I wanted to suggest a couple of things…

  1. Can we make the devices child devices which are configures based upon the device selected.
    You can use the

GET /shelly

    command and look at the ‘type’ and then use a case statement to define the type setup.

Have a look at how Brett does it with his sonoff-tasmota smarthings devices…

  1. Using the child devices for each channel will mean they can be individually renamed and configured. This means if we create a ‘power’ child driver which turns on and off the switch we can also create a ‘power+energy’ which both powers the switch and polls it regularly for the energy usage on devices which can use this function. You only create the tile if the function exists.

Taking this approach, people can add to the core by creating the child devices to do what they need, eg roller shutters vs switches.

Just a thought!

If no one wants to start this off, I’ll take a look in February when I have the time and the devices to play with.


(Kevin [Yorkshire UK]) #59

Shelly 4 Pro has inbuilt MQTT too.


(Daniel Diefenderfer) #60

I just received Shelly1 devices and pulled the current firmware version. Anyone know what needs to be updated in the code?

PS - I’d rather get this going than using the Google Home/Shelly Cloud integration as it’s extra commands that are needed vs using Smartthings and just telling google to “Turn on Kitchen Light”