Skip to content

Commit d72f308

Browse files
committed
Enhance device version detection for v3.4 and v3.5 in ForceScannedDevice class #671
1 parent d5a52f9 commit d72f308

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

tinytuya/scanner.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -493,14 +493,15 @@ def timeout( self, forced=False ):
493493
self.step = FSCAN_NOT_STARTED
494494
self.connect()
495495
return
496-
# closed thrice, probably a v3.4 device
496+
# closed thrice, probably a v3.4 or v3.5 device
497497
if self.debug:
498-
print('ForceScannedDevice: Retrying as v3.4')
498+
print('ForceScannedDevice: Retrying as v3.4/3.5')
499+
self.message = "%s Unable to determine version, likely v3.4 or v3.5 - trying key negotiation..." % (self.options['termcolors'].dim)
499500
self.retries = 0
500501
self.deviceinfo['dev_type'] = 'default'
501502
self.step = FSCAN_v34_BRUTE_FORCE_ACTIVE
502-
self.deviceinfo['version'] = 3.4
503-
self.ver_found = True
503+
self.deviceinfo['version'] = 3.4 # Assume 3.4 to start, but don't mark as confirmed
504+
# Don't set ver_found = True here - only set it when we get actual response
504505
self.keygen = (i for i in self.options['keylist'] if not i.used)
505506
self.cur_key = next( self.keygen, None )
506507
if self.debug:
@@ -519,7 +520,7 @@ def timeout( self, forced=False ):
519520
else:
520521
self.err_found = True
521522
self.deviceinfo['version'] = 0.0
522-
self.message = "%s Polling %s Failed: Device stopped responding before key was found" % (self.options['termcolors'].alertdim, self.ip)
523+
self.message = "%s Polling %s Failed: Device stopped responding before key was found (likely v3.4 or v3.5)" % (self.options['termcolors'].alertdim, self.ip)
523524
_print_device_info( self.deviceinfo, 'Failed to Force-Scan', self.options['termcolors'], self.message, self.options['verbose'])
524525
self.displayed = True
525526
self.close()
@@ -532,8 +533,9 @@ def timeout( self, forced=False ):
532533
self.v3x_brute_force_try_next_key()
533534
elif forced:
534535
self.err_found = True
535-
self.message = "%s Polling %s Failed: Unexpected close during read/write operation" % (self.options['termcolors'].alertdim, self.ip)
536-
_print_device_info( self.deviceinfo, 'Failed to Force-Scan', self.options['termcolors'], self.message, self.options['verbose'])
536+
hint = " (likely v3.4 or v3.5)" if self.step == FSCAN_v34_BRUTE_FORCE_ACTIVE else ""
537+
self.message = "%s Polling %s Failed: Unexpected close during read/write operation%s" % (self.options['termcolors'].alertdim, self.ip, hint)
538+
_print_device_info( self.deviceinfo, 'Failed to Force-Scan', self.options['termcolors'], self.message, self.options['verbose'])
537539
self.displayed = True
538540
self.remove = True
539541
elif self.step == FSCAN_v31_PASSIVE_LISTEN or self.step == FSCAN_v33_BRUTE_FORCE_ACQUIRE:
@@ -543,7 +545,8 @@ def timeout( self, forced=False ):
543545
self.passive = True
544546
elif self.step == FSCAN_FINAL_POLL:
545547
if not self.message:
546-
self.message = "%s Polling %s Failed: No response to poll request" % (self.options['termcolors'].alertdim, self.ip)
548+
hint = " (likely v3.4 or v3.5)" if not self.ver_found else ""
549+
self.message = "%s Polling %s Failed: No response to poll request%s" % (self.options['termcolors'].alertdim, self.ip, hint)
547550
_print_device_info( self.deviceinfo, 'Force-Scanned', self.options['termcolors'], self.message, self.options['verbose'])
548551
self.displayed = True
549552
self.remove = True
@@ -661,11 +664,8 @@ def read_data( self ):
661664
if prefix_offset > 0:
662665
data = data[prefix_offset:]
663666
else:
664-
prefix_offset = data.find(tinytuya.PREFIX_BIN)
665-
if prefix_offset >= 0:
666-
data = data[prefix_offset:]
667-
self.try_v35_with_v34 = False
668-
elif self.try_v35_with_v34 and self.deviceinfo['version'] == 3.4:
667+
# Check for v3.5 prefix FIRST when testing both protocols
668+
if self.try_v35_with_v34 and self.deviceinfo['version'] == 3.4:
669669
prefix_offset = data.find(tinytuya.PREFIX_6699_BIN)
670670
if prefix_offset >= 0:
671671
if self.debug:
@@ -675,6 +675,12 @@ def read_data( self ):
675675
self.deviceinfo['version'] = 3.5
676676
self.device.set_version(3.5)
677677
self.ver_found = True
678+
# Fall back to v3.4 prefix if v3.5 not found
679+
if self.deviceinfo['version'] != 3.5:
680+
prefix_offset = data.find(tinytuya.PREFIX_BIN)
681+
if prefix_offset >= 0:
682+
data = data[prefix_offset:]
683+
self.try_v35_with_v34 = False
678684
hmac_key = self.device.local_key if self.deviceinfo['version'] >= 3.4 else None
679685
msg = tinytuya.unpack_message(data, hmac_key=hmac_key)
680686
except:

0 commit comments

Comments
 (0)