forked from rux616/webacon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
webacon.py
173 lines (155 loc) · 4.03 KB
/
webacon.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/local/bin/python
##############################
#
# WeMo Basic Control (WeBaCon) by
# Dan Cassidy
# 2013-10-12
#
# Based on wemo.py by
# Isaac Kelly
# http://www.issackelly.com/
#
# Requires Miranda v1.4 by
# Craig Heffner
# https://code.google.com/p/miranda-upnp/
#
# Version:
# 1.0 (2013-10-12):
# - Initial release
#
##############################
import sys
import getopt
# Requires Miranda v1.4
from miranda import upnp, msearch
def main(argv):
# Set defaults
interface = None
serialNumber = ""
command = False
timeout = 3
# Check command line options
try:
opts, args = getopt.getopt(argv, "i:s:c:t:h")
except getopt.GetoptError, e:
print "Usage Error: ", e
showusage()
sys.exit(2)
else:
if opts == []:
showusage()
sys.exit(0)
for opt, arg in opts:
if opt in ("-i"):
# interface
interface = arg
elif opt in ("-s"):
# serial number
serialNumber = arg
elif opt in ("-c"):
# command
command = arg
elif opt in ("-t"):
# timeout
timeout = int(arg)
elif opt in ("-h"):
# help
showusage()
sys.exit(0)
# Create the connection
hp = upnp(False, False, interface, None)
# Update some of the connection settings
hp.MAX_HOSTS = 1
hp.TIMEOUT = timeout
# Scan for the specified uuid
msearch(3, ["msearch", "uuid", "Socket-1_0-%s" % serialNumber], hp)
# Check to make sure that msearch found a device
if len(hp.ENUM_HOSTS) == 0:
# Device not found, die gracefully
print "wemo: device_not_found"
sys.exit(1)
# Get the device's details
hostInfo = hp.ENUM_HOSTS[0]
if hostInfo['dataComplete'] == False:
xmlHeaders, xmlData = hp.getXML(hostInfo['xmlFile'])
hp.getHostInfo(xmlData,xmlHeaders,0)
# Process command
if command == "status":
status = get(hp)
if status:
print "wemo: on"
else:
print "wemo: off"
sys.exit(0)
elif command == "off":
status = off(hp)
if status:
print "wemo: off"
sys.exit(0)
else:
print "wemo: error"
sys.exit(1)
elif command == "on":
status = on(hp)
if status:
print "wemo: on"
sys.exit(0)
else:
print "wemo: error"
sys.exit(1)
else:
print "wemo: command_unknown"
sys.exit(1)
# Show usage
def showusage():
print "Usage: %s [OPTIONS]\n"\
" -i <interface> Set interface\n"\
" -s <serial number> Set serial number\n"\
" -c <status|on|off> Send command to WeMo\n"\
" -t <seconds> Set the timeout in seconds, default is 3\n"\
" -h Show help" % sys.argv[0]
return
# Send request to a WeMo socket
def _send(hp, action, data=None):
if not data:
data = {}
hostInfo = hp.ENUM_HOSTS[0]
deviceName = 'controllee'
serviceName = 'basicevent'
controlURL = hostInfo['proto'] + hostInfo['name']
controlURL2 = hostInfo['deviceList'][deviceName]['services'][serviceName]['controlURL']
if not controlURL.endswith('/') and not controlURL2.startswith('/'):
controlURL += '/'
controlURL += controlURL2
response = hp.sendSOAP(
hostInfo['name'],
'urn:Belkin:service:basicevent:1',
controlURL,
action,
data
)
return response
# Gets the state of a WeMo socket
def get(hp):
response = _send(hp, 'GetBinaryState')
tagValue = hp.extractSingleTag(response, 'BinaryState')
return True if tagValue == '1' else False
# Turns a WeMo socket on
def on(hp):
# BinaryState is set to 'Error' in the case that it was already on.
response = _send(hp, 'SetBinaryState', {'BinaryState': (1, 'Boolean')})
tagValue = hp.extractSingleTag(response, 'BinaryState')
return True if tagValue in ['1', 'Error'] else False
# Turns a WeMo socket off
def off(hp):
# BinaryState is set to 'Error' in the case that it was already off.
response = _send(hp, 'SetBinaryState', {'BinaryState': (0, 'Boolean')})
tagValue = hp.extractSingleTag(response, 'BinaryState')
return True if tagValue in ['0', 'Error'] else False
if __name__ == "__main__":
try:
print "WeBaCon v1.0 by Dan Cassidy"
main(sys.argv[1:])
except Exception, e:
print 'Caught main exception:',e
sys.exit(1)