Skip to content

Commit

Permalink
MappedDevice updates, remove some debugging print()s and add "raw_dps…
Browse files Browse the repository at this point in the history
…" and "dps_objects" to responses
  • Loading branch information
uzlonewolf committed Jul 2, 2023
1 parent dbf958b commit d38194e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 18 deletions.
53 changes: 37 additions & 16 deletions tinytuya/MappedDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def encode_value( self, val ):

class _dp_type_array( _dp_type_base_class ):
def __init__( self, data, type_lower ):
print('parsing Array', type_lower, data)
#print('parsing Array', type_lower, data)
super( _dp_type_array, self ).__init__( data, type_lower )
#if 'elementTypeSpec' in self.values and isinstance( self.values['elementTypeSpec'], dict ) and 'type' in self.values['elementTypeSpec']:
# self.subtype = self.values['elementTypeSpec']['type'].lower()
Expand Down Expand Up @@ -367,21 +367,21 @@ def encode_value( self, val ):

class _dp_type_json( _dp_type_base_class ):
def __init__( self, data, type_lower ):
print('parsing JSON', type_lower, data)
#print('parsing JSON', type_lower, data)
super( _dp_type_json, self ).__init__( data, type_lower )
self.items = {}
self.value_len = 0
for k in self.values:
vtype = _detect_json_subtype( self.values[k] )
print('JSON key', k, 'subtype', vtype)
#print('JSON key', k, 'subtype', vtype)
self.items[k] = _build_obj( {'type': vtype, 'values': self.values[k]} )
if not self.items[k].value_len:
self.value_len = None
elif self.value_len is not None:
self.value_len += self.items[k].value_len
if not self.value_len:
self.value_len = 0
print( 'Value len:', self.value_len, data )
#print( 'Value len:', self.value_len, data )

def parse_value( self, val ):
parsed = {}
Expand Down Expand Up @@ -433,7 +433,8 @@ def encode_value( self, val ):
return val

class _dp_object( object ):
EXPOSE_ITEMS = ( 'value_type', 'unit', 'enum_range', 'int_min', 'int_max', 'int_step', 'int_scale', 'bitmap', 'maxlen' )
COMMON_ITEMS = ( 'dp', 'name', 'alt_name', 'names', 'raw_value', 'value' )
OPTION_ITEMS = ( 'value_type', 'unit', 'enum_range', 'int_min', 'int_max', 'int_step', 'int_scale', 'bitmap', 'maxlen' )
def __init__( self, device, dp ):
super( _dp_object, self ).__setattr__( 'device', device )
super( _dp_object, self ).__setattr__( 'dp', dp )
Expand All @@ -457,7 +458,7 @@ def _update_value( self, new_value ):

def _update_obj( self, new_obj ):
super( _dp_object, self ).__setattr__( 'obj', new_obj )
for k in self.EXPOSE_ITEMS:
for k in self.OPTION_ITEMS:
super( _dp_object, self ).__setattr__( k, getattr( self.obj, k, None ) )

def __setattr__( self, key, data, *args, **kwargs ):
Expand All @@ -481,11 +482,30 @@ def __setattr__( self, key, data, *args, **kwargs ):
#return super( _dp_object, self ).__setattr__( key, data, *args, **kwargs )
raise AttributeError( 'Attempted to set %r but only "value" can be set!' % key )

def __repr__( self ):
def _as_dict( self ):
d = {}
for k in ( 'dp', 'name', 'alt_name', 'names', 'raw_value', 'value' ) + self.EXPOSE_ITEMS:
for k in self.COMMON_ITEMS + self.OPTION_ITEMS:
d[k] = getattr( self, k, None )
return repr(d)
return d

# override __dict__ (and vars())
@property
def __dict__(self):
return self._as_dict()

def __repr__( self ):
return repr(self._as_dict())

# allows dict()
def __iter__( self ):
for k in self.COMMON_ITEMS + self.OPTION_ITEMS:
yield (k, getattr( self, k, None ))

#def __getitem__( self, key ):
# return getattr( self, key, None )

#def __dir__( self ):
# return list(self.COMMON_ITEMS + self.OPTION_ITEMS)

class mapped_dps_object( object ):
def __init__( self, device ):
Expand Down Expand Up @@ -629,28 +649,29 @@ def _process_response( self, data ):

new_dps = {}
changed = []
all_dps = []
for dp_id in data['dps']:
dp_id_s = str(dp_id)
has_changed, dst = self.dps._update_value( dp_id_s, data['dps'][dp_id] )
all_dps.append( dst )

# set both primary and alt names
if dst.name:
new_dps[dst.name] = dst.value
if (dst.alt_name) and (dst.alt_name != dst.name):
new_dps[dst.alt_name] = dst.value
# prefer alt name
if has_changed:
changed.append( dst.alt_name )
elif has_changed:
if has_changed:
# only use name if no alt name
changed.append( dst.name )
changed.append( dst )
else:
# no name, so use DP ID
new_dps[dst.dp] = dst.value
if has_changed:
changed.append( dst.dp )
changed.append( dst )

data['raw_dps'] = data['dps']
data['dps'] = new_dps
data['dps_objects'] = all_dps
data['changed'] = changed
return data

Expand Down Expand Up @@ -727,7 +748,7 @@ def set_timer(self, num_secs, dps_id=0, nowait=False):
if possible:
found = possible
else:
# core's set_timer() says last DP ID is probably the timer, so use it
# set_timer() in tinytuya.core says last DP ID is probably the timer, so use it
for obj in self.dps:
found = obj
dps_id = found.dp
Expand Down
13 changes: 11 additions & 2 deletions tinytuya/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,11 @@ def read_data( self ):
elif self.step == FSCAN_FINAL_POLL:
result = self.device._decode_payload( msg.payload )
result = self.device._process_response( result )
if result and isinstance(result, dict):
if 'changed' in result:
del result['changed']
#if 'dps_objects' in result:
# del result['dps_objects']
if self.debug:
print('ForceScannedDevice: Final Poll', self.ip, self.step, payload)
print(result)
Expand Down Expand Up @@ -859,6 +864,11 @@ def read_data( self ):
log.debug("PollDevice: raw unpacked message = %r", msg)
result = self.device._decode_payload(msg.payload)
result = self.device._process_response( result )
if result and isinstance(result, dict):
if 'changed' in result:
del result['changed']
#if 'dps_objects' in result:
# del result['dps_objects']
except:
log.debug("PollDevice: error unpacking or decoding tuya JSON payload")
result = tinytuya.error_json(tinytuya.ERR_PAYLOAD)
Expand Down Expand Up @@ -1696,10 +1706,9 @@ def save_snapshotfile(fname, data, term=None):
for itm in data:
devices.append( _snapshot_save_item(itm) )
current = {'timestamp' : time.time(), 'devices' : devices}
output = json.dumps(current, indent=4)
print(bold + "\n>> " + norm + "Saving device snapshot data to " + fname + "\n")
with open(fname, "w") as outfile:
outfile.write(output)
json.dump(current, outfile, indent=4, default=dict)

# Scan Devices in snapshot.json
def snapshot(color=True):
Expand Down

0 comments on commit d38194e

Please sign in to comment.