
    j{                         d Z ddlZddlZddlZddlZ	 ddlZddl  G d d	e      Zy# e$ r>Z ed        ed        edj                  ej                  d                Y dZ[OdZ[ww xY w)
a  
 Python module to interface with Tuya WiFi smart devices

 Author: Jason A. Cox
 For more information see https://github.com/jasonacox/tinytuya

 Local Control Classes
    Cloud(apiRegion, apiKey, apiSecret, apiDeviceID, new_sign_algorithm)

 Functions
    Cloud
        setregion(apiRegion)
        cloudrequest(url, action=[POST if post else GET], post={}, query={})
        getdevices(verbose=False)
        getstatus(deviceid)
        getfunctions(deviceid)
        getproperties(deviceid)
        getdps(deviceid)
        sendcommand(deviceid, commands [, uri])
        getconnectstatus(deviceid)
        getdevicelog(deviceid, start=[now - 1 day], end=[now], evtype="1,2,3,4,5,6,7,8,9,10", size=100, params={})
          -> when start or end are negative, they are the number of days before "right now"
             i.e. "start=-1" is 1 day ago, "start=-7" is 7 days ago

 Reference
    * https://developer.tuya.com/en/docs/cloud/device-connection-service?id=Kb0b8geg6o761

    NzGWARN: Unable to import requests library, Cloud functions will not work.zNWARN: Check dependencies. See https://github.com/jasonacox/tinytuya/issues/377zWARN: Error: {}.   )*c                       e Zd ZddddddefdZddZddZd ZddZdd	Z	d
 Z
ddZdg dfdZd ZddZd dZddZddZddZddZd!dZddZd"dZed        Zed        ZddZd Zd Zy)#CloudNTc                 D   || _         || _        || _        || _        || _        d| _        d| _        || _        d| _        || _	        d| _
        d| _        d| _        |r|sb	 i }	t        | j                         5 }
t        j                  |
      }	|	d   | _        |	d   | _        |	d   | _        d|	v r
|	d   | _        ddd       | j'                  |       | j                  s| j)                          yy# 1 sw Y   8xY w#  t!        t"        d	      | _        t%        d	      xY w)
a  
        Tuya Cloud IoT Platform Access

        Args:
            apiRegion (str, optional): Tuya API region code (e.g., 'us', 'eu', 'cn', 'in').
            apiKey (str, optional): Tuya Cloud API key.
            apiSecret (str, optional): Tuya Cloud API secret.
            apiDeviceID (str, optional): Device ID for initial API calls.
            new_sign_algorithm (bool, optional): Use new sign algorithm for API requests. Default: True.
            initial_token (str, optional): The auth token from a previous run. It will be refreshed if expired.
            configFile (str, optional): Path to the config file to use for credentials. Default: 'tinytuya.json'.
            **extrakw: Additional keyword arguments for future compatibility.

        If apiKey or apiSecret are not provided, credentials will be loaded from the config file.

        Playload Construction - Header Data:
            Parameter 	  Type    Required	Description
            client_id	  String     Yes	client_id
            signature     String     Yes	HMAC-SHA256 Signature (see below)
            sign_method	  String	 Yes	Message-Digest Algorithm of the signature: HMAC-SHA256.
            t	          Long	     Yes	13-bit standard timestamp (now in milliseconds).
            lang	      String	 No	    Language. It is zh by default in China and en in other areas.
            access_token  String     *      Required for service management calls

        Signature Details:
            * OAuth Token Request: signature = HMAC-SHA256(KEY + t, SECRET).toUpperCase()
            * Service Management: signature = HMAC-SHA256(KEY + access_token + t, SECRET).toUpperCase()

        URIs:
            * Get Token = https://openapi.tuyaus.com/v1.0/token?grant_type=1
            * Get UserID = https://openapi.tuyaus.com/v1.0/devices/{DeviceID}
            * Get Devices = https://openapi.tuyaus.com/v1.0/users/{UserID}/devices

        REFERENCE:
            * https://images.tuyacn.com/smart/docs/python_iot_code_sample.py
            * https://iot.tuya.com/cloud/products/detail
         Nr   T	apiRegionapiKey	apiSecretapiDeviceIDz"Tuya Cloud Key and Secret required)
CONFIGFILEr	   r
   r   r   urlhostuidtokenerrornew_sign_algorithmserver_time_offsetuse_old_device_listmappingsopenjsonload
error_jsonERR_CLOUDKEY	TypeError	setregion	_gettoken)selfr	   r
   r   r   r   initial_token
configFileextrakwconfigfs              ;/DATA/.local/lib/python3.12/site-packages/tinytuya/Cloud.py__init__zCloud.__init__2   s!   N %""&"

"4"##' 	F$//*a!YYq\F%+K%8DN"("2DK%+K%8DN$.+1-+@( + 	y!zzNN # +*F' 8

   DEEs%   !C= 8AC1:C= 1C:6C= ="Dc                    || j                   }|j                         | _         d| _        | j                   dk(  s| j                   dk(  rd| _        y | j                   dk(  s| j                   dk(  rd| _        y | j                   dk(  rd	| _        y | j                   d
k(  s| j                   dk(  rd| _        y | j                   dk(  rd| _        y | j                   dk(  rd| _        y y )Nzopenapi.tuyacn.comusazzopenapi.tuyaus.comzus-euezopenapi-ueaz.tuyaus.comeuzopenapi.tuyaeu.comzeu-wwezopenapi-weaz.tuyaeu.cominzopenapi.tuyain.comsgzopenapi-sg.iotbing.com)r	   lowerr   )r   r	   s     r$   r   zCloud.setregion   s    I"*+>>T!T^^t%;/DL^^v%4)?4DL^^t#/DL^^v%4)?4DL^^t#/DL^^t#3DL $    Fc                    |rd| j                   d|d|}n,|d   dk(  rd| j                   |}nd| j                   d|}i }	i }
|}|t        j                  |      }
|dvr|rdnd}|dk(  r|d}|r||	d	<   |rt        |      t        k(  r|d   d
k(  r||z  }n|d
|z   z  }|}nt        |      t
        k(  rg }t        |j                               D ]  }|j                  |||   f        |}|d
dj                  |D cg c]"  }t	        |d         dz   t	        |d         z   $ c}      z   z  }t        j                  |||      j                         }|j                  }n4t        j                  |||      j                         }|j                  x}}t        t        j                         dz        }|	rEt        t!        |	j#                               ddj                  |	j                               fgz         ni }	| j$                  (| j&                  t	        |      z   }| j(                  |	d<   n%| j&                  | j$                  z   t	        |      z   }| j*                  r|d|z  t-        j.                  t1        |
xs dj3                  d                  j5                         z   dz   dj                  |	j7                  dd      j9                  d      D cg c]  }||	v r|d|	|   d c}      z   dz   dz   |j9                  dd      d   j9                  dd      d   z   z  }t;        j<                  | j(                  j3                  d      |j3                  d      t,        j.                        j5                         j?                         }| j&                  |	d<   ||	d<   t	        |      |	d<   d|	d<   d|	d <   | j$                  | j$                  |	d!<   |dk(  rPt        j6                  ||	"      }t@        jC                  d#||	|jD                  |jF                  | j$                         nft@        jC                  d$||	|
       t        jH                  ||	|
%      }t@        jC                  d&|jD                  |jF                  | j$                         d'|jF                  v rv|d(u rt@        jC                  d)       yt@        jC                  d*       | jK                          | j$                  st@        jC                  d+       y| jM                  ||||d(      S 	 t        jN                  |jP                  jS                               }d| _*        |S c c}w c c}w #  	 t        jN                  |jP                        }Y |S #  tW        tX        d,|jP                  z        | _*        | jT                  cY cY S xY wxY w)-z<
        Handle GET and POST requests to Tuya Cloud
        zhttps:///r   N)GETPOSTPUTDELETEr3   r2   zapplication/jsonzContent-type?&=r   )params  zSignature-Headers:secretz%s
r   zutf-8
z//)msg	digestmod	client_idsigntzHMAC-SHA256sign_methodcorsmodeaccess_token)headersz8GET: URL=%s HEADERS=%s response code=%d text=%s token=%szPOST: URL=%s HEADERS=%s DATA=%s)rH   dataz'POST RESPONSE: code=%d text=%s token=%sztoken invalidTz,Failed 2nd attempt to renew token - AbortingzToken Expired - Try to renewzFailed to renew tokenz*Cloud _tuyaplatform() invalid response: %r)-r   r   dumpstypestrdictsortedkeysappendjoinrequestsRequestprepareurlinttimelistitemsr   r
   r   r   hashlibsha256bytesencode	hexdigestgetsplithmacnewupperlogdebugstatus_codetextpostr   _tuyaplatformloadscontentdecoder   r   r   )r   uriactionrh   ver	recursivequerycontent_typerU   rH   bodysign_urlsorted_querykxreqnowpayloadkey	signatureresponseresponse_dicts                         r$   ri   zCloud._tuyaplatform   sc   
 (,c3?CVs]$(LL#6C  &*\\37C::d#D99#VFV 4-L&2GN#E{c!8s?5LC3;&C ;$&#%L#EJJL1$++aq]< 2(EchhV[0\V[QRQqTS3qt91LV[0\&^ ^^H"**63uEMMOC''C"**63uEMMOC%(WW,Hs$))+d"#el$tGMMO,1Dchhw||~F^0_/``art::kkCH,G $GHkkDJJ.S9G ""udjb%8%8%ABCMMOPRVW'.{{3F'K'Q'QRU'V/'V"g~ %(6'V/ 00 37	7
 
 nnT1-b177Q?CD EG HHNN!!'*w'nn
 )+eeg	 	  ${{#3x!. ::!&*jjGN# U?||C9HIIJCQXZbZnZnpxp}p}  @D  @J  @J II13  }}S'EHII98;O;OQYQ^Q^`d`j`j
 hmm+D 		HIII45NN::		12))#vtS$GG	" JJx'7'7'>'>'@AMDJ a 1]$/h	"" $

8+;+; < "' @8CSCSS
 zz!s0   'U"U#4U# #V?&V0V<8V?<V?c                    d | _         | j                  d      }|r	d|vs|d   s't        t        d|d   z        | _        | j                  S d|v rct        |d   dz  t        j                         z
  dz        | _        | xj                  dz  c_        t        j                  d| j                         |d	   d
   | _         | j                   S )Nztoken?grant_type=1successzCloud _gettoken() failed: %rr?   rC   g     @@x   zserver_time_offset: %rresultrG   )
r   ri   r   ERR_CLOUDTOKENr   roundrW   r   rd   re   )r   r~   s     r$   r   zCloud._gettoken  s    
**+?@	 >mT]F^#.u1EEDJ ::-&+}S/AF/Jdiik.Y]`-`&bD###s*#II.0G0GH"8,^<
zzr/   c                 .   | j                   s| j                  S |st        t        d      S d|z  }| j	                  |      }|d   sGd|vrd|d<   d|vrd|d<   t
        j                  d|d          t        t        d	|d   d
|d         S |d   d   }|S )Nz%_getuid() requires deviceID parameter
devices/%sr   coder>   r?   zUnknown ErrorError from Tuya Cloud: %rzError from Tuya Cloud: Code z: r   r   )r   r   r   
ERR_PARAMSri   rd   re   	ERR_CLOUD)r   deviceidrm   r~   r   s        r$   _getuidzCloud._getuid"  s    zz::7  X%**3/Y']*(*f%M)'6e$II+]5-A 8Ef8M}]bOcd 
 H%e,
r/   c                 n    | j                   s| j                  S ||rdnd}| j                  |||d|      S )a  
        Make a generic cloud request and return the results.

        Args:
          url:    Required.  The URL to fetch, i.e. "/v1.0/devices/0011223344556677/logs"
          action: Optional.  GET, POST, DELETE, or PUT.  Defaults to GET, unless POST data is supplied.
          post:   Optional.  POST body data.  Will be fed into json.dumps() before posting.
          query:  Optional.  A dict containing query string key/value pairs.
        Nr3   r2   )rn   rh   ro   rq   )r   r   ri   )r   rU   rn   rh   rq   s        r$   cloudrequestzCloud.cloudrequest>  s@     zz::>#VF!!#f4TQV!WWr/   c                     |D ]U  }d|vs|d   sd}|D ].  }d|v s|d   |d   k(  sd}|D ]  }||vs||   r||   ||<    0 |rE|j                  |       W y )NidFT)rP   )r   result1result2
new_devicefoundexisting_devicerv   s          r$   _update_device_listzCloud._update_device_listQ  s    !J:%Z-=E#*?*t/D
SWHX/X E'O3?1;M1;AOA. ( $+ 
, "r/   c                    d}dg i}d }d}d}|rEdd|d}d}	|rAt        |t              st        |t              rdj                  |      |d	<   n||d	<   nd
di}d}	|r| j	                  |	|      }
|dz  }d}t        |
      t        k(  r@t        j                  d       t        j                  t        j                  |
d             nt        j                  d|
       |
D ]}  }|dk(  rnd|
|   v rd|
|   vr||xx   |
|   d   z  cc<   nd|
|   v r||xx   |
|   d   z  cc<   d|
|   v r|
|   d   }d|
|   v r|
|   d   |d<   d|
|   v sm|
|   d   }v|
|   ||<    |r||d<   ||d<   |S )Nr   r   T75tuyaUser)	page_sizesource_type	source_idz/v1.3/iot-03/devices,
device_idssize50z%/v1.0/iot-01/associated-users/devicesrq   r   FzCloud response:   indentzCloud response: %rrX   devicestotallast_row_keyhas_morefetches)
isinstancetuplerX   rQ   r   rK   rM   rd   re   r   rJ   )r   r   r   r   
our_resultr   r   r   rq   rm   r   is               r$   _get_all_deviceszCloud._get_all_devices_  s   %
!%jsSE(Cz52j*d6T*-((:*>E,'*4E,' DME9C&&5&:FqLGHF|t#		,.		4::va9;		/9 =*yq	/I"16)::"fQi/"19)==&)+VAYw5GU%206q	.0In-!VAY.#)!9Z#8$*1IJqM  8 !(
9#
7r/   c                    i }|r<|D ]7  }t        |t              rd|vrt        j                  d|       .|d   }|||<   9 | j                  r| j
                  ri }i }| j                  j                  d      D ]B  }|j                         }|s| j                  |      }	|	s*t        |	t              r|	c S d||	<   D |st        t        d      S |D ]A  }	d|	z  }
| j                  |
      }|D ]$  }||vs|dk7  r	||   ||<   ||xx   ||   z  cc<   & C nj| j                         }i }|d   D ]  }d|v sd||d   <    |r?|j                         D ],  }	| j                  |		      }| j                  |d   |d          . |r|S |rd|vrt        t        d
      S || _        |d   }g }g }|D ]  }|d   }||vr|j!                  |       ||   }d|vs|d   |d   k7  r|j!                  |       Dd|vrd|v s|rd|vs|d   |j!                  |       id}t"        D ]&  }||v s|dk7  s|dk7  s||vs||   ||   k7  s$d} n |s|j!                  |       |j!                  |        |r| j%                  |      }|D ]B  }|D ]  }d|v s|d   |k(  s||   |d<    ||   s&|D ]  }d|v s|d   |k(  s||   |d<    D |D ]A  }d|vs|d   |j'                  d      }|s!||v s&||   j'                  d      }|=||d<   C t        j)                  dt+        |             t        j)                  dt+        |             | j-                  |      |z   S )z
        Return dictionary of all devices.

        Args: 
            verbose - Returns raw JSON data from Tuya Cloud
            oldlist - List of devices from previous run
            include_map - Include the DPS mapping in the device list
        r   z#Skipping malformed device entry: %sr   Tz!Unable to get uid for device listzusers/%s/devicesr   r   )r   zUnable to get device listr{   	local_keyiconmappinglast_ipF
product_idzchanged: %dzunchanged: %d)r   rM   rd   warningr   r   r`   stripr   r   r   ri   r   rO   r   getdevices_rawrP   DEVICEFILE_SAVE_VALUESgetmappingsr_   re   lenfilter_devices)r   verboseoldlistinclude_mapold_devicesdevdev_id	json_datauid_listr   rm   json_runrv   users
json_data2devschanged_devicesunchanged_devicesoldis_samer   	productidold_mappings                          r$   
getdeviceszCloud.getdevices  s    !3.$c/KK EsKT&)F#   8 8IH **005llF,sD*J$(HSM 6 !7 
  (3.--c2!A*X'/{	! "!3 "   --/IE *C<(,E#e*% +  !::<C!%!6!6C!6!AJ,,i.A:hCWY ( hi7+ 
 (" CYF[(&&-f%CC3u:[1A#A&&-s"3[i_bNbfijsftf|&&-G+8VYASLTWXYTZ^abc^dTd#G , &&-$$c+/ 2 '':H%	*C#s*s</@I/M)1))<I + I&0'3.3|3D	3Q-5i-@C	N  1 &" 'C'3y>+A WWT]F&K"7&1&&9&=&=i&H&2-8C	N ' 			=#o"68		?C(9$:< ""O58IIIr/   c                     |r{ddj                  |d d       z  }| j                  |      }t        j                  t	        j
                  |d             d|v r|d   D ]  }d|v s|d   }|d= |||<    |dd  }|rzy y )Nz#devices/factory-infos?device_ids=%sr   2   r   r   r   r   )rQ   ri   rd   re   r   rJ   )r   maclistr   rm   r   r   r   s          r$   _get_hw_addresseszCloud._get_hw_addresses%  s    7388GCRL;QRC'',FIItzz6!576!!(+Cs{!$TI*-	 ,
 bclG r/   c                    i }| j                  ||D cg c]  }|d   	 c}       g }d| j                  j                  dd      d   z   dz   }|D ]  }|d   }d|vrdn|d   j                         |d|vrdn|d   d	|vrdn|d	   d
}||v rdD ]  }	|	||   v s||   |	   ||	<    |rd	|v r|d	   |v r||d	      |d<   t        D ]   }	|	|v s|	dk(  r|||	   z   ||	<   ||	   ||	<   " d|v r
d}	||	   ||	<   |j                  |        |S c c}w )Nr   zhttps://images..r   r1   namer   r   mac)r   r   r{   r   )r   uuidsnipr   
gateway_id)r   r   r`   r   r   rP   )
r   r   ip_listjson_mac_datar   tuyadevices	icon_hostr   itemrv   s
             r$   r   zCloud.filter_devices3  sr   /FA$/FH%(:(:C(DQ(GG#M	AtWF$Ao1V9??3D(1rq~"!^r5	D &,AM&11"/"7":Q - 5D=T%[G-C$T%[1T
+6F{"+ad"2Q"#A$Q , q  A$Qt$9 < G 0Gs   D	
c                     | j                   s| j                  S |st        t        d      S d|d|}| j	                  |      }|d   st
        j                  d|d          |S )NMissing DeviceID Parameteriot-03/devices/r1   r   r   r?   r   r   r   r   ri   rd   re   )r   paramr   rm   r~   s        r$   
_getdevicezCloud._getdevice[  sp    zz::,  
 )1%8**3/Y'II+]5-A r/   c                 &    | j                  d|      S )z/
        Get the status of the device.
        statusr   r   r   s     r$   	getstatuszCloud.getstatusl  s     x22r/   c                 &    | j                  d|      S )z2
        Get the functions of the device.
        	functionsr   r   s     r$   getfunctionszCloud.getfunctionsr  s     {H55r/   c                 &    | j                  d|      S )z3
        Get the properties of the device.
        specificationr   r   s     r$   getpropertieszCloud.getpropertiesx  s     99r/   c                     | j                   s| j                  S |st        t        d      S d|z  }| j	                  |d      }|d   st
        j                  d|d          |S )zI
        Get the specifications including DPS IDs of the device.
        r   zdevices/%s/specificationszv1.1ro   r   r   r?   r   r   r   rm   r~   s       r$   getdpszCloud.getdps~  sr     zz::,  *X6**3F*;Y'II+]5-A r/   c                     | j                   s| j                  S |r|st        t        d      S |d|z  z  }| j	                  |d|      }|d   st
        j                  d|d          |S )z.
        Send a command to the device
        z*Missing DeviceID and/or Command Parametersz%s/commandsr3   )rn   rh   r   r   r?   r   )r   r   commandsrm   r~   s        r$   sendcommandzCloud.sendcommand  s{     zz::(<  	}))**3f(*KY'II+]5-A r/   c                     | j                   s| j                  S |st        t        d      S d|z  }| j	                  |d      }|d   st
        j                  d|d          |d   d	   S )
z6
        Get the device Cloud connect status.
        r   r   v1.0r   r   r   r?   r   onliner   r   s       r$   getconnectstatuszCloud.getconnectstatus  sx     zz::,  h'**3F*;Y'II1=3GHX&x01r/   c	                 r   |st        t        d      S |s.t        t        j                         | j                  z   dz        }nN|dk  r4t        t        j                         | j                  z   |dz  z   dz        }nt
        j                  |      }|s|dz
  }nN|dk  r4t        t        j                         | j                  z   |dz  z   dz        }nt
        j                  |      }||kD  r|}	|}|	}|sd}nt        |      t        k(  rnt        |      t        k(  r|j                  d      }nt        |      t        k(  rt        |      }ngt        |      t        k(  st        |      t        k(  r)dj                  |D 
cg c]  }
t        |
       c}
      }nt        d	t        |      d
|      |}|sd}n|dkD  rd}|r|dk  rd}t        |      t        k7  ri n|j!                         }d|vr||d<   d|vr||d<   d|vr||d<   d|vr||d<   d|vrd|d<   |r||d<   | j#                  d|z  |      }|dz  }d}|rd|v r|d   }d}d}|r|rd|v rd|v r|d   r|rt%        |d         |k  rd|v r|d   r||d   k7  rd}|dz  }|dz  }|d   |d<   |d   }d|d<   d|d<   | j#                  d|z  |      }|r8d|v r4|d   }d|v r|dxx   |d   z  cc<   d}d|v r|d   |d<   d|v r
|d   |d<   nn6|r4|r2d|v r.d|v r*|d   r%|rt%        |d         |k  rd|v r|d   r	||d   k7  r||d<   |S c c}
w )aw  
        Get the logs for a device.
        https://developer.tuya.com/en/docs/cloud/0a30fc557f?id=Ka7kjybdo0jse

        Note: The cloud only returns logs for DPs in the "official" DPS list.
          If the device specifications are wrong then not all logs will be returned!
          This is a limitation of Tuya's servers and there is nothing we can do about it.

        Args:
          devid:  Required.  Device ID
          start:  Optional.  Get logs starting from this time.  Defaults to yesterday
          end:    Optional.  Get logs until this time.  Defaults to the current time
          evtype: Optional.  Limit to events of this type.  1 = Online, 7 = DP Reports.  Defaults to all events.
          size:   Optional.  Target number of log entries to return.  Defaults to 0 (all, up to max_fetches*100).
                               Actual number of log entries returned will be between "0" and "size * 2 - 1"
          max_fetches: Optional. Maximum number of queries to send to the server.  Tuya's server has a hard limit
                               of 100 records per query, so the maximum number of logs returned is "max_fetches * 100"
          start_row_key: Optional. The "next_row_key" from a previous run.
          params: Optional.  Additional values to include in the query string.  Defaults to an empty dict.

        Returns:
          Response from server
        r   r:   r   iQ i \&z1,2,3,4,5,6,7,8,9,10utf8r   zUnhandled 'evtype' type z - d   r   r   
start_timeend_timerK   r   
query_typestart_row_keyz/v1.0/devices/%s/logsr   r   Tr   logshas_nextnext_row_keyFNr   )r   r   rV   rW   r   r   format_timestamprK   rL   r\   rl   rX   r   rQ   
ValueErrorrM   copyr   r   )r   r   startendevtyper   max_fetchesr  r9   tmpr   	want_sizeretr   r   againr  resr   s                      r$   getdevicelogzCloud.getdevicelog  s   0 ,  tyy{T%<%<<DEC1W		d&=&==#+NSWWXC((#/C:&EQY$))+(?(??EEMRW[[\E**E3E3;CEC ,F&\S &\U"]]6*F&\S [F&\T!T&\U%:XX71A79F4<QWXZZ	DCZD kAoKF|t+v%#(F< V#!$F:#F6N!F6Nv%#$F< &3F?#!88!C6Rq8s?]FELkf$&(VJ-?"c&.&9D&@"f,1GL\bcq\rLrq 1*0*@'%n5)-~&%*z"'')@8)KSY'Z8s?!(mG(v'&/9 $!W,-4Z-@z*%0181H~.1 kf$&(VJ-?"c&.&9D&@"f,1GL\bcq\rLr, %C	N
A  8s   ?L4c                     t        |       t        k7  r=t        t        t        |                   dk(  rt        | dz        } | S t        |       } | S t        t        |             dk(  r| dz  } | S )N
   r:   )rK   rV   r   rL   )tss    r$   r  zCloud.format_timestamp4  sk     8s?3s2w< B&"t)%
 	 "Y 	 R\R$JB	r/   c                 Z   | D ]  }	 |d   }d|vr|nt        |d         }||v r"||d   d}|d   j                         dk(  r|d   }n	 t        j                  |d         }|rst	        |      t
        k(  rad|v r]|d   rX|d   j                  dd	      j                  d
d      j                  dd	      j                  dd      j                  dd      |d<   |d   j                         dk(  r|d   |d<   ||d<   |||<    y #  |d   }Y xY w#  t        j                  dd       Y 'xY w)Nr   dp_idrK   )r   rK   stringvaluesunitu   ℉u   °Fu   ℃u   °Cr#   cu   秒sr   
raw_valueszParse mapping item failed!T)exc_info)	rL   r.   r   rj   rK   rM   replacerd   re   )srcdstmappr   r  rI   r  s          r$   _build_mappingzCloud._build_mapping@  sr    DIF| 't 3T']9KC<!%tF|=<%%'83!(^F0!%T(^!= d6ld2v7Gf~ *0)?)?e)L)T)TUZ[`)a)i)ijmns)t)|)|  ~A  BG  *H  *P  *P  QV  WZ  *[v <%%'61)-hD&!'X!E
1 0!%hI		7$	Hs)   D$D
D"BDD	DD*c                    | j                   si | _         || j                   v r| j                   |   S |r| j                  |      }|rd|v r`|d   }i }d|v r| j                  |d   |       d|v r| j                  |d   |       || j                   |<   t        j	                  d||       n'd|v r|d   dk(  sd|v r|d   dk(  ri | j                   |<   || j                   v r| j                   |   S y )	Nr   r   r   z$Downloaded mapping for device %r: %rr   i  r?   znot support this device)r   r   r#  rd   re   )r   r   r   r   dpss        r$   
getmappingzCloud.getmapping_  s    }}DM%==++[[*Fv%#H-FC6)++VH-=sD"f,++VK-@#G/2DMM),IIExQTU&6&>T+AuPV[abg[h  mF  \F/1DMM),%==++ r/   c                 8    t        |      t        k(  r|| _        y y N)rK   rM   r   )r   r   s     r$   setmappingszCloud.setmappings  s    >T!$DM "r/   c                     | j                   si | _         |D ].  }	 |d   }|d   }|| j                   vs| j                  ||       0 | j                   S #  Y AxY w)Nr   r   )r   r&  )r   r   r   devidr   s        r$   r   zCloud.getmappings  sf     }}DMCD	-	
 -E3  }}s   
AAr(  )r2   Nr   FNN)NNN)NN)r   N)NNr   )NNNNr   r   NN)__name__
__module____qualname__r   r%   r   ri   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  staticmethodr  r#  r&  r)  r    r/   r$   r   r   1   s    !%ddPTim  ~B  OY L\4&xt*8X&-6p "' LJ\#&P"36:((2$zx 	 	 I I<"H%
r/   r   )__doc__rZ   ra   r   rW   rR   ImportErrorimpErrprintformatargscoreobjectr   r0  r/   r$   <module>r9     sv   :    5 hF h  5	
ST	
Z[	

#
#FKKN
3445s   ) A,4A''A,