WeMo Insight Switches

Is this still working for you guys? I just tried install it, but my wemo insight device doesn’t show any power / energy info, and the state of button on/off doesn’t change.
It seems I can turn it on, but I can’t turn it off either.
All help is appreciated, Im willing to make a donation to someone who can make it work for me.
Thanks.

I have a WEMO Switch, Insight and bulbs all working OK to my st hub.
I have stopped using the WeMo’s via their app and rules as believe it or not, they don’t always trigger, go missing and are generally a crock of sh*t.
Through the ST hub things work 99% of the time for me.
The Belkin support is also appalling. If you think ST could be better they are streets ahead of Belkin’s support. (But I digress). :blush:

Any chance you can give me a heads up what you’ve done? step by step? I would love to get the memo insight switches working, which I have quite a few of already.
Thanks in advance, I would gladly make a paypal payment to you for your trouble if it works out.
PS: I have hub version 1 if it matters.

I did a factory reset on all devices.
On the switch and Insight this is done by powering off, holding in the rest button, powering on and keeping the reset button pushed in for 10 seconds. This gets them back to factory reset.
I then configured them using the wemo app. This then has them paired to the router.
On my router I gave the devices a fixed IP Address. This was mainly done because of issues I had with the devices losing connectivity to the wemo app when I was using it.
In the ST App I went into:-
Marketplace -> Things -> Lights & Switches -> Outlets -> Belkin -> Belkin WeMo Switch -> Connect Now.
This is when I needed a bit of patience. Sometimes it finds it OK almost immediately, sometimes I had to unplug/plug in the Insight and just leave it while I had hit ‘Connect Now’.
It would find it though.
What does happen is that it can occasionally go ‘Offline’ in the ST App so I have used ‘Pollster’ to refresh the device every 15 minutes.
I then use Smart Lighting ‘rules’ to control it.
I have not tried using the apps mentioned in earlier posts as I just want it as a switch and do not need to see power usage etc.
Hope this helps.
BTW. I did have to change some config on my hub when I was using the Insight through the WeMo app as it would continually go missing. I think it was 'Muliti cast Pass through.
Forgot to mention the I am using a V1 US Hub even though I am in the UK.

I will try this as soon as I’m back home, one question though.
I realized you said you dont need the power meters or anything, but is it visible on the insight device? but you dont use it for anything? or isn’t it visible at all?

It’s not visible through the Mobile ST App or via the ide that I can see. Not sure if the apps mentioned earlier in this post will give this information. You can see this information in the wemo app.
There is also an app called WeMoHome which when the Insight is active, it gives the wattage being used.
There is also another app called WeMoManager. This lets you see the wattage being used and also gives an energy total. This one lets you set up your own server on your network to run your rules ‘In house’ so to speak, but this is not for me.
I think they both cost a small amount but may be for you.

Ill understand, the thing is I would love to make changes based on the watt being used.
Example if its more then “xxx” shut down device.
So this is not possible for you todo as you have it setup now?

Sorry. I just use it as a switch and I am not interested in power usage.

Thank you vert much for your effort either way.
If anyone have some tricks up their sleeve to make it work with power usage, please tell me…

My Insight switch seems to be working better after removing it from the app and re-connecting it.

Anyone who managed to have their insight switch working and displaying the energy consumption data?

I’ve adapted the Smartthings sample code for Wemo Switches to work for Wemo Insight Switches. There are still a few problems with it. The code overrides the device handler for Wemo Switch but cannot deal with old (non-insight) Wemo Switches. Therefore, it is only suitable if you only have Wemo Insight Switches and no Wemo Switches.

The device handler adds a Power Meter capability and can respond to changes in energy consumption. I use it to monitor our washing machine and dryer in an outbuilding and send me a notification when they are done.

The device handler reports:

  • Energy consumption.
  • The correct on/off status of the device (previously, Wemo Insight Switches that were on but consumed little energy were reported as off.
  • Time on now
  • Time on today

To install the code,

  • Create or overwrite the Wemo Switch device handler with the code below.

  • Run the Wemo (Connect) SmartApp on your mobile device.

    /**

    • Copyright 2015 SmartThings

    • 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.

    • Wemo Switch

    • Author: superuser

    • Date: 2013-10-11

    • Updated for Wemo Insight Switch

    • Author: Jeroen Keppens, 14/3/2016
      */
      metadata {
      definition (name: “Wemo Switch”, namespace: “smartthings”, author: “SmartThings”) {
      capability “Actuator”
      capability “Switch”
      capability “Polling”
      capability “Power Meter”
      capability “Refresh”
      capability “Sensor”

      attribute "status", "string"
      attribute "onNow", "string"
      attribute "onToday", "string"
      
      command "subscribe"
      command "resubscribe"
      command "unsubscribe"
      

      }

      // simulator metadata
      simulator {}

      // UI tile definitions
      tiles {
      standardTile(“switch”, “device.switch”, width: 2, height: 2, canChangeIcon: true) {
      state “on”, label:’{name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821" state "off", label:'{name}’, action:“switch.on”, icon:“st.switches.switch.off”, backgroundColor:"#ffffff"
      }
      valueTile(“power”, “device.power”, decoration: “flat”, width: 1, height: 1) {
      state “power”, label:’{currentValue} W' } standardTile("status", "device.status", width: 1, height: 1 ) { state( "on", label: 'ON', backgroundColor: "#79b821" ) state( "standby", label: 'STANDBY', backgroundColor: "#FFA500" ) state( "off", label: 'OFF', backgroundColor: "#ffffff" ) } valueTile("onNow", "device.onNow", decoration: "flat", width: 1, height: 1) { state "onNow", label:'{currentValue}’
      }
      valueTile(“onToday”, “device.onToday”, decoration: “flat”, width: 1, height: 1) {
      state “onToday”, label:’${currentValue}’
      }
      standardTile(“refresh”, “device.switch”, inactiveLabel: false, decoration: “flat”, width: 1, height: 1) {
      state “default”, label:’’, action:“refresh.refresh”, icon:“st.secondary.refresh”
      }

      main "switch"
      details (["switch", "power", "status", "onNow", "onToday", "refresh"])
      

      }
      }

    private def parseBinaryStateString(stateString) {
    //log.debug “stateString: stateString" //log.debug "stateString.size(): {stateString.size()}”
    def states =
    def token = “”
    for(int i=0; i<stateString.size(); i++) {
    if (stateString[i] ==~ /[0-9]/) {
    //log.debug “symbol: ${stateString[i]}”
    token = token + stateString[i]
    } else {
    //log.debug “adding token: $token”
    int state = token.toLong()
    states << state
    token = “”
    }
    }
    //log.debug “states: $states”
    return states
    }

    private def convertSecondsToTimeString(seconds) {
    log.debug “convertSecondsToTimeString of $seconds seconds”
    int h = seconds.intdiv(3600)
    int m = (seconds-h3600).intdiv(60)
    int s = seconds-(h
    3600)-(m*60)
    log.debug “h: $h, m: $m, s: $s”
    def timeString = “”
    if (h==0) {
    timeString = timeString + “00”
    } else if (h<=9) {
    timeString = timeString + “0$h”
    } else {
    timeString = timeString + “$h”
    }
    if (m==0) {
    timeString = timeString + “:00”
    } else if (m<=9) {
    timeString = timeString + “:0$m”
    } else {
    timeString = timeString + “:$m”
    }
    if (s==0) {
    timeString = timeString + “:00”
    } else if (s<=9) {
    timeString = timeString + “:0$s”
    } else {
    timeString = timeString + “:$s”
    }
    return timeString
    }

    // parse events into attributes
    def parse(String description) {
    log.debug “Parsing ‘${description}’”

      def msg = parseLanMessage(description)
      def headerString = msg.header
    
      if (headerString?.contains("SID: uuid:")) {
      	def sid = (headerString =~ /SID: uuid:.*/) ? ( headerString =~ /SID: uuid:.*/)[0] : "0"
      	sid -= "SID: uuid:".trim()
    
      	updateDataValue("subscriptionId", sid)
      }
    
      def result = []
      def bodyString = msg.body
      if (bodyString) {
      	def body = new XmlSlurper().parseText(bodyString)
          //log.info "Line 67 bodyString: $bodyString"
          //log.info "Line 68 body: $body"
    
      	if (body?.property?.TimeSyncRequest?.text()) {
      		log.trace "Got TimeSyncRequest"
      		result << timeSyncResponse()
      	} else if (body?.Body?.SetBinaryStateResponse?.BinaryState?.text()) {
      		log.trace "Got SetBinaryStateResponse = ${body?.Body?.SetBinaryStateResponse?.BinaryState?.text()}"
      	} else if (body?.property?.BinaryState?.text()) {
          // To Do: Refactor
              def wemoStateString = body?.property?.BinaryState?.text()
              log.info "State string: $wemoStateString"
              def states = parseBinaryStateString(wemoStateString)
              def value = states[0] == 0 ? "off" : "on"
              log.trace "Notify: BinaryState = ${value}"
              result << createEvent(name: "switch", value: value)
              if (states[0]==0) {
              	result << createEvent(name: "status", value: "off")
              } else if (states[0]==1) {
              	result << createEvent(name: "status", value: "on")
              } else {
              	result << createEvent(name: "status", value: "standby")
              }
              if (states[2] != null) {
              	log.debug "states[2]: ${states[2]}"
                  def onNow = convertSecondsToTimeString(states[2])
                  log.trace "Notify: Time on now = ${onNow}"
                  result << createEvent(name: "onNow", value: "on now  $onNow")
              }
              if (states[3] != null) {
              	log.debug "states[3]: ${states[3]}"
                  def onToday = convertSecondsToTimeString(states[3])
                  log.trace "Notify: Time on today = ${onToday}"
                  result << createEvent(name: "onToday", value: "on today $onToday")
              }
              if (states[7] != null) {
              	log.debug "states[7]: ${states[7]}"
              	def power = (int)Math.round(states[7]/1000)
              	log.trace "Notify: Current power consumption = ${power}"
              	result << createEvent(name: "power", value: power)
              }
      		//def value = body?.property?.BinaryState?.text().toInteger() == 1 ? "on" : "off"
      		//log.trace "Notify: BinaryState = ${value}"
      	} else if (body?.property?.TimeZoneNotification?.text()) {
      		log.debug "Notify: TimeZoneNotification = ${body?.property?.TimeZoneNotification?.text()}"
      	} else if (body?.Body?.GetBinaryStateResponse?.BinaryState?.text()) {
          	// To Do: Revise
      		def wemoStateString = body?.Body?.GetBinaryStateResponse?.BinaryState?.text()
              log.info "Binary State Response (not processed at this point): $wemoStateString"
      	}
      }
    
      result
    

    }

    private getTime() {
    // This is essentially System.currentTimeMillis()/1000, but System is disallowed by the sandbox.
    ((new GregorianCalendar().time.time / 1000l).toInteger()).toString()
    }

    private getCallBackAddress() {
    device.hub.getDataValue(“localIP”) + “:” + device.hub.getDataValue(“localSrvPortTCP”)
    }

    private Integer convertHexToInt(hex) {
    Integer.parseInt(hex,16)
    }

    private String convertHexToIP(hex) {
    [convertHexToInt(hex[0…1]),convertHexToInt(hex[2…3]),convertHexToInt(hex[4…5]),convertHexToInt(hex[6…7])].join(".")
    }

    private getHostAddress() {
    def ip = getDataValue(“ip”)
    def port = getDataValue(“port”)

      if (!ip || !port) {
      	def parts = device.deviceNetworkId.split(":")
      	if (parts.length == 2) {
      		ip = parts[0]
      		port = parts[1]
      	} else {
      		log.warn "Can't figure out ip and port for device: ${device.id}"
      	}
      }
      log.debug "Using ip: ${ip} and port: ${port} for device: ${device.id}"
      return convertHexToIP(ip) + ":" + convertHexToInt(port)
    

    }

    def on() {
    log.debug “Executing ‘on’”
    sendEvent(name: “switch”, value: “on”)
    def turnOn = new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
    SOAPAction: “urn:Belkin:service:basicevent:1#SetBinaryState”
    Host: ${getHostAddress()}
    Content-Type: text/xml
    Content-Length: 333

    <?xml version="1.0"?>

    <SOAP-ENV:Envelope xmlns:SOAP-ENV=“http://schemas.xmlsoap.org/soap/envelope/” SOAP-ENV:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”>
    SOAP-ENV:Body
    <m:SetBinaryState xmlns:m=“urn:Belkin:service:basicevent:1”>
    1
    </m:SetBinaryState>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>""", physicalgraph.device.Protocol.LAN)
    }

    def off() {
    log.debug “Executing ‘off’”
    sendEvent(name: “switch”, value: “off”)
    def turnOff = new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
    SOAPAction: “urn:Belkin:service:basicevent:1#SetBinaryState”
    Host: ${getHostAddress()}
    Content-Type: text/xml
    Content-Length: 333

    <?xml version="1.0"?>

    <SOAP-ENV:Envelope xmlns:SOAP-ENV=“http://schemas.xmlsoap.org/soap/envelope/” SOAP-ENV:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”>
    SOAP-ENV:Body
    <m:SetBinaryState xmlns:m=“urn:Belkin:service:basicevent:1”>
    0
    </m:SetBinaryState>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>""", physicalgraph.device.Protocol.LAN)
    }

    /*def refresh() {
    log.debug “Executing ‘refresh’”
    new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
    SOAPACTION: “urn:Belkin:service:basicevent:1#GetBinaryState”
    Content-Length: 277
    Content-Type: text/xml; charset=“utf-8”
    HOST: ${getHostAddress()}
    User-Agent: CyberGarage-HTTP/1.0

    <?xml version="1.0" encoding="utf-8"?>

    <s:Envelope xmlns:s=“http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”>
    <s:Body>
    <u:GetBinaryState xmlns:u=“urn:Belkin:service:basicevent:1”>
    </u:GetBinaryState>
    </s:Body>
    </s:Envelope>""", physicalgraph.device.Protocol.LAN)
    }*/

    def refresh() {
    log.debug “Executing WeMo Switch ‘subscribe’, then ‘timeSyncResponse’, then ‘poll’”
    [subscribe(), timeSyncResponse(), poll()]
    }

    def subscribe(hostAddress) {
    log.debug “Executing ‘subscribe()’”
    def address = getCallBackAddress()
    new physicalgraph.device.HubAction("""SUBSCRIBE /upnp/event/basicevent1 HTTP/1.1
    HOST: {hostAddress} CALLBACK: <http://{address}/>
    NT: upnp:event
    TIMEOUT: Second-5400
    User-Agent: CyberGarage-HTTP/1.0

    “”", physicalgraph.device.Protocol.LAN)
    }

    def subscribe() {
    subscribe(getHostAddress())
    }

    def subscribe(ip, port) {
    def existingIp = getDataValue(“ip”)
    def existingPort = getDataValue(“port”)
    if (ip && ip != existingIp) {
    log.debug “Updating ip from $existingIp to $ip”
    updateDataValue(“ip”, ip)
    }
    if (port && port != existingPort) {
    log.debug “Updating port from $existingPort to $port”
    updateDataValue(“port”, port)
    }

      subscribe("${ip}:${port}")
    

    }

    ////////////////////////////
    def resubscribe() {
    log.debug “Executing ‘resubscribe()’”

    def sid = getDeviceDataByName(“subscriptionId”)

    new physicalgraph.device.HubAction("""SUBSCRIBE /upnp/event/basicevent1 HTTP/1.1
    HOST: {getHostAddress()} SID: uuid:{sid}
    TIMEOUT: Second-5400

    “”", physicalgraph.device.Protocol.LAN)

    }

    ////////////////////////////
    def unsubscribe() {
    def sid = getDeviceDataByName(“subscriptionId”)
    new physicalgraph.device.HubAction("""UNSUBSCRIBE publisher path HTTP/1.1
    HOST: {getHostAddress()} SID: uuid:{sid}

    “”", physicalgraph.device.Protocol.LAN)
    }

    ////////////////////////////
    //TODO: Use UTC Timezone
    def timeSyncResponse() {
    log.debug “Executing ‘timeSyncResponse()’”
    new physicalgraph.device.HubAction("""POST /upnp/control/timesync1 HTTP/1.1
    Content-Type: text/xml; charset=“utf-8”
    SOAPACTION: “urn:Belkin:service:timesync:1#TimeSync”
    Content-Length: 376
    HOST: ${getHostAddress()}
    User-Agent: CyberGarage-HTTP/1.0

    <?xml version="1.0" encoding="utf-8"?>

    <s:Envelope xmlns:s=“http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”>
    <s:Body>
    <u:TimeSync xmlns:u=“urn:Belkin:service:timesync:1”>
    ${getTime()}
    -05.00
    1
    1
    </u:TimeSync>
    </s:Body>
    </s:Envelope>
    “”", physicalgraph.device.Protocol.LAN)
    }

    def poll() {
    log.debug “Executing ‘poll’”
    new physicalgraph.device.HubAction("""POST /upnp/control/basicevent1 HTTP/1.1
    SOAPACTION: “urn:Belkin:service:basicevent:1#GetBinaryState”
    Content-Length: 277
    Content-Type: text/xml; charset=“utf-8”
    HOST: ${getHostAddress()}
    User-Agent: CyberGarage-HTTP/1.0

    <?xml version="1.0" encoding="utf-8"?>

    <s:Envelope xmlns:s=“http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”>
    <s:Body>
    <u:GetBinaryState xmlns:u=“urn:Belkin:service:basicevent:1”>
    </u:GetBinaryState>
    </s:Body>
    </s:Envelope>""", physicalgraph.device.Protocol.LAN)
    }

8 Likes

I’m trying to set this up, but it’s not reporting power data. The on/off function is working tho. Any idea how to fix this?

Is there a way to estimate the cost using this code? Like this device https://github.com/bigpunk6/device-type.AeonSmartEnergySwitch-

Installed this today, its awesome compared the stock Wemo Switch device handler. Thanks.

Can you create a GitHub like [RELEASE] Iris Smart Plug (3210-L) Zigbee Plug with Z-wave Repeater has for us to connect to? Makes monitoring for and getting updates much easier as well as allows submission of suggested improvements.

Better yet maybe just submit a MR to this one that people are already using: https://github.com/zzarbi/smartthings/tree/master/wemo

awesome! hope that some day this will support both standard and insight switches. I have both :frowning:

I’m getting the following error after adding switches…

physicalgraph.app.exception.UnknownDeviceTypeException: Device type ‘Wemo Switch’ in namespace ‘mujica’ not found. @ line 323

has anyone experienced this?

Thanks for this update. It’s working.