Plugin - WeMo Switch

Python and python framework

Moderator: leecollings

Post Reply
mivo
Posts: 80
Joined: Friday 21 April 2017 8:58
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Czechia
Contact:

Plugin - WeMo Switch

Post by mivo »

Hi all,

I am using my simple plugin for WeMo Switch for some time, now I am releasing in publicly. Feel free to test it and send me a comments etc. Plugin and Readme is available on GitHub:

https://github.com/milanvo/domoticz-plu ... emo-switch
My toys:
Raspberry Pi 3 + UPS PIco HV3.0 A Stack
Minibian (Raspbian Jessie) + Domoticz beta
RFLink 433 Gateway, 1wire DS18B20 temp sensors (GPIO)
RaZberry module + 2x Comet Z-Wave + Z-wave socket
---
Plugins: WeMo Switch, UPS PIco HV3.0A on GitHub
andi216
Posts: 46
Joined: Tuesday 14 March 2017 13:10
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.7243
Contact:

Re: Plugin - WeMo Switch

Post by andi216 »

@mivo
Thanks for the plugin. It works very well.
(Rasp B + v3.8153 and Rasp V2 v3.8312).
In the future can change the plugin to add new Wemo devices (similar to Ping device)?
mivo
Posts: 80
Joined: Friday 21 April 2017 8:58
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Czechia
Contact:

Re: Plugin - WeMo Switch

Post by mivo »

Hi,

thank you for feedback. I thought about more addresses for WeMo switches, Python plugins has limited options for configuration parameters. Ping hardware has sub-page for setup - native device in C++ code. Do you have more WeMo for testing ? I have only one ;). I will try to add option to specify more addresses in field, comma separated.
My toys:
Raspberry Pi 3 + UPS PIco HV3.0 A Stack
Minibian (Raspbian Jessie) + Domoticz beta
RFLink 433 Gateway, 1wire DS18B20 temp sensors (GPIO)
RaZberry module + 2x Comet Z-Wave + Z-wave socket
---
Plugins: WeMo Switch, UPS PIco HV3.0A on GitHub
r3wt3d
Posts: 7
Joined: Friday 10 November 2017 4:09
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Plugin - WeMo Switch

Post by r3wt3d »

Hi

I tried this out and it seems to work, however I have error in my log

When I turn off I get this:
2017-11-13 14:45:47.025 Error: (xxxxxxx) Except updStatus: 0|1510551709|236|2059|357681|1209600|83|55680|1194829|473422122

When I turn on I get this:
2017-11-13 14:46:25.091 Error: (xxxxxxx) Except updStatus: 8|1510551947|236|2059|357681|1209600|48|0|1194829|473422122

Icon changes after onHeartbeat it seems.
2017-11-13 14:46:39.336 (zzzzzzzz) Updating device from 0:'0' to have values 1:'100'.
2017-11-13 14:46:39.347 (xxxxxxx) Updated to: 1

How can I fix it?
r3wt3d
Posts: 7
Joined: Friday 10 November 2017 4:09
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Plugin - WeMo Switch

Post by r3wt3d »

Ok I fixed it...and I additionally added dirty support for WeMo insight switch.
It seems that WeMo is only sending extended status back when turning on/off the switch,
I turn on the relay on every heartbeat if it is already switched on to receive the energy data.
Normally it seems it feeds with upnp, but I have no clue how to grab it on python.

You could probably use this and create a script to update via API:
https://github.com/timonreinhard/wemo-client (check the test directory)

While researching I found this:
https://ouimeaux.readthedocs.io/en/latest/wemo.html
http://moderntoil.com/?p=839
I didn't look deeply inside but maybe I could have used this aswell:
https://github.com/mgsg/domoticz-sonos-plugin

anyway here is the code..
I'm pretty new to python and Domoticz so maybe there are some mistakes you guys can correct...
This script will add a "Insight" True/False switch to Hardware and if you change it to True and restart domoticz
it will create a counter device if not done already, and updates every heartbeat with the latest energy consumption.
Don't forget to enable it.

Spoiler: show

Code: Select all

#!/usr/bin/python3
#
# Domoticz Python Plugin for WeMo Switch by Belkin
# Added support for WeMo Insight switch - r3wt3d 2017/11/16 
# Based on code from:
# https://gist.github.com/pruppert/af7d38cb7b7ca75584ef
# https://github.com/pdumoulin/blinky
#
# Author: mivo
#
"""
<plugin key="wemo-switch" name="WeMo Switch (plugin)" author="mivo" version="0.1" wikilink="http://www.domoticz.com/wiki/plugins" externallink="https://github.com/milanvo/domoticz-plugins">
    <params>
        <param field="Address" label="IP Address" width="200px" required="true"/>
        <param field="Port" label="Port" width="50px" required="true" default="49153"/>
        <param field="Mode1" label="Insight" width="50px">
            <options>
                <option label="True" value="YES"/>
                <option label="False" value="NO" default="true"/>
            </options>
        </param> 
        <param field="Mode6" label="Debug" width="75px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal" default="true"/>
            </options>
        </param>
    </params>
</plugin>
"""
import Domoticz
import urllib.request

class wemoSwitch:
    ip = None
    ports = [49153, 49152, 49154, 49151, 49155]

    def __init__(self, switch_ip=None, switch_port=None):
        self.ip = switch_ip
        if switch_port:
            self.ports = [switch_port]

    def action(self, action):
        value = None

        if action == 'on':
            method, obj, value = ('Set', 'BinaryState', 1)
        elif action == 'off':
            method, obj, value = ('Set', 'BinaryState', 0)
        elif action == 'status':
            method, obj = ('Get', 'BinaryState')
        elif action == 'name':
            method, obj = ('Get', 'FriendlyName')
        elif action == 'signal':
            method, obj = ('Get', 'SignalStrength')

        return self._send(method, obj, value)

    def on(self):
        return self.action('on')

    def off(self):
        return self.action('off')

    def status(self):
        return self.action('status')

    def name(self):
        return self.action('name')

    def signal(self):
        return self.action('signal')

    def _get_header_xml(self, method, obj):
        method = method + obj
        return '"urn:Belkin:service:basicevent:1#%s"' % method

    def _get_body_xml(self, method, obj, value=0):
        method = method + obj
        return '<u:%s xmlns:u="urn:Belkin:service:basicevent:1"><%s>%s</%s></u:%s>' % (method, obj, value, obj, method)

    def _send(self, method, obj, value=None):
        body_xml = self._get_body_xml(method, obj, value)
        header_xml = self._get_header_xml(method, obj)
        for port in self.ports:
            result = self._try_send(self.ip, port, body_xml, header_xml, obj) 
            if result is not None:
                self.ports = [port]
            return result
        raise Exception("_send TimeoutOnAllPorts")

    def _try_send(self, ip, port, body, header, data):
        try:
            request = urllib.request.Request('http://%s:%s/upnp/control/basicevent1' % (ip, port))
            request.add_header('Content-type', 'text/xml; charset="utf-8"')
            request.add_header('SOAPACTION', header)
            request_body = '<?xml version="1.0" encoding="utf-8"?>'
            request_body += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
            request_body += '<s:Body>%s</s:Body></s:Envelope>' % body
            request.data = request_body.encode()
            result = urllib.request.urlopen(request, timeout=3)
            return self._extract(result.read().decode(), data)
        except Exception as e:
#        except:
#            raise
            print(str(e))
            return None

    def _get_request_data(self, method, obj, value=None):
        body_xml = self._get_body_xml(method, obj, value)
        header_xml = self._get_header_xml(method, obj)
        headers = dict()
        
        url = '/upnp/control/basicevent1'
        headers['Content-type'] = 'text/xml; charset="utf-8"'
        headers['SOAPACTION'] = header_xml

        body = '<?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/">'
        body += '<s:Body>%s</s:Body></s:Envelope>' % body_xml

        headers['Content-Length'] = "%d"%(len(body))
        
        return dict(url=url, headers=headers, body=body)

    def _extract(self, XML, tagName):
        #print('XML:', XML)
        #print('tagName:', tagName)
        startTag = '<%s>' % (tagName)
        endTag = '</%s>' % (tagName)
        startPos = XML.find(startTag)
        endPos = XML.find(endTag, startPos+1)
        #print('start end:', startPos, endPos)
        if ((startPos == -1) or (endPos == -1)):
            print("'"+tagName+"' not found in supplied XML")
            raise Exception("_extract" + "'"+tagName+"' not found in supplied XML")
            return False
        #if ((startPos == -1) or (endPos == -1)): Domoticz.Error("'"+tagName+"' not found in supplied XML")
        #print('vystup:', XML[startPos+len(startTag):endPos])
        return XML[startPos+len(startTag):endPos]

global switch
switch = wemoSwitch()

def onStart():
    global switch

    if Parameters["Mode6"] == "Debug":
        Domoticz.Debugging(1)
    if (len(Devices) == 0):
        Domoticz.Device(Name="Switch 1", Unit=1, TypeName="Switch").Create()
        Domoticz.Log("Device created.")
    if (2 not in Devices and Parameters["Mode1"] == "YES"):
        Domoticz.Device(Name="Power", Unit=2, TypeName="kWh").Create() 
        Domoticz.Log("kWh Device created.")

    Domoticz.Heartbeat(30)
    
    switch.ip = Parameters["Address"]
    switch.port = Parameters["Port"]

    try:
        status = switch.status()
    except Exception as e:
        Domoticz.Error('Except onStart: ' + str(e))
        return

    updStatus(status)

    DumpConfigToLog()

def onStop():
    Domoticz.Log("Plugin is stopping.")

def onCommand(Unit, Command, Level, Hue):
    global switch

    try:
        if (Command.upper() == 'ON'):
            status = switch.on()
        else:
            status = switch.off()
    except Exception as e:
        Domoticz.Error('Except onCommand: ' + str(e))
        return
    
    updStatus(status)

def onHeartbeat():
    global switch

    try:
        status = switch.status()
    except Exception as e:
        Domoticz.Error('Except onHeartbeat: ' + str(e))
        return
    Domoticz.Debug(str(status))
    if int(status[0:1]) == 1 and Parameters["Mode1"] == "YES":
       power = str(switch.on()).split('|')
       kwh = str(int(power[7])/1000)
       Domoticz.Debug(kwh) 
       Devices[2].Update(0,kwh)

    if int(status[0:1]) == 0 and Parameters["Mode1"] == "YES":
       Devices[2].Update(0,"0.000")
    updStatus(status)

def updStatus(status):
    if not status:
        Domoticz.Error('False updStatus: ' + str(status))
        return

    try:
        istatus = int(status[0:1])
    except ValueError:
        Domoticz.Error('Except updStatus: ' + str(status))
        return

    Domoticz.Debug('Status: ' + str(status) + ' iStatus: ' + str(istatus))

    if istatus == 1:
        if (1 in Devices):
            if Devices[1].nValue == 0:
            #if Devices[1].sValue == "Off":
                Devices[1].Update(1,"On")
                Domoticz.Debug('Updated to: ' + str(istatus))
    elif istatus == 0:
        if (1 in Devices):
            if Devices[1].nValue == 1:
            #if Devices[1].sValue == "On":
                Devices[1].Update(0,"Off")
                Domoticz.Debug('Updated to: ' + str(istatus))
    elif istatus == 8:
        if (1 in Devices):
            if Devices[1].nValue == 0:
                Devices[1].Update(1,"On")
                Domoticz.Debug('Updated to: ' + str(istatus))
    #DumpConfigToLog()

# Generic helper functions
def DumpConfigToLog():
    for x in Parameters:
        if Parameters[x] != "":
            Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'")
    Domoticz.Debug("Device count: " + str(len(Devices)))
    for x in Devices:
        Domoticz.Debug("Device:           " + str(x) + " - " + str(Devices[x]))
        Domoticz.Debug("Device ID:       '" + str(Devices[x].ID) + "'")
        Domoticz.Debug("Device Name:     '" + Devices[x].Name + "'")
        Domoticz.Debug("Device nValue:    " + str(Devices[x].nValue))
        Domoticz.Debug("Device sValue:   '" + Devices[x].sValue + "'")
        Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
    return

def main():
    import argparse

    parser = argparse.ArgumentParser(description='WeMo Switch control module for Python')
    parser.add_argument('action', choices=['on', 'off', 'status', 'name', 'signal'], help='Action')
    parser.add_argument('ip', help='IP address')
    parser.add_argument('port', nargs='?', default='49153', help='Port')
    args = parser.parse_args()

    IP=args.ip
    PORT=args.port

    switch = wemoSwitch(IP, PORT)

    if args.action:
        print(switch.action(args.action))

if __name__ == '__main__':
    main()
huey
Posts: 10
Joined: Tuesday 21 March 2017 20:45
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Contact:

Re: Plugin - WeMo Switch

Post by huey »

Hi, I have taken the liberty of using your and mivo's code and adjusted it a bit for the Wemo Insight. Still working on it to see if i can get the standby status and info in a bit better...

I will include the code, maybe anyone has some additional ideas and pointers.
Spoiler: show

Code: Select all

#!/usr/bin/python3
#
# Domoticz Python Plugin for WeMo Insight by Belkin
# Modifications for WeMo Insight switch and rename to wemo-insight - huey 2018/04/16
# Added support for WeMo Insight switch - r3wt3d 2017/11/16 
# Based on code from:
# https://gist.github.com/pruppert/af7d38cb7b7ca75584ef
# https://github.com/pdumoulin/blinky
#
# Author: mivo 
#
"""
<plugin key="wemo-insight" name="WeMo Insight (plugin)" author="huey, with thx to mivo and r3wt3d" version="0.1" wikilink="http://www.domoticz.com/wiki/plugins" >
    <params>
        <param field="Address" label="IP Address" width="200px" required="true"/>
        <param field="Port" label="Port" width="50px" required="true" default="49153"/>
        <param field="Mode1" label="Power" width="75px">
            <options>
                <option label="True" value="YES" default="true"/>
                <option label="False" value="NO"/>
            </options>
        </param> 
        <param field="Mode2" label="OnFor Usage" width="75px">
            <options>
                <option label="True" value="YES"/>
                <option label="False" value="NO" default="true"/>
            </options>
        </param> 
        <param field="Mode3" label="OnToday Usage" width="75px">
            <options>
                <option label="True" value="YES"/>
                <option label="False" value="NO" default="true"/>
            </options>
        </param> 
        <param field="Mode4" label="Summary" width="75px">
            <options>
                <option label="True" value="YES"/>
                <option label="False" value="NO" default="true"/>
            </options>
        </param> 
        <param field="Mode6" label="Debug" width="75px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal" default="true"/>
                <option label="Logging" value="File"/>
            </options>
        </param>
    </params>
</plugin>
"""
import Domoticz
import urllib.request
import datetime

class wemoInsight:
    ip = None
    ports = [49153, 49152, 49154, 49151, 49155]

    def __init__(self, insight_ip=None, insight_port=None):
        self.ip = insight_ip
        if insight_port:
            self.ports = [insight_port]

    def action(self, action):
        value = None

        if action == 'on':
            event, method, obj, value = ('basicevent', 'Set', 'BinaryState', 1)
            return self._send(event, method, obj, value)
        elif action == 'off':
            event, method, obj, value = ('basicevent', 'Set', 'BinaryState', 0)
            return self._send(event, method, obj, value)
        elif action == 'status':
            event, method, obj = ('basicevent', 'Get', 'BinaryState')
            return self._send(event, method, obj, value)
        elif action == 'name':
            event, method, obj = ('basicevent', 'Get', 'FriendlyName')
            return self._send(event, method, obj, value)
        elif action == 'signal':
            event, method, obj = ('basicevent', 'Get', 'SignalStrength')
            return self._send(event, method, obj, value)

        elif action == 'params':
            event, method, obj = ('insight', 'Get', 'InsightParams')
            return self._send(event, method, obj, value)

        elif action == 'autopowerthreshold':
            event, method, obj = ('insight', 'SetAuto', 'PowerThreshold')
            return self._send(event, method, obj, value)
        elif action == 'setpowerthreshold':
            event, method, obj = ('insight', 'Set', 'PowerThreshold', value)
            return self._send(event, method, obj, value)
        elif action == 'resetpowerthreshold':
            event, method, obj = ('insight', 'Reset', 'PowerThreshold')
            return self._send(event, method, obj, value)
                        
    def on(self):
        return self.action('on')

    def off(self):
        return self.action('off')

    def status(self):
        return self.action('status')

    def name(self):
        return self.action('name')

    def signal(self):
        return self.action('signal')

    def params(self):
        return self.action('params')

    def autopowerthreshold(self):
        return self.action('autopowerthreshold')

    def setpowerthreshold(self):
        return self.action('setpowerthreshold')

    def resetpowerthreshold(self):
        return self.action('resetpowerthreshold')

    def _get_header_xml(self, event, method, obj):
        method = method + obj
        return '"urn:Belkin:service:%s:1#%s"' % (event, method)

    def _get_body_xml(self, event, method, obj, value=0):
        method = method + obj
        return '<u:%s xmlns:u="urn:Belkin:service:%s:1"><%s>%s</%s></u:%s>' % (method, event, obj, value, obj, method)

    def _send(self, event, method, obj, value=None):
        body_xml = self._get_body_xml(event, method, obj, value)
        header_xml = self._get_header_xml(event, method, obj)
        for port in self.ports:
            result = self._try_send(self.ip, port, body_xml, header_xml, obj, event) 
            if result is not None:
                self.ports = [port]
            return result
        raise Exception("_send TimeoutOnAllPorts")

    def _try_send(self, ip, port, body, header, data, event):
        try:
            request = urllib.request.Request('http://%s:%s/upnp/control/%s1' % (ip, port, event))
            request.add_header('Content-type', 'text/xml; charset="utf-8"')
            request.add_header('SOAPACTION', header)
            request_body = '<?xml version="1.0" encoding="utf-8"?>'
            request_body += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
            request_body += '<s:Body>%s</s:Body></s:Envelope>' % body
            request.data = request_body.encode()
            result = urllib.request.urlopen(request, timeout=3)
            return self._extract(result.read().decode(), data)
        except Exception as e:
#        except:
#            raise
            print(str(e))
            return None

#huey: not sure what this is for, seems unused to me.
#    def _get_request_data(self, event, method, obj, value=None):
#        body_xml = self._get_body_xml(event, method, obj, value)
#        header_xml = self._get_header_xml(event, method, obj)
#        headers = dict()
#       
#        url = '/upnp/control/%s1' % event
#        headers['Content-type'] = 'text/xml; charset="utf-8"'
#        headers['SOAPACTION'] = header_xml
#
#        body = '<?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/">'
#        body += '<s:Body>%s</s:Body></s:Envelope>' % body_xml
#
#        headers['Content-Length'] = "%d"%(len(body))
#        
#        return dict(url=url, headers=headers, body=body)

    def _extract(self, XML, tagName):
        #Domoticz.Debug('XML: ' + XML)
        #Domoticz.Debug('tagName: ' + tagName)
        startTag = '<%s>' % (tagName)
        endTag = '</%s>' % (tagName)
        startPos = XML.find(startTag)
        endPos = XML.find(endTag, startPos+1)
        #Domoticz.Debug('start end: ' + str(startPos) + ' ' + str(endPos))
        if ((startPos == -1) or (endPos == -1)):
            raise Exception("_extract" + "'"+tagName+"' not found in supplied XML")
            return False
        #if ((startPos == -1) or (endPos == -1)): Domoticz.Error("'"+tagName+"' not found in supplied XML")
        #print('vystup:', XML[startPos+len(startTag):endPos])
        return XML[startPos+len(startTag):endPos]

global insight
insight = wemoInsight()

def onStart():
    global insight
    Domoticz.Log("* Plugin is starting *")

    if Parameters["Mode6"] == "Debug":
        Domoticz.Debugging(1)
        DumpConfigToLog()
        #huey: can not get external imports to work...
        #Domoticz.Log("Debugger started, use 'telnet 0.0.0.0 4444' to connect")
        #import rpdb
        #rpdb.set_trace()

#    if 'WeMoInsightLogo' not in Images: Domoticz.Image('wemo-insight.zip').Create()

    if (len(Devices) == 0):
        Domoticz.Device(Name="Switch", Unit=1, TypeName="Switch", Used=1).Create()
        Domoticz.Log("Switch Device created.")
    if (2 not in Devices and Parameters["Mode1"] == "YES"):
        Domoticz.Device(Name="Power", Unit=2, TypeName="kWh", Used=1).Create()
        Domoticz.Log("kWh Device created.")
    if (3 not in Devices and Parameters["Mode2"] == "YES"):
        Domoticz.Device(Name="OnFor", Unit=3, TypeName="Custom", Options = { "Custom" : "1;seconds"}, Used=0).Create()
        UpdateImage(3, 'WeMoInsightLogo')
        Domoticz.Log("OnFor Custom Device created.")
    if (4 not in Devices and Parameters["Mode3"] == "YES"):
        Domoticz.Device(Name="OnTodayFor", Unit=4, TypeName="Custom", Options = { "Custom" : "1;seconds"}, Used=0).Create()
        UpdateImage(4, 'WeMoInsightLogo')
        Domoticz.Log("OnToday Custom Device created.")
    if (5 not in Devices and Parameters["Mode4"] == "YES"):
        Domoticz.Device(Name="Summary", Unit=5, TypeName="Text", Used=0).Create()
        Domoticz.Log("Summary Text Device created.")

#    if 3 in Devices:
#        UpdateImage(3, 'WeMoInsightLogo')
#    if 4 in Devices: 
#        UpdateImage(4, 'WeMoInsightLogo')


#    Domoticz.Heartbeat(30)
    Domoticz.Heartbeat(60)
    
    insight.ip = Parameters["Address"]
    insight.port = Parameters["Port"]

def onStop():
    Domoticz.Log("* Plugin is stopping *")

def onCommand(Unit, Command, Level, Hue):
    global insight
    Domoticz.Debug("onCommand called")
    try:
        if (Command.upper() == 'ON'):
            status = insight.on()
        else:
            status = insight.off()
    except Exception as e:
        Domoticz.Error('Except onCommand: ' + str(e))
        return
    
    updStatus(status)

def onHeartbeat():
    global insight
    Domoticz.Debug("* onHeartBeat called *")
    try:
        params = insight.params()
    except Exception as e:
        Domoticz.Error('Except onHeartbeat: ' + str(e))
        return
    Domoticz.Debug('DebugParams: ' + str(params))

    if params is None:
        Domoticz.Log('ERROR Params is undefined')
    else:
        state = int(params[0:1])
        Domoticz.Debug('DebugState : ' + str(state)) 
        power = str(insight.params()).split('|')
        #if state >= 1:
        updStatus(params)
         
        if Parameters["Mode2"] == "YES":
            Domoticz.Debug("* Device 3 update called *")
            onfor = int(power[2])
            Domoticz.Debug('DebugOnFor: ' + str(onfor))
 
            Devices[3].Update(0,str(onfor))
 
        if Parameters["Mode3"] == "YES":
            Domoticz.Debug("* Device 4 update called *")
            ontoday = int(power[3])
            Domoticz.Debug('DebugOnToday: ' + str(ontoday))    
 
            Devices[4].Update(0,str(ontoday))
 
        if Parameters["Mode4"] == "YES":
            Domoticz.Debug("* Device 5 update called *")
            lastchange = datetime.datetime.fromtimestamp(int(power[1]))
            Domoticz.Debug('DebugLastChange: ' + str(lastchange)) 
            onfortext = datetime.timedelta(seconds=int(power[2]))
            Domoticz.Debug('DebugOnForText: ' + str(onfortext))
            ontodaytext = datetime.timedelta(seconds=int(power[3]))
            Domoticz.Debug('DebugOnTodayText: ' + str(ontodaytext))    
            ontotal = int(power[4])
            Domoticz.Debug('DebugOnTotal: ' + str(ontotal))    
            ontotaltext = datetime.timedelta(seconds=int(power[4]))
            Domoticz.Debug('DebugOnTotalText: ' + str(ontotaltext))    
            totalmw = int(float(power[9]))/1000
            Domoticz.Debug('DebugTotalkWh: ' + str(totalmw))    
            threshold = int(power[10])/1000 
            Domoticz.Debug('DebugThreshold: ' + str(threshold)) 
            
            Devices[5].Update(0,"On for: "+ str(onfortext) + "<br>" + "On today: " + str(ontodaytext) + "<br>" + "On total: " + str(ontotaltext) + "<br>" + "Total kWh: " + str(totalmw) + "<br>" + "Standby threshold: " + str(threshold) + "<br>" + "Last change: " + str(lastchange))
    
def updStatus(status):
    Domoticz.Debug("* updStatus called *")
    if not status:
        Domoticz.Error('False updStatus: ' + str(status))
        return

    try:
        istate = int(status[0:1])
    except ValueError:
        Domoticz.Error('Except updStatus: ' + str(status))
        return

    Domoticz.Debug('DebugStatus: ' + str(status) + ' iState: ' + str(istate))

    Domoticz.Debug("* Device 1 update called *")
    if istate == 1:
        if (1 in Devices):
            if Devices[1].nValue == 0:
            #if Devices[1].sValue == "Off":
                Devices[1].Update(1,"On")
                Domoticz.Debug('Updated to: ' + str(istate))
    elif istate == 0:
        if (1 in Devices):
            if Devices[1].nValue == 1:
            #if Devices[1].sValue == "On":
                Devices[1].Update(0,"Off")
                Domoticz.Debug('Updated to: ' + str(istate))
    elif istate == 8:
        if (1 in Devices):
            if Devices[1].nValue == 0:
                Devices[1].Update(1,"On")
                Domoticz.Debug('Updated to: ' + str(istate))

    if Parameters["Mode1"] == "YES":
        Domoticz.Debug("* Device 2 update called *")
#        power = str(insight.params()).split('|')
        power = status.split('|')
        if Parameters["Mode1"] == "YES":
            currentmw = int(power[7])/1000
            Domoticz.Debug('DebugkWh: ' + str(currentmw)) 
            todaymw = int(power[8])/1000 
            Domoticz.Debug('DebugtoDay: ' + str(todaymw))

            Devices[2].Update(0,str(currentmw) + "; " + str(todaymw))

# Synchronise images to match parameter in hardware page
#def UpdateImage(Unit, Logo):
#    if Unit in Devices and Logo in Images:
#        if Devices[Unit].Image != Images[Logo].ID:
#            Domoticz.Log("Device Image update: 'WeMoInsight', Currently " + str(Devices[Unit].Image) + ", should be " + str(Images[Logo].ID))
#            Devices[Unit].Update(nValue=Devices[Unit].nValue, sValue=str(Devices[Unit].sValue), Image=Images[Logo].ID)
#    return

# Generic helper functions
def LogMessage(Message):
    if Parameters["Mode6"] == "File":
        f = open(Parameters["HomeFolder"] + "plugin.log", "a")
        f.write(Message + "\r\n")
        f.close()
    Domoticz.Debug(Message)

def DumpConfigToLog():
    for x in Parameters:
        if Parameters[x] != "":
            LogMessage( "'" + x + "':'" + str(Parameters[x]) + "'")
    LogMessage("Device count: " + str(len(Devices)))
    for x in Devices:
        LogMessage("Device:           " + str(x) + " - " + str(Devices[x]))
        LogMessage("Internal ID:     '" + str(Devices[x].ID) + "'")
        LogMessage("External ID:     '" + str(Devices[x].DeviceID) + "'")
        LogMessage("Device Name:     '" + Devices[x].Name + "'")
        LogMessage("Device nValue:    " + str(Devices[x].nValue))
        LogMessage("Device sValue:   '" + Devices[x].sValue + "'")
        LogMessage("Device LastLevel: " + str(Devices[x].LastLevel))
    return

def main():
    import argparse

    parser = argparse.ArgumentParser(description='WeMo Insight control module for Python')
    parser.add_argument('action', choices=['on', 'off', 'status', 'name', 'signal', 'params', 'autopowerthreshold', 'setpowerthreshold', 'resetpowerthreshold'], help='Action')
    parser.add_argument('ip', help='IP address')
    parser.add_argument('port', nargs='?', default='49153', help='Port')
    args = parser.parse_args()

    IP=args.ip
    PORT=args.port

    insight = wemoInsight(IP, PORT)

    if args.action:
        print(insight.action(args.action))

if __name__ == '__main__':
    main()
huey
Posts: 10
Joined: Tuesday 21 March 2017 20:45
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Contact:

Re: Plugin - WeMo Switch

Post by huey »

Latest and probably last version and with some icons.
Spoiler: show

Code: Select all

#!/usr/bin/python3
#
# Domoticz Python Plugin for WeMo Insight by Belkin
# Modifications for WeMo Insight switch and rename to wemo-insight - huey 2018/04/16
# Added support for WeMo Insight switch - r3wt3d 2017/11/16 
# Based on code from:
# https://gist.github.com/pruppert/af7d38cb7b7ca75584ef
# https://github.com/pdumoulin/blinky
#
# Author: mivo 
#
"""
<plugin key="wemo-insight" name="WeMo Insight (plugin)" author="huey, with thx to mivo and r3wt3d" version="0.1" wikilink="http://www.domoticz.com/wiki/plugins" >
    <description>
        <h2>Belkin WeMo Insight plugin</h2><br/>
        <h3>Devices</h3>
        <ul style="list-style-type:square">
            <li>Comes default with on/off switch and power</li>
            <li>Optional additional selector switch for more convenient logging of standby status</li>
            <li>Optional additional devices to log duration of last ontime and total for day in seconds</li>
            <li>Optional additional device with summary details text</li>
            <li>Optional additional device to reset standby threshold to default value of 8 or auto value</li>
        </ul>
    </description>
    
    <params>
        <param field="Address" label="IP Address" width="200px" required="true"/>
        <param field="Port" label="Port" width="50px" required="true" default="49153"/>
        <param field="Mode1" label="Standby status" width="75px">
            <options>
                <option label="True" value="YES" default="true"/>
                <option label="False" value="NO"/>
            </options>
        </param> 
        <param field="Mode2" label="On for seconds" width="75px">
            <options>
                <option label="True" value="YES"/>
                <option label="False" value="NO" default="true"/>
            </options>
        </param> 
        <param field="Mode3" label="Today seconds" width="75px">
            <options>
                <option label="True" value="YES"/>
                <option label="False" value="NO" default="true"/>
            </options>
        </param> 
        <param field="Mode4" label="Summary details" width="75px">
            <options>
                <option label="True" value="YES"/>
                <option label="False" value="NO" default="true"/>
            </options>
        </param> 
        <param field="Mode5" label="Standby reset" width="75px">
            <options>
                <option label="True" value="YES"/>
                <option label="False" value="NO" default="true"/>
            </options>
        </param> 
        <param field="Mode6" label="Debug" width="75px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal" default="true"/>
            </options>
        </param>
    </params>
</plugin>
"""
##import Domoticz
try:
    import Domoticz
except ImportError:
    def Log(s):
        print(s)
    def Debug(s):
        print(s)
    def Error(s):
        print(s)    
import sys
import urllib.request
import datetime
   
class wemoInsight:
    ip = None
    ports = [49153, 49152, 49154, 49151, 49155]

    def __init__(self, insight_ip=None, insight_port=None):
        self.ip = insight_ip
        if insight_port:
            self.ports = [insight_port]

    def action(self, action):
        value = None

        if action == 'on':
            event, method, obj, value = ('basicevent', 'Set', 'BinaryState', 1)
            return self._send(event, method, obj, value)
        elif action == 'off':
            event, method, obj, value = ('basicevent', 'Set', 'BinaryState', 0)
            return self._send(event, method, obj, value)
        elif action == 'status':
            event, method, obj = ('basicevent', 'Get', 'BinaryState')
            return self._send(event, method, obj, value)
        elif action == 'name':
            event, method, obj = ('basicevent', 'Get', 'FriendlyName')
            return self._send(event, method, obj, value)
        elif action == 'signal':
            event, method, obj = ('basicevent', 'Get', 'SignalStrength')
            return self._send(event, method, obj, value)

        elif action == 'params':
            event, method, obj = ('insight', 'Get', 'InsightParams')
            return self._send(event, method, obj, value)

        elif action == 'autopowerthreshold':
            event, method, obj = ('insight', 'SetAuto', 'PowerThreshold')
            return self._send(event, method, obj, value)
        elif action == 'setpowerthreshold':
            event, method, obj, value = ('insight', 'Set', 'PowerThreshold', value)
            return self._send(event, method, obj, value)
        elif action == 'resetpowerthreshold':
            event, method, obj = ('insight', 'Reset', 'PowerThreshold')
            return self._send(event, method, obj, value)
                        
    def on(self):
        return self.action('on')

    def off(self):
        return self.action('off')

    def status(self):
        return self.action('status')

    def name(self):
        return self.action('name')

    def signal(self):
        return self.action('signal')

    def params(self):
        return self.action('params')

    def autopowerthreshold(self):
        return self.action('autopowerthreshold')

    def setpowerthreshold(self):
        return self.action('setpowerthreshold')

    def resetpowerthreshold(self):
        return self.action('resetpowerthreshold')

    def _get_header_xml(self, event, method, obj):
        method = method + obj
        return '"urn:Belkin:service:%s:1#%s"' % (event, method)

    def _get_body_xml(self, event, method, obj, value=0):
        method = method + obj
        return '<u:%s xmlns:u="urn:Belkin:service:%s:1"><%s>%s</%s></u:%s>' % (method, event, obj, value, obj, method)

    def _send(self, event, method, obj, value=None):
        body_xml = self._get_body_xml(event, method, obj, value)
        header_xml = self._get_header_xml(event, method, obj)
        for port in self.ports:
            result = self._try_send(self.ip, port, body_xml, header_xml, obj, event) 
            if result is not None:
                self.ports = [port]
            return result
        raise Exception("_send TimeoutOnAllPorts")

    def _try_send(self, ip, port, body, header, data, event):
        try:
            request = urllib.request.Request('http://%s:%s/upnp/control/%s1' % (ip, port, event))
            request.add_header('Content-type', 'text/xml; charset="utf-8"')
            request.add_header('SOAPACTION', header)
            request_body = '<?xml version="1.0" encoding="utf-8"?>'
            request_body += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
            request_body += '<s:Body>%s</s:Body></s:Envelope>' % body
            request.data = request_body.encode()
            result = urllib.request.urlopen(request, timeout=3)
            return self._extract(result.read().decode(), data)
        except Exception as e:
#        except:
#            raise
            print(str(e))
            return None

#huey: not sure what this is for, seems unused to me.
#    def _get_request_data(self, event, method, obj, value=None):
#        body_xml = self._get_body_xml(event, method, obj, value)
#        header_xml = self._get_header_xml(event, method, obj)
#        headers = dict()
#       
#        url = '/upnp/control/%s1' % event
#        headers['Content-type'] = 'text/xml; charset="utf-8"'
#        headers['SOAPACTION'] = header_xml
#
#        body = '<?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/">'
#        body += '<s:Body>%s</s:Body></s:Envelope>' % body_xml
#
#        headers['Content-Length'] = "%d"%(len(body))
#        
#        return dict(url=url, headers=headers, body=body)

    def _extract(self, XML, tagName):
        #Domoticz.Debug('XML: ' + XML)
        #Domoticz.Debug('tagName: ' + tagName)
        startTag = '<%s>' % (tagName)
        endTag = '</%s>' % (tagName)
        startPos = XML.find(startTag)
        endPos = XML.find(endTag, startPos+1)
        #Domoticz.Debug('start end: ' + str(startPos) + ' ' + str(endPos))
        if ((startPos == -1) or (endPos == -1)):
            raise Exception("_extract" + "'"+tagName+"' not found in supplied XML")
            return False
        #if ((startPos == -1) or (endPos == -1)): Domoticz.Error("'"+tagName+"' not found in supplied XML")
        #print('vystup:', XML[startPos+len(startTag):endPos])
        return XML[startPos+len(startTag):endPos]

global insight
insight = wemoInsight()

def onStart():
    global insight
    Domoticz.Log("* Plugin is starting *")

    if Parameters["Mode6"] == "Debug":
        Domoticz.Debugging(1)
        Domoticz.Debug("sys.exec: " + str(sys.executable))
        #sys.path.append('/usr/local/lib/python36/site-packages')
        Domoticz.Debug("sys.path: " + str(sys.path))
        DumpConfigToLog()
        #huey: can not get external imports to work...
        #Domoticz.Log("Debugger started, use 'telnet 0.0.0.0 4444' to connect")
        #import rpdb
        #rpdb.set_trace()

    if 'WeMoInsight' not in Images:
        Domoticz.Debug("Create new images")
        Domoticz.Image('WeMoInsight.zip').Create()
    
    if (len(Devices) == 0):
        Domoticz.Device(Name="Switch", Unit=1, TypeName="Switch", Used=1).Create()
        Domoticz.Log("Switch Device created.")
        Domoticz.Device(Name="Power", Unit=2, TypeName="kWh", Used=1).Create()
        Domoticz.Log("kWh Device created.")
    if (3 not in Devices and Parameters["Mode2"] == "YES"):
        Domoticz.Device(Name="OnFor", Unit=3, TypeName="Custom", Options = { "Custom" : "1;s"}, Used=0).Create()
        Domoticz.Log("OnFor Custom Device created.")
    if (4 not in Devices and Parameters["Mode3"] == "YES"):
        Domoticz.Device(Name="OnTodayFor", Unit=4, TypeName="Custom", Options = { "Custom" : "1;s"}, Used=0).Create()
        Domoticz.Log("OnToday Custom Device created.")
    if (5 not in Devices and Parameters["Mode4"] == "YES"):
        Domoticz.Device(Name="Summary", Unit=5, TypeName="Text", Used=0).Create()
        Domoticz.Log("Summary Text Device created.")
    if (6 not in Devices and Parameters["Mode1"] == "YES"):
        OptionsStatus = {"LevelActions": "||", 
                   "LevelNames": "Off|On|Standby",
                   "LevelOffHidden": "false",
                   "SelectorStyle": "0"}
        Domoticz.Device(Name="Status",  Unit=6, TypeName="Selector Switch", Switchtype=18, Image=12, Options=OptionsStatus, Used=0).Create()
        Domoticz.Log("Switch Status Device created.")
    if (7 not in Devices and Parameters["Mode5"] == "YES"):
        OptionsStandby = {"LevelActions": "||", 
                   "LevelNames": "Off|Default|Auto",
                   "LevelOffHidden": "true",
                   "SelectorStyle": "0"}
        Domoticz.Device(Name="Standby threshold",  Unit=7, TypeName="Selector Switch", Switchtype=18, Image=12, Options=OptionsStandby, Used=0).Create()
        Domoticz.Log("Standby Reset Device created.")

    if 1 in Devices:
        UpdateImage(1, 'WeMoInsight')
    if 3 in Devices:
        UpdateImage(3, 'WeMoInsight')
    if 4 in Devices: 
        UpdateImage(4, 'WeMoInsight')
#    if 5 in Devices: 
#        UpdateImage(5, 'WeMoInsight')
    if 6 in Devices: 
        UpdateImage(6, 'WeMoInsight')
    if 7 in Devices: 
        UpdateImage(7, 'WeMoInsight')

#    Domoticz.Heartbeat(30)
    Domoticz.Heartbeat(60)
    
    insight.ip = Parameters["Address"]
    insight.port = Parameters["Port"]

def onStop():
    Domoticz.Log("* Plugin is stopping *")

def onCommand(Unit, Command, Level, Hue):
    global insight
    Domoticz.Debug("onCommand called, unit: " + str(Unit) + " command: " + str(Command) + " level: " + str(Level) + " hue: " + str(Hue))
    try:
        if (Command.upper() == 'ON') or (Unit == 6 and Command.upper() == 'SET LEVEL' and Level >= 10):
            status = insight.on()
            updStatus(status)
        elif (Unit == 7 and Command.upper() == 'SET LEVEL' and Level == 10):
            status = insight.resetpowerthreshold()
            Devices[7].Update(1,"10")
            Domoticz.Debug("Standby: 'Default (8)'") 
        elif (Unit == 7 and Command.upper() == 'SET LEVEL' and Level == 20):
            status = insight.autopowerthreshold()
            Devices[7].Update(1,"20")
            Domoticz.Debug("Standby: 'Auto'") 
        else:
            status = insight.off()
            updStatus(status)
    except Exception as e:
        Domoticz.Error('Except onCommand: ' + str(e))
        return
    
def onHeartbeat():
    global insight
    Domoticz.Debug("* onHeartBeat called *")
    try:
        params = insight.params()
    except Exception as e:
        Domoticz.Error('Except onHeartbeat: ' + str(e))
        return
    Domoticz.Debug('DebugParams: ' + str(params))

    if params is None:
        Domoticz.Log('ERROR Params is undefined')
    else:
        state = int(params[0:1])
        Domoticz.Debug('DebugState : ' + str(state)) 
        power = str(insight.params()).split('|')
        #if state >= 1:
        updStatus(params)
         
        if Parameters["Mode2"] == "YES":
            Domoticz.Debug("* Device 3 update called *")
            onfor = int(power[2])
            Domoticz.Debug('DebugOnFor: ' + str(onfor))
 
            Devices[3].Update(0,str(onfor))
 
        if Parameters["Mode3"] == "YES":
            Domoticz.Debug("* Device 4 update called *")
            ontoday = int(power[3])
            Domoticz.Debug('DebugOnToday: ' + str(ontoday))    
 
            Devices[4].Update(0,str(ontoday))
 
        if Parameters["Mode4"] == "YES":
            Domoticz.Debug("* Device 5 update called *")
            lastchange = datetime.datetime.fromtimestamp(int(power[1]))
            Domoticz.Debug('DebugLastChange: ' + str(lastchange)) 
            onfortext = datetime.timedelta(seconds=int(power[2]))
            Domoticz.Debug('DebugOnForText: ' + str(onfortext))
            ontodaytext = datetime.timedelta(seconds=int(power[3]))
            Domoticz.Debug('DebugOnTodayText: ' + str(ontodaytext))    
            ontotal = int(power[4])
            Domoticz.Debug('DebugOnTotal: ' + str(ontotal))    
            ontotaltext = datetime.timedelta(seconds=int(power[4]))
            Domoticz.Debug('DebugOnTotalText: ' + str(ontotaltext))    
            totalmw = int(float(power[9]))/1000
            Domoticz.Debug('DebugTotalkWh: ' + str(totalmw))    
            threshold = int(power[10])/1000 
            Domoticz.Debug('DebugThreshold: ' + str(threshold)) 
            
            Devices[5].Update(0,"On for: "+ str(onfortext) + "<br>" + "On today: " + str(ontodaytext) + "<br>" + "On total: " + str(ontotaltext) + "<br>" + "Total kWh: " + str(totalmw) + "<br>" + "Standby threshold: " + str(threshold) + "<br>" + "Last change: " + str(lastchange))
    
        if Parameters["Mode5"] == "YES":
            Domoticz.Debug("* Device 5 update called *")
            if threshold == int('8000')/1000: 
                Devices[7].Update(1,"10")
                Domoticz.Debug("Standby: 'Default (8)'") 
            else:
                Devices[7].Update(1,"20")
                Domoticz.Debug("Standby: 'Auto'") 
 
def updStatus(status):
    Domoticz.Debug("* updStatus called *")
    if not status:
        Domoticz.Error('False updStatus: ' + str(status))
        return

    try:
        istate = int(status[0:1])
    except ValueError:
        Domoticz.Error('Except updStatus: ' + str(status))
        return

    Domoticz.Debug('DebugStatus: ' + str(status) + ' iState: ' + str(istate))
    if istate == 1:
        if (1 in Devices):
            if Devices[1].nValue == 0 or Devices[1].nValue == 1:
                Domoticz.Debug("* Device 1 update called *, nValue: " + str(Devices[1].nValue) )
                Devices[1].Update(1,"On")
                Domoticz.Debug("Device 1 updated to " + str(istate) + ", nValue: " + str(Devices[1].nValue) + " sValue: " + Devices[1].sValue)
                Domoticz.Debug("* Device 6 update called *, nValue: " + str(Devices[6].nValue) )
                Devices[6].Update(10, "10")
                Domoticz.Debug("Device 6 updated to " + str(istate) + ", nValue: " + str(Devices[6].nValue) + " sValue: " + Devices[6].sValue)
    elif istate == 0:
        if (1 in Devices):
            if Devices[1].nValue == 1:
                Domoticz.Debug("* Device 1 update called *, nValue: " + str(Devices[1].nValue) )
                Devices[1].Update(0,"Off")
                Domoticz.Debug("Device 1 updated to " + str(istate) + ", nValue: " + str(Devices[1].nValue) + " sValue: " + Devices[1].sValue)
                Domoticz.Debug("* Device 6 update called *, nValue: " + str(Devices[6].nValue) )
                Devices[6].Update(0, "0")
                Domoticz.Debug("Device 6 updated to " + str(istate) + ", nValue: " + str(Devices[6].nValue) + " sValue: " + Devices[6].sValue)
    elif istate == 8:
        if (1 in Devices):
            if Devices[1].nValue == 0 or Devices[1].nValue == 1:
                Domoticz.Debug("* Device 1 update called *, nValue: " + str(Devices[1].nValue) )
                Devices[1].Update(1,"On")
                Domoticz.Debug("Device 1 updated to " + str(istate) + ", nValue: " + str(Devices[1].nValue) + " sValue: " + Devices[1].sValue)
                Domoticz.Debug("* Device 6 update called *, nValue: " + str(Devices[6].nValue) )
                Devices[6].Update(20, "20")
                Domoticz.Debug("Device 6 updated to " + str(istate) + ", nValue: " + str(Devices[6].nValue) + " sValue: " + Devices[6].sValue)

    if Parameters["Mode1"] == "YES":
        Domoticz.Debug("* Device 2 update called *")
        power = status.split('|')
        if Parameters["Mode1"] == "YES":
            currentmw = round(int(power[7])/1000)
            Domoticz.Debug('DebugkWh: ' + str(currentmw)) 
            todaymw = int(power[8])/1000 
            Domoticz.Debug('DebugtoDay: ' + str(todaymw))

            Devices[2].Update(0,str(currentmw) + "; " + str(todaymw))

# Synchronise images to match required Logo
def UpdateImage(Unit, Logo):
    Domoticz.Debug("* updateImage called *, unit: " + str(Unit) )
    Domoticz.Debug("Device current logo    : " + str(Devices[Unit].Image) )
    Domoticz.Debug("Device should have logo: " + str(Images[Logo].ID) )
    if (Unit in Devices) and (Logo in Images):
        if (Devices[Unit].Image != Images[Logo].ID):
            Devices[Unit].Update(nValue=Devices[Unit].nValue, sValue=str(Devices[Unit].sValue), Image=Images[Logo].ID)
            Domoticz.Debug("Device " + str(Unit) + " image updated to " + Logo)
    return

# Generic helper functions
def LogMessage(Message):
    Domoticz.Debug(Message)

def DumpConfigToLog():
    for x in Parameters:
        if Parameters[x] != "":
            LogMessage( "'" + x + "':'" + str(Parameters[x]) + "'")
    LogMessage("Device count: " + str(len(Devices)))
    for x in Devices:
        LogMessage("Device:           " + str(x) + " - " + str(Devices[x]))
        LogMessage("Internal ID:     '" + str(Devices[x].ID) + "'")
        LogMessage("External ID:     '" + str(Devices[x].DeviceID) + "'")
        LogMessage("Device Name:     '" + Devices[x].Name + "'")
        LogMessage("Device nValue:    " + str(Devices[x].nValue))
        LogMessage("Device sValue:   '" + Devices[x].sValue + "'")
        LogMessage("Device LastLevel: " + str(Devices[x].LastLevel))
        LogMessage("Device Image ID: '" + str(Devices[x].Image) + "'")
    return

def main():
    import argparse

    parser = argparse.ArgumentParser(description='WeMo Insight control module for Python')
    parser.add_argument('action', choices=['on', 'off', 'status', 'name', 'signal', 'params', 'autopowerthreshold', 'setpowerthreshold', 'resetpowerthreshold'], help='Action')
    parser.add_argument('ip', help='IP address')
    parser.add_argument('port', nargs='?', default='49153', help='Port')
    args = parser.parse_args()

    IP=args.ip
    PORT=args.port

    insight = wemoInsight(IP, PORT)

    if args.action:
        print(insight.action(args.action))

if __name__ == '__main__':
    main()
Attachments
WeMoInsight.zip
(6.14 KiB) Downloaded 169 times
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest