+
     viI  c                   s   R t ^ RIt^ RIt^ RIHt ^ RIHt ^ RIHt ^ RI	H
t
 ]P                  ! ]4      t^t^t^t^t^t^ t^!t^"tR]^2^d3/tR]^ ^d3/t^t^<t^-t^2t^Bt^t^ t^tR]^ ^d3R]^2^d3/t ^t!^t"^t#^t$^t%^ t&Rt']PP                  PR                  ]PP                  PT                  ,          ]PP                  PV                  ,          t, ! R	 R
]4      t- ! R R]-4      t. ! R R].4      t/ ! R R]-4      t0 ! R R].4      t1R t2]/t3]0t4]1t5R# )u   liquidctl drivers for fifth generation Asetek 690LC liquid coolers.

Supported devices:

- EVGA CLC (120 CL12, 240, 280 or 360); modern generic Asetek 690LC
- NZXT Kraken X (X31, X41 or X61); legacy generic Asetek 690LC
- NZXT Kraken X (X40 or X60); legacy generic Asetek 690LC
- Corsair Hydro H80i GT, H100i GTX or H110i GTX
- Corsair Hydro H80i v2, H100i v2 or H115i

Copyright Jonas Malaco and contributors

Incorporates or uses as reference work by Kristóf Jakab, Sean Nelson
and Chris Griffith.

SPDX-License-Identifier: GPL-3.0-or-later
N)	UsbDriverNotSupportedByDevice)RuntimeStorage)clamppumpfani  c            
       s   a a ] tR t^Kt oRtRt]RV 3R ll4       t]V 3R l4       tR t	R t
R tR t. RO. RO. RO]^ ^ RRRR	3
R
 ltR tV 3R ltR tV 3R ltR tRtVtV ;t# )
_Base690Lcz(Common methods for Asetek 690LC devices.Fc              +  sj   <"   W P                   8w  d   R# \        SV `  ! V3/ VB  Rj  xL
  R#  L5i)z8Probe `handle` and yield corresponding driver instances.N)_LEGACY_690LCsuperprobe)clsZhandlelegacy_690lckwargs	__class__   &&&,</usr/lib/python3.14/site-packages/liquidctl/driver/asetek.pyr
   Z_Base690Lc.probeP   s.      ,,,7=26222s   '313c                s<   < \         SV `  ! RRV P                  /VB # )zuFind devices specifically compatible with this driver.

Automatically sets the appropriate value for `legacy_690lc`.
r    )r	   find_supported_devicesr   )r   r   r      &,r   r   Z!_Base690Lc.find_supported_devicesW   s$     w-W3;L;LWPVWW    c                s    \         P                  RV4       V'       d,   V P                  P                  \        \
        \        4       R# V P                  P                  \        \
        \        4       R# )z>Set the software clear-to-send flow control policy for device.zset clear to send = %sN)_LOGGERdebugdevicectrl_transfer
_USBXPRESS_USBXPRESS_REQUEST_USBXPRESS_CLEAR_TO_SEND_USBXPRESS_NOT_CLEAR_TO_SEND)selfclear_to_send   &&r   _configure_flow_controlZ"_Base690Lc._configure_flow_control`   sD    .>KK%%j2DF^_KK%%j2DFbcr   c                s    \         P                  R4       V P                  P                  4        V P                  P	                  \
        \        \        4       R# )z5Begin a new transaction before writing to the device.zbegin transactionN)r   r   r   Zclaimr   r   r   _USBXPRESS_FLUSH_BUFFERSr      &r   _begin_transactionZ_Base690Lc._begin_transactionh   s7    )*!!*.@BZ[r   c                sF    V P                   P                  \        V4       R # N)r   Zwrite_WRITE_ENDPOINT)r   Zdatar   r   _writeZ_Base690Lc._writen   s    /40r   c                s    V P                   P                  \        \        4      pV P                   P	                  4        V# )a`  End the transaction by reading from the device.

According to the official documentation, as well as Craig's open-source
implementation (libSiUSBXp), it should be necessary to check the queue
size and read the data in chunks.  However, leviathan and its
derivatives seem to work fine without this complexity; we also
successfully follow this approach.
)r   Zread_READ_ENDPOINT_READ_LENGTHZrelease)r   msg   & r   _end_transaction_and_readZ$_Base690Lc._end_transaction_and_readq   s/     kk~|<
r   Tc                sx    V P                  ^.V,           V,           V,           WEWg'       * VW^ ^.	,           4       R# )i   N)r'   )r   color1color2color3
alert_temp	interval1	interval2blackoutfadingblinkingZenable_alerts   &&&&&&&&&&&r   _configure_deviceZ_Base690Lc._configure_device   s<     	TFVOf,v5!ivtT;; 	<r   c                sX   \        V4      p\        V4      pV^8  d   \        R4      hV\        8  d   \        RV RV R24      h\	        V4       F  w  pw  rV\        WV4      3WW&   K  	  WF,
          p
V
'       d.   \        P                  RV
4       V\        ^d3.V
,          ,           pV# )i   zat least one PWM point requiredztoo many PWM points (z), only z
 supportedu1   filling missing %d PWM points with (60°C, 100%%))	listZlenZ
ValueError_MAX_PROFILE_POINTSZ	enumerater   r   info_CRITICAL_TEMPERATURE)r   profileZmin_dutyZmax_dutyZ
max_pointsZoptZsizeZitempdutyZmissings   &&&&&      r   _prepare_profileZ_Base690Lc._prepare_profile   s    7m3x!8>??''4TF(:,jYZZ(~OA|E$(;<CF  .# LLLgV/56w>>C
r   c                sL   < \         SV `  ! R/ VB pV P                  RR7       V# )zEConnect to the device.

Enables the device to send data to the host.
T)r   r   )r	   connectr    )r   r   retr   s   &, r   r?   Z_Base690Lc.connect   s,     go''$$4$8
r   c                sf    V P                  4        V P                  4        V P                  4        R# )zInitialize the device.N)r$   r6   r,   )r   r   s   &,r   
initializeZ_Base690Lc.initialize   s&    ! &&(r   c                s(   < \         SV `  ! R/ VB  R# )u  Disconnect from the device.

Implementation note: unlike SI_Close is supposed to do,¹ do not send
_USBXPRESS_NOT_CLEAR_TO_SEND to the device.  This allows one program to
disconnect without stopping reads from another.

Surrounding device.read() with _USBXPRESS_[NOT_]CLEAR_TO_SEND would
make more sense, but there seems to be a yet unknown minimum delay
necessary for that to work reliably.

¹ https://github.com/craigshelley/SiUSBXp/blob/master/SiUSBXp.c
Nr   )r	   
disconnectr   r   r   r   r   rB   Z_Base690Lc.disconnect   s     	$V$r   c                    \        4       hzNot supported by this device.r   )r   channelmodeZvaluer   s   &&&&,r   
set_screenZ_Base690Lc.set_screen       "$$r   r   F)    rK   rK   i   rK   rK   )__name__
__module____qualname____firstlineno____doc__r   Zclassmethodr
   r   r    r$   r'   r,   _HIGH_TEMPERATUREr6   r>   r?   rA   rB   rH   __static_attributes____classdictcell____classcell__r   __classdict__   @@r   r   r   K   s     2M3 3 X Xd\1 (1;%6!q#(UY<*)% % %r   r   c                   sp   a a ] tR t^t oR tR
V 3R lltR t^R]. RO^R3R ltR
R lt	R
R lt
R	tVtV ;t# )_ModernBase690Lcc                s    \         P                  R 4       V P                  4        V P                  \        .4       V P                  4        R# )z.instructing device to persist current settingsN)r   r   r$   r'   _CMD_STORE_SETTINGSr,   r"   r#   r   _persistZ_ModernBase690Lc._persist   s7    FG!()*&&(r   Fc                s\   < \         SV `  ! R/ VB  V'       d   V P                  4        R # R # )Nr   )r	   rA   r[   )r   non_volatiler   r   s   &&,r   rA   Z_ModernBase690Lc.initialize   s$    $V$MMO r   c                s   V P                  4        V P                  \        ^ ^ ^ .4       V P                  4       pRP                  ! \        VR,          4      !  pRV^
,          V^,          ^
,          ,           R3RV^ ,          ^,          V^,          ,          R3RV^,          ^,          V^	,          ,          R3RVR	3.# 
zJGet a status report.

Returns a list of `(property, value, unit)` tuples.
z{}.{}.{}.{}:i   i   NzLiquid temperatureu   °Cz	Fan speedZrpmz
Pump speedzFirmware versionZ )r$   r'   	_CMD_LUIDr,   formattupler   r   r*   Zfirmware   &,  r   
get_statusZ_ModernBase690Lc.get_status   s     	!Y1a(),,. ''s9~)>?!3r7SWRZ#7?#a&A+A.63q6Q;Q/72.	
 	
r   Nc
                s   \        V4      pV P                  4        VR8X  d`   \        V\        4      '       d   \	        V4      pV P                  ^#\        V^^4      .4       V P                  \        V^ ^d4      VR7       EM,VR8X  dP   V P                  RV^ ,          V^,          \        V^^4      \        V^ ^d4      VR7       V P                  ^#^ .4       MVR8X  dZ   Vf   TpV P                  RV^ ,          \        V^^4      \        V^^4      \        V^ ^d4      VR7       V P                  ^#^ .4       MvVR	8X  d;   V P                  V^ ,          \        V^ ^d4      VR
7       V P                  ^#^ .4       M5VR8X  d!   V P                  R\        V^ ^d4      VR7       M\        RV 24      hV P                  4        V	'       d   V P                  4        R# R# )*Set the color mode for a specific channel.rainbow)r0   r/   r4   Tr4   r-   r.   r1   r0   r/   r5   Nr5   r-   r1   r2   r0   r/   fixedr-   r0   r/   r3   r3   r0   r/   zunknown lighting mode )r7   r$   Z
isinstanceZstrintr'   r   r6   KeyErrorr,   r[   )r   rF   rG   colorstime_per_colortime_offalert_thresholdalert_colorZspeedr\   r   s   &&&&&&&&&&,r   	set_colorZ_ModernBase690Lc.set_color   s   
 f!9%%%E
KKuUAq123""eOQ.LU`"aX""$vayPQ-2>1c-J.3OQ.LU` # b KKq	"Z)""D-28Q-D-2>1c-J.3OQ.LU` # b KKq	"W_""&)oWXZ]@^*5 # 7KKq	"Z""DU?TUWZ=[*5 # 7 3D6:;;&&(MMO r   c                s   \         V,          w  rVpV P                  W&V\        4      pV F  w  r\        P	                  RWV
4       K  	  \        \        \        V!  4      w  rV P                  4        V P                  V^ .V,           V,           4       V P                  4        V'       d   V P                  4        R# R# )z+Set channel to follow a speed duty profile.u8   setting %s PWM point: (%d°C, %d%%), device interpolatedN)_VARIABLE_SPEED_CHANNELSr>   r8   r   r9   Zmapr7   Zzipr$   r'   r,   r[   )r   rF   r;   r\   r   mtypedmindmaxZadjustedr<   r=   ZtempsZdutiess   &&&&,        r   set_speed_profileZ"_ModernBase690Lc.set_speed_profile  s    4W=T((>QR"JDLLS . # D#x.1!UAJ&/0&&(MMO r   c                sj   VR8X  d?   \         P                  RV4       V P                  ! V^ V3\        ^,
          V3.V3/ VB  R# \        V,          w  rVp\        W&V4      p\        \        ,
          ^,           p\        W&,
          Wv,
          ,          V,          4      p	\        WiWv,
          ,          V,          ,           4      p
\         P                  RWV	4       V P                  4        V P                  V\        V	,           .4       V P                  4        V'       d   V P                  4        R# R# )"Set channel to a fixed speed duty.r   z.using a flat profile to set %s to a fixed dutyNz&setting %s PWM duty to %d%% (level %d))r   r9   rw   r:   _FIXED_SPEED_CHANNELSr   _MAX_PUMP_SPEED_CODE_MIN_PUMP_SPEED_CODEZroundr$   r'   r,   r[   )r   rF   r=   r\   r   rt   ru   rv   Ztotal_levelsZlevelZeffective_dutys   &&&&,      r   set_fixed_speedZ _ModernBase690Lc.set_fixed_speed  s    e LLI7S""7aY9NQR9RTX8Y,Z\hslrs1':TT&+.BBQFt{T[1,>?tT[&9,&FFG=wX]^!U0589:&&(MMO r   r   rJ   rL   )rM   rN   rO   rP   r[   rA   rc   rR   rr   rw   r|   rS   rT   rU   rV   rX   r   rY   rY      s=     )

" ?@1BP[%N r   rY   c                   s8   a  ] tR tRt o RtRRR/ 3.tR tRtV tR# )	Modern690Lci+  z,Modern fifth generation Asetek 690LC cooler.3$     z Asetek 690LC (assuming EVGA CLC)c                sb    \        V P                  V P                  4      pRV n        RV n        V# )a  Take the device handle and return a new Legacy690Lc instance for it.

This method returns a new instance that takes the device handle from
`self`.  Because of this, the caller should immediately discard `self`,
as it is no longer valid to call any of its methods or access any of
its properties.

While it is sometimes possible to downgrade a device that has seen
modern traffic since it booted, this will generally not work.
Additionally, no attempt to disconnect from the device is made while
downgrading the instance.

Thus, callers are strongly advised to only call this function before
connecting to the device from this instance and, in fact, before
calling any other methods at all on the device, from any instance.

Finally, this method is not yet considered stable and its signature
and/or behavior may change.  Callers should follow the development of
liquidctl and the stabilization of this API.
N)Legacy690Lcr   _description)r   legacyr+   r   downgrade_to_legacyZModern690Lc.downgrade_to_legacy2  s.    * T[[$*;*;< r   )r   r   N)	rM   rN   rO   rP   rQ   _MATCHESr   rS   rT   )rW   s   @r   r}   r}   +  s(     6 
;R@H r   r}   c                   s   a a ] tR tRt oRtRRR/ 3.tRtV 3R ltRV 3R	 lltR
 t	V 3R lt
R tRR]. RO3R ltR tR tRtVtV ;t# )r   iM  z,Legacy fifth generation Asetek 690LC cooler.r~   r   z%Asetek 690LC (assuming NZXT Kraken X)Tc                s8   < \         SV `  ! W3/ VB  R V n        R # r%   )r	   __init___data)r   r   Zdescriptionr   r   r   r   r   ZLegacy690Lc.__init__V  s    77 
r   Nc                s   < \         SV `  ! R/ VB pV'       d	   Wn        V# R V P                  R RV P                  R 2pRV P
                   RV P                   2p\        WER.R7      V n        V# )ZvidZ04xZ_pidbusZ_addressr   )Zkey_prefixesr   )r	   r?   r   Z	vendor_idZ
product_idr   Zaddressr   )r   Zruntime_storager   r@   ZidsZlocr   s   &&,   r   r?   ZLegacy690Lc.connect\  su    go''(J
 
 s+4/DECz$,,8C'c5IJDJ
r   c           	     s"   V P                  4        R Fj  p\        V,          w  r#p\        V P                  P	                  V R2\
        VR7      W44      p\        P                  RW4       V P                  W%.4       Kl  	  V P                  4       # )r   _duty)Zof_typeZdefaultzsetting %s duty to %d%%)r   r   )
r$   _LEGACY_FIXED_SPEED_CHANNELSr   r   Zloadrk   r   r9   r'   r,   )r   rF   rt   ru   rv   r=   s   &     r   _set_all_fixed_speedsZ!Legacy690Lc._set_all_fixed_speedsf  s}    !&G <W EEG9E):CQUVX\cDLL2GBKK&	 '
 --//r   c                s   < \         SV `  ! R/ VB  V P                  P                  R R4       V P                  P                  RR4       V P	                  4        \        R/ VB  R# )Z	pump_dutyNZfan_dutyr   )r	   rA   r   storer   _warn_on_unsupported_optionrC   r   r   rA   ZLegacy690Lc.initializeo  sR    $V$

d+

T*""$#-f-r   c                s.   V P                  4       pRP                  ! \        VR,          4      !  pRV^
,          V^,          ^
,          ,           R3RV^ ,          ^,          V^,          ,          R3RV^,          ^,          V^	,          ,          R3RVR	3.# r]   )r   r_   r`   ra   rb   r   rc   ZLegacy690Lc.get_statusv  s     ((* ''s9~)>?!3r7SWRZ#7?#a&A+A.63q6Q;Q/72.	
 	
r   c                sp   \        V4      pV P                  4        VR8X  dC   Vf   ^pV P                  RV^ ,          V^,          \        V^^4      \        V^ ^d4      VR7       MVR8X  dM   Vf   ^pVf   TpV P                  RV^ ,          \        V^^4      \        V^^4      \        V^ ^d4      VR7       McVR8X  d(   V P                  V^ ,          \        V^ ^d4      VR7       M5VR	8X  d!   V P                  R\        V^ ^d4      VR
7       M\	        RV 24      hV P                  4        \        R/ VB  R# )rd   r4   NTrf   r5   rg   rh   ri   r3   rj   unsupported lighting mode r   )r7   r$   r6   r   rl   r,   r   )	r   rF   rG   rm   rn   ro   rp   rq   r   s	   &&&&&&&&,r   rr   ZLegacy690Lc.set_color  sX   
 f!8%!"""$vayPQ-2>1c-J.3OQ.LU` # b Z%!")""D-28Q-D-2>1c-J.3OQ.LU` # b W_""&)oWXZ]@^*5 # 7Z""DU?TUWZ=[*5 # 7 7v>??&&(#-f-r   c                s    \         V,          w  rEp\        W%V4      pV P                  P                  V R2V4       V P	                  4        \        R/ VB  R# )rx   r   Nr   )r   r   r   r   r   r   )r   rF   r=   r   rt   ru   rv   s   &&&,   r   r|   ZLegacy690Lc.set_fixed_speed  sO    8ATT&

G9E*D1""$#-f-r   c                rD   rE   r   )r   rF   r;   r   s   &&&,r   rw   ZLegacy690Lc.set_speed_profile  rI   r   )r   r%   rL   )rM   rN   rO   rP   rQ   r   r   r   r?   r   rA   rc   rR   rr   r|   rw   rS   rT   rU   rV   rX   r   r   r   M  s`     6 
@"EH M0.
 ?CT"3.B.% %r   r   c            	       sv   a a ] tR tRt oRtRRR/ 3RRR/ 3RRR	/ 3RR
R/ 3RRR/ 3RRR/ 3.tV 3R ltRtVtV ;t	# )
Hydro690Lci  z5Corsair-branded fifth generation Asetek 690LC cooler.i  i  zCorsair Hydro H80i GTi  zCorsair Hydro H100i GTXi  zCorsair Hydro H110i GTXi  zCorsair Hydro H80i v2i	  zCorsair Hydro H100i v2i
  zCorsair Hydro H115ic                sV   < VR8X  d   \        RV 24      h\        SV `  ! WV3/ VB  R# )rd   re   r   N)rl   r	   rr   )r   rF   rG   rm   r   r   s   &&&&,r   rr   ZHydro690Lc.set_color  s2    97v>??':6:r   r   )
rM   rN   rO   rP   rQ   r   rr   rS   rT   rU   rV   rX   r   r   r     si     ? 
0"5	2B7	2B7	0"5	126	.3H; ;r   r   c                  sb    V P                  R 4      '       d   \        P                  R4       R# R# )r\   z7device does not support non-volatile settings, skippingN)Zgetr   Zwarning)r   s   ,r   r   r     s#    zz.!!QR "r   )6rQ   ZloggingZusbZliquidctl.driver.usbr    Zliquidctl.errorr   Zliquidctl.keyvalr   Zliquidctl.utilr   Z	getLoggerrM   r   Z_CMD_RUNTIMEZ_CMD_PROFILEZ_CMD_OVERRIDEZ_CMD_PUMP_PWMr^   Z_CMD_READ_ONLY_RUNTIMErZ   Z_CMD_EXTERNAL_TEMPERATUREry   rs   r8   r:   rR   r{   rz   r(   r)   r&   r   r   r!   r   r   Z_USBXPRESS_GET_PART_NUMZ_UNKNOWN_OPEN_REQUESTZ_UNKNOWN_OPEN_VALUEZutilZCTRL_OUTZCTRL_TYPE_VENDORZCTRL_RECIPIENT_DEVICEr   r   rY   r}   r   r   r   ZAsetekDriverZLegacyAsetekDriverZCorsairAsetekDriverr   r   r   <module>r      s  $  
 * 0 +  


H
%	     mR%  
lAs#        
]As#
mR%      #      XX!:!::SXX=[=[[
r% r%jiz iV" Dc%* c%L;! ;&S     r   