Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc updates to find_device(), wizard, and repr(device) #196

Merged
merged 3 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion tinytuya/Cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,18 @@ def _getuid(self, deviceid=None):
response_dict = self._tuyaplatform(uri)

if not response_dict['success']:
if 'code' not in response_dict:
response_dict['code'] = -1
if 'msg' not in response_dict:
response_dict['msg'] = 'Unknown Error'
log.debug(
"Error from Tuya Cloud: %r", response_dict['msg'],
)
return None
return error_json(
ERR_CLOUD,
"Error from Tuya Cloud: Code %r: %r" % (response_dict['code'], response_dict['msg'])
)

uid = response_dict['result']['uid']
return uid

Expand All @@ -239,6 +247,9 @@ def getdevices(self, verbose=False):
ERR_CLOUD,
"Unable to get device list"
)
elif isinstance( uid, dict):
return uid

# Use UID to get list of all Devices for User
uri = 'users/%s/devices' % uid
json_data = self._tuyaplatform(uri)
Expand Down
29 changes: 17 additions & 12 deletions tinytuya/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ def find_device(dev_id=None, address=None):
address = The IP address you are tring to find the Device ID for

Response:
(ip, version, {broadcast data})
{'ip':<ip>, 'version':<version>, 'id':<id>, 'product_id':<product_id>, 'data':<broadcast data>}
"""
if dev_id is None and address is None:
return (None, None, None)
Expand All @@ -430,9 +430,9 @@ def find_device(dev_id=None, address=None):

deadline = time.time() + SCANTIME
selecttime = SCANTIME
ret = (None, None, None)
ret = None

while (ret[0] is None) and (selecttime > 0):
while (ret is None) and (selecttime > 0):
rd, _, _ = select.select( [client, clients], [], [], selecttime )
for sock in rd:
try:
Expand All @@ -454,26 +454,30 @@ def find_device(dev_id=None, address=None):
ip = result["ip"]
gwId = result["gwId"]
version = result["version"]
product_id = '' if 'productKey' not in result else result['productKey']
log.debug( 'find() received broadcast from %r: %r', ip, result )
except:
result = {"ip": ip}
log.debug( 'find() failed to decode broadcast from %r: %r', addr, data )
continue

# Check to see if we are only looking for one device
if dev_id and gwId == dev_id:
# We found it by dev_id!
ret = (ip, version, result)
ret = {'ip':ip, 'version':version, 'id':gwId, 'product_id':product_id, 'data':result}
break
elif address and address == ip:
# We found it by ip!
ret = (ip, version, result)
ret = {'ip':ip, 'version':version, 'id':gwId, 'product_id':product_id, 'data':result}
break

selecttime = deadline - time.time()

# while
clients.close()
client.close()
if ret is None:
ret = {'ip':None, 'version':None, 'id':None, 'product_id':None, 'data':{}}
log.debug( 'find() is returning: %r', ret )
return ret

Expand Down Expand Up @@ -598,12 +602,12 @@ def __init__(

if (not address) or address == "Auto" or address == "0.0.0.0":
# try to determine IP address automatically
(addr, ver, bcast_data) = find_device(dev_id)
if addr is None:
bcast_data = find_device(dev_id)
if bcast_data['ip'] is None:
log.debug("Unable to find device on network (specify IP address)")
raise Exception("Unable to find device on network (specify IP address)")
self.address = addr
self.set_version(float(ver))
self.address = bcast_data['ip']
self.set_version(float(bcast_data['version']))
time.sleep(0.1)
elif version:
self.set_version(float(version))
Expand All @@ -621,7 +625,8 @@ def __del__(self):

def __repr__(self):
# FIXME can do better than this
return "%r" % ((self.id, self.address),)
return ("%s( %r, address=%r, local_key=%r, dev_type=%r, connection_timeout=%r, version=%r, persist=%r )" %
(self.__class__.__name__, self.id, self.address, self.real_local_key.decode(), self.dev_type, self.connection_timeout, self.version, self.socketPersistent))

def _get_socket(self, renew):
if renew and self.socket is not None:
Expand Down Expand Up @@ -1194,8 +1199,8 @@ def find(did):
Response:
(ip, version)
"""
(ip, ver, bcast_data) = find_device(dev_id=did)
return (ip, ver)
bcast_data = find_device(dev_id=did)
return (bcast_data['ip'], bcast_data['version'])

def generate_payload(self, command, data=None, gwId=None, devId=None, uid=None):
"""
Expand Down
10 changes: 9 additions & 1 deletion tinytuya/wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,20 @@ def wizard(color=True, retries=None, forcescan=False):

# on auth error, cloud.token is a dict and will cause getdevices() to implode
if isinstance( cloud.token, dict):
print('\n\n' + bold + 'Error from Tuya server: ' + dim + cloud.token['Payload'])
err = cloud.token['Payload'] if 'Payload' in cloud.token else 'Unknown Error'
print('\n\n' + bold + 'Error from Tuya server: ' + dim + err)
print('Check API Key and Secret')
return

# Get UID from sample Device ID
json_data = cloud.getdevices( True )

if 'result' not in json_data:
err = json_data['Payload'] if 'Payload' in json_data else 'Unknown Error'
print('\n\n' + bold + 'Error from Tuya server: ' + dim + err)
print('Check DeviceID and Region')
return

if forcescan:
# Force Scan - Get list of all local ip addresses
try:
Expand Down