Shelly wifi device integration

I ported your DH to Hubitat… I hope that is ok because both work like a champ !!

Can someone explain me how to add shelly not tasmota to ST? I have never done before, so I need step by step guide. Im Italian and we dont have forums for ST

Hello On ST I cant define if I want the windows at 35%, only open or close, is it correct?

thaks.

In Shelly facebook support page they claim that Smartthing official integration is soon, lets hope that is true.

" Smartthing official integration is on the way, we expect to be done in 3-4 weeks"

Hi Everyone!

I am using the DH of dgasparri with great success as normal switches (https://github.com/dgasparri/SmartThingsPublic/blob/master/devicetypes/shelly/shelly2.src/shelly-as-switch.groovy)

Could somebody help how can this DH modified to have Shelly to close the circuit only for a few seconds. Currently I am using it to control a garage door and in the Shelly own app I use the preference of auto off with 0.5 sec, it is working really fine, so I thought it could be somehow easy to integrate in the DH this auto-off option, but unfortunately I am not a programmer, I have no idea what to write and where in the code. Could somebody help?

1 Like

Hi!

I was able to do it and use Shelly as a normal switch (on/off).

  1. go to this ide page and sign in: https://graph.api.smartthings.com/
  2. choose your location
  3. go to the My device handler
  4. go to +Create a new Device Handler
  5. Choose from Code
  6. copy this Device Handler from this page (from the raw): https://github.com/dgasparri/SmartThingsPublic/blob/master/devicetypes/shelly/shelly2.src/shelly-as-switch.groovy
  7. Push Create
  8. Push Publish/For Me
  9. Go to My device/New device
  10. Give it a name and id (whatever you want)
  11. As Type choose the Shelly as switch (probably last one)
  12. Select Location/Hub
  13. Push Create
  14. After that you chose Edit in the Preferences section (define the IP of the given Shelly device -> you can find it in the Shelly app at Settings/Device information, you should give a fix ip in your router to the Shelly, and choose channel 0 in case you have Shelly1).
  15. That’s it, after that you can see the device in you Smartthin app and click on/off
2 Likes

Hi there, It’s work with out flashing?
Regards!

If the question is for me, then YES. I have never flashed my Shellys.

Can anybody help me in this matter? I think there should be an easy solution (once it is working as a normal switch), just I am not capable to solve it due to the reason that I do not understand groovy-s, I am only copy-paste them.

Thank you @Coolby. I’ll recive mine next week. I’ll give it a try!
Regards

Nobody can help in this matter?

Hello @Coolby, have you tried Webcore? I have solved it with that. (With a sonoff’s switch, but it will be the same).

In this example I am using a virtual contact sensor, but it is not necessary. Switch 10 is the sonoff switch. In your case it will be the shelly’s switch. After 2 seconds it automatically turns it off.

Hope can help!
Regards

Thx, I will check it, but currently I do not use webcore, I need to start it from the ground. I hoped somebody could add a line for these device handler (https://github.com/dgasparri/SmartThingsPublic/blob/master/devicetypes/shelly/shelly2.src/shelly-as-switch.groovy) to have auto off, but it seems nobody can or it is not as simple as I thought.

This driver should work but I would not recommend using such a short on-off cycle. You’re talking about a WiFi device not a zigbee or z-wave one. I think the fastest response time you are going to get is 1-2 seconds.

/**
 *  Shelly as Switch Device Handler
 *
 *  Copyright 2018 DUCCIO GASPARRI
 *
 *  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.
 *
 *
 *
 * Shelly http POST at http://IP/relay/0 ( can be 0/1 for shelly 2) with body form-urlencoded:
 *   turn=on
 *   turn=off
 *   ison=boolean
 *
 */
 
 

metadata {
	definition (name: "Shelly as Switch", namespace: "dgasparri", author: "Duccio Marco Gasparri") {
		capability "Actuator"
		capability "Sensor"
        capability "Refresh" // refresh command
        capability "Health Check"
        capability "Switch"
	}



    tiles(scale: 2) {
        multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
            tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
                attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#00A0DC", nextState:"turningOff"
                attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#FFFFFF", nextState:"turningOn", defaultState: true
                attributeState "turningOn", label:'Turning On', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#00A0DC", nextState:"turningOn"
                attributeState "turningOff", label:'Turning Off', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#FFFFFF", nextState:"turningOff"
            }
        }

        standardTile("explicitOn", "device.switch", width: 2, height: 2, decoration: "flat") {
            state "default", label: "On", action: "switch.on", icon: "st.Home.home30", backgroundColor: "#ffffff"
        }
        standardTile("explicitOff", "device.switch", width: 2, height: 2, decoration: "flat") {
            state "default", label: "Off", action: "switch.off", icon: "st.Home.home30", backgroundColor: "#ffffff"
        }

        standardTile("refresh", "device.refresh", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
            state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh", nextState: "disabled"
            state "disabled", label:'', action:"", icon:"st.secondary.refresh"
        }


        main(["switch"])
        details(["switch", "explicitOn", "explicitOff","refresh"])

    }


    preferences {
        input("ip", "string", title:"IP", description:"Shelly IP Address", defaultValue:"" , required: false, displayDuringSetup: true)
        input("channel", "string", title:"Channel", description:"Channel (only for Shelly2):", defaultValue:"0" , required: false, displayDuringSetup: true)
		input("autoOff", "bool", title:"Auto-off",description:"Enable for auto-off function.", defaultValue:false, required: false, dispalyDuringSetup: true)
		input("autoOffTime", "number", title:"Auto-off Time", description:"Time (in seconds) for auto-off function.", defaultValue: "0", required: false, displayDuringSetup: true)
    }

}


def getCheckInterval() {
    // These are battery-powered devices, and it's not very critical
    // to know whether they're online or not – 12 hrs
    log.debug "getCheckInterval"
    return 4 * 60 * 60
}

def installed() {
    log.debug "Installed"
    sendEvent(name: "checkInterval", value: checkInterval, displayed: false)
    refresh()
}

def updated() {
    log.debug "Updated"
    if (device.latestValue("checkInterval") != checkInterval) {
        sendEvent(name: "checkInterval", value: checkInterval, displayed: false)
    }
    refresh()
}


def parse(description) {
    log.debug "Parsing result $description"
    
    def msg = parseLanMessage(description)

    // log.debug "Lan message $msg"
    // headers:[content-length:172, http/1.1 200 ok:null, connection:close, content-type:application/json, server:Mongoose/6.11], 
    // body:{"state":"close","power":0.00,"is_valid":true,"safety_switch":false,"stop_reason":"normal",
    //    "last_direction":"close","current_pos":46,"calibrating":false,"positioning":true}, 
    // header:HTTP/1.1 200 OK 
    
 
    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 data = msg.data              // => either JSON or XML in response body (whichever is specified by content-type header in response)
    
    log.debug "Data"
    log.debug data
    
    def evt1 = null
    if ( data.ison == true ) {
        log.debug "CreateEvent ison=true"
        evt1 = createEvent(name: "switch", value: "on", displayed: false)
    } else  {
        log.debug "CreateEvent ison=false"
        evt1 = createEvent(name: "switch", value: "off", displayed: false)
    }

    return evt1
}


//switch.on
def on() {
    log.debug "Executing switch.on"
    sendSwitchCommand "turn=on"
	if (autoOff){
		def myDelay = toInteger(autoOffTime)
		runIn(myDelay, off)
	}
}

//switch.off
def off() {
    log.debug "Executing switch.off"
    sendSwitchCommand "turn=off"
}



def ping() {
    log.debug "Ping"
    refresh()
}

def refresh() {
    log.debug "Refresh - Getting Status"
    sendHubCommand(new physicalgraph.device.HubAction(
      method: "GET",
      path: "/relay/" + channel,
      headers: [
        HOST: getShellyAddress(),
        "Content-Type": "application/x-www-form-urlencoded"
      ]
    ))
}

def sendSwitchCommand(action) {
    log.debug "Calling /relay/ with $action"
    sendHubCommand(new physicalgraph.device.HubAction(
      method: "POST",
      path: "/relay/" + channel,
      body: action,
      headers: [
        HOST: getShellyAddress(),
        "Content-Type": "application/x-www-form-urlencoded"
      ]
    ))
    runIn(25, refresh)
}


private getShellyAddress() {
    def port = 80
    def iphex = ip.tokenize( '.' ).collect { String.format( '%02x', it.toInteger() ) }.join().toUpperCase()
    def porthex = String.format('%04x', port.toInteger())
    def shellyAddress = iphex + ":" + porthex
    device.deviceNetworkId = shellyAddress.toUpperCase()
    log.debug "Using IP " + ip + ", PORT 80 and HEX ADDRESS " + shellyAddress + " for device: ${device.id}"
    return device.deviceNetworkId
}

DISCLAIMER: I don’t have the device so i haven’t been able to test it. I have confirmed it saves to the IDE, that is all.

Thanks. You are great. Now I am not home, but I will test it. Auto-off 0.5 sec is currently used without problem with Shelly app, which uses wifi connection (however cloud can be faster at Shelly).

Thanks a lot

1 Like

Hi,

iam using the patrick powell DTH and everything works fine for me …
the only thing is, that every few minutes, i get a switch on and off event … (the switch physically does not turn on and off) - but my routines and smartapps are getting in trouble …

Imgur

what to do to solve this issue ?

thanks,

matthias

For me its weird, i do not have these automatic on/off events. Is there no smartapp, routine running?

Dear Ryan. Thank you for the dh. It is working fine. I am using it now for a while. I have only one issue, namely: the autó turn-off is working, but the button in the app is still on/off, so when I push from off-to-on it gives the 0.5sec signal (my gate opens), but the switch remains on, when I push again it does nothing just it changes from on-to-off, and after that I should push again to change from off-to-on to send the signal (close the gate). Is there any way to make it in the app as a real toggle switch?

What do you have the autoOff time set to?

There is one line you should change in the DTH.

Change this:

def myDelay = toInteger(autoOffTime)

To:

def myDelay = settings.autoOffTime.toInteger()