1818 getfunctions(deviceid)
1919 getproperties(deviceid)
2020 getdps(deviceid)
21- sendcommand(deviceid, commands)
21+ sendcommand(deviceid, commands [, uri] )
2222 getconnectstatus(deviceid)
2323 getdevicelog(deviceid, start=[now - 1 day], end=[now], evtype="1,2,3,4,5,6,7,8,9,10", size=100, params={})
2424 -> when start or end are negative, they are the number of days before "right now"
@@ -213,6 +213,9 @@ def _tuyaplatform(self, uri, action='GET', post=None, ver='v1.0', recursive=Fals
213213 "POST: URL=%s HEADERS=%s DATA=%s" , url , headers , body ,
214214 )
215215 response = requests .post (url , headers = headers , data = body )
216+ log .debug (
217+ "POST RESPONSE: code=%d text=%s token=%s" , response .status_code , response .text , self .token
218+ )
216219
217220 # Check to see if token is expired
218221 if "token invalid" in response .text :
@@ -307,17 +310,48 @@ def cloudrequest(self, url, action=None, post=None, query=None):
307310 action = 'POST' if post else 'GET'
308311 return self ._tuyaplatform (url , action = action , post = post , ver = None , query = query )
309312
310- def _get_all_devices (self ):
313+ # merge device list 'result2' into 'result1'
314+ # if result2 has a device which is not in result1 then it will be added
315+ # if result2 has a key which does not exist or is empty in result1 then that key will be copied over
316+ def _update_device_list ( self , result1 , result2 ):
317+ for new_device in result2 :
318+ if 'id' not in new_device or not new_device ['id' ]:
319+ continue
320+ found = False
321+ for existing_device in result1 :
322+ if 'id' in existing_device and existing_device ['id' ] == new_device ['id' ]:
323+ found = True
324+ for k in new_device :
325+ if k not in existing_device or not existing_device [k ]:
326+ existing_device [k ] = new_device [k ]
327+ if not found :
328+ result1 .append ( new_device )
329+
330+ def _get_all_devices ( self , uid = None , device_ids = None ):
311331 fetches = 0
312332 our_result = { 'result' : [] }
313333 last_row_key = None
314334 has_more = True
315335 total = 0
316- query = {'size' :'50' }
317336
318- while has_more :
337+ if uid :
338+ # get device list for specified user id
339+ query = {'page_size' :'75' , 'source_type' : 'tuyaUser' , 'source_id' : uid }
340+ # API docu: https://developer.tuya.com/en/docs/cloud/dc413408fe?id=Kc09y2ons2i3b
341+ uri = '/v1.3/iot-03/devices'
342+ if device_ids :
343+ if isinstance ( device_ids , tuple ) or isinstance ( device_ids , list ):
344+ query ['device_ids' ] = ',' .join (device_ids )
345+ else :
346+ query ['device_ids' ] = device_ids
347+ else :
348+ # get all devices
349+ query = {'size' :'50' }
319350 # API docu: https://developer.tuya.com/en/docs/cloud/fc19523d18?id=Kakr4p8nq5xsc
320- result = self .cloudrequest ( '/v1.0/iot-01/associated-users/devices' , query = query )
351+ uri = '/v1.0/iot-01/associated-users/devices'
352+
353+ while has_more :
354+ result = self .cloudrequest ( uri , query = query )
321355 fetches += 1
322356 has_more = False
323357
@@ -330,7 +364,12 @@ def _get_all_devices(self):
330364 # format it the same as before, basically just moves result->devices into result
331365 for i in result :
332366 if i == 'result' :
333- our_result [i ] += result [i ]['devices' ]
367+ # by-user-id has the result in 'list' while all-devices has it in 'devices'
368+ if 'list' in result [i ] and 'devices' not in result [i ]:
369+ our_result [i ] += result [i ]['list' ]
370+ elif 'devices' in result [i ]:
371+ our_result [i ] += result [i ]['devices' ]
372+
334373 if 'total' in result [i ]: total = result [i ]['total' ]
335374 if 'last_row_key' in result [i ]:
336375 has_more = result [i ]['has_more' ]
@@ -364,6 +403,17 @@ def getdevices(self, verbose=False):
364403 json_data = self ._tuyaplatform (uri )
365404 else :
366405 json_data = self ._get_all_devices ()
406+ users = {}
407+ # loop through all devices and build a list of user IDs
408+ for dev in json_data ['result' ]:
409+ if 'uid' in dev :
410+ users [dev ['uid' ]] = True
411+ if users :
412+ # we have at least 1 user id, so fetch the device list again to make sure we have the local key
413+ # this also gets us the gateway_id for child devices
414+ for uid in users .keys ():
415+ json_data2 = self ._get_all_devices ( uid = uid )
416+ self ._update_device_list ( json_data ['result' ], json_data2 ['result' ] )
367417
368418 if verbose :
369419 return json_data
@@ -422,6 +472,10 @@ def filter_devices( self, devs, ip_list=None ):
422472 else :
423473 item [k ] = i [k ]
424474
475+ if 'gateway_id' in i :
476+ k = 'gateway_id'
477+ item [k ] = i [k ]
478+
425479 tuyadevices .append (item )
426480
427481 return tuyadevices
0 commit comments