
    :j2                       d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	 ddl
mZ ddlmZmZmZ dd	lmZmZ d
dlmZ d
dlmZ d
dlmZmZmZmZmZ erd
dl
mZ  ej        e          Z dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ) G d de          Z* G d de          Z+ G d dej,                  Z- G d dej,                  Z. G d  d!eeee-          Z/ G d" d#          Z0 G d$ d%e          Z1dS )&z,
Controller to monitor audio group members.
    )annotationsN)TYPE_CHECKING	TypedDict)UUID   )BaseController)MediaControllerMediaStatusListenerMediaStatus)
CastStatusCastStatusListener   )MESSAGE_TYPE)CastMessage)CONNECTION_STATUS_CONNECTEDCONNECTION_STATUS_DISCONNECTEDCONNECTION_STATUS_LOSTConnectionStatusConnectionStatusListener)
Chromecastz$urn:x-cast:com.google.cast.multizoneCASTING_GROUPSDEVICE_ADDEDDEVICE_UPDATEDDEVICE_REMOVEDGET_CASTING_GROUPS
GET_STATUSMULTIZONE_STATUSPLAYBACK_SESSION_UPDATEDc                  (    e Zd ZU dZded<   ded<   dS )	GroupInfoz/Chromecast connection and listener for a group.r   
chromecastListenerlistenerN__name__
__module____qualname____doc____annotations__     X/home/user/adhan/venv/lib/python3.11/site-packages/pychromecast/controllers/multizone.pyr    r    +   s0         99r+   r    c                  (    e Zd ZU dZded<   ded<   dS )GroupMemberInfoz+Group memberships and listener for a group.zset[str]group_membershipszlist[MultiZoneManagerListener]	listenersNr$   r*   r+   r,   r.   r.   2   s0         55------r+   r.   c                  x    e Zd ZdZej        d
d            Zej        d
d            Zej        dd            Zd	S )MultiZoneControllerListenerz*Listener for receiving audio group events.
group_uuidstrreturnNonec                    dS z:The cast has been added to group identified by group_uuid.Nr*   selfr3   s     r,   multizone_member_addedz2MultiZoneControllerListener.multizone_member_added<         r+   c                    dS z>The cast has been removed from group identified by group_uuid.Nr*   r9   s     r,   multizone_member_removedz4MultiZoneControllerListener.multizone_member_removed@   r<   r+   c                    dS )z"Multizone status has been updated.Nr*   r:   s    r,   multizone_status_receivedz5MultiZoneControllerListener.multizone_status_receivedD   r<   r+   Nr3   r4   r5   r6   r5   r6   )	r%   r&   r'   r(   abcabstractmethodr;   r?   rB   r*   r+   r,   r2   r2   9   s        44I I I I 	M M M M 	1 1 1 1 1 1r+   r2   c                      e Zd ZdZej        dd            Zej        dd            Zej        dd
            Zej        dd            Z	dS )MultiZoneManagerListenerz<Listener for receiving audio group events for a cast device.r3   r4   r5   r6   c                    dS r8   r*   r9   s     r,   added_to_multizonez+MultiZoneManagerListener.added_to_multizoneL   r<   r+   c                    dS r>   r*   r9   s     r,   removed_from_multizonez/MultiZoneManagerListener.removed_from_multizoneP   r<   r+   media_statusr   c                    dS )zXThe group identified by group_uuid, of which the cast is a member, has new media status.Nr*   )r:   r3   rM   s      r,   multizone_new_media_statusz3MultiZoneManagerListener.multizone_new_media_statusT   r<   r+   cast_statusr   c                    dS )zRThe group identified by group_uuid, of which the cast is a member, has new status.Nr*   )r:   r3   rP   s      r,   multizone_new_cast_statusz2MultiZoneManagerListener.multizone_new_cast_statusZ   r<   r+   NrC   )r3   r4   rM   r   r5   r6   )r3   r4   rP   r   r5   r6   )
r%   r&   r'   r(   rE   rF   rJ   rL   rO   rR   r*   r+   r,   rH   rH   I   s        FFI I I I 	M M M M 	g g g g
 	a a a a a ar+   rH   c                  R    e Z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S )!r"   zCallback handler.
group_castr   castsdict[str, GroupMemberInfo]r5   r6   c                h   || _         |                    |            |j                            |            |                    |            t	          |j                  | _        | j                            |            t          |j                  | _	        |
                    | j                   dS )zInitialize the listener.N)_castsregister_status_listenermedia_controllerregister_connection_listenerMultizoneControlleruuid_mzregister_listenerr4   _group_uuidregister_handler)r:   rT   rU   s      r,   __init__zListener.__init__i   s     ++D111#<<TBBB//555&z77""4(((z//##DH-----r+   statusr   c                    | j         }| j        j        }|D ]@}||vrt          ||         d                   D ]}|                    | j        |           AdS )z%Handle reception of a new CastStatus.r0   N)rX   r^   memberslistrR   r`   r:   rc   rU   group_membersmember_uuidr#   s         r,   new_cast_statuszListener.new_cast_statusv   s    (( 	M 	MK%'' {!3K!@AA M M2243CVLLLLM	M 	Mr+   r   c                    | j         }| j        j        }|D ]@}||vrt          ||         d                   D ]}|                    | j        |           AdS )z&Handle reception of a new MediaStatus.r0   N)rX   r^   re   rf   rO   r`   rg   s         r,   new_media_statuszListener.new_media_status   s    (( 	N 	NK%'' {!3K!@AA N N33D4DfMMMMN	N 	Nr+   queue_item_idint
error_codec                    dS )zCalled when load media failed.Nr*   )r:   rm   ro   s      r,   load_media_failedzListener.load_media_failed   r<   r+   r   c                    |j         t          k    r| j                                         |j         t          t
          fv r| j                                         dS dS )z+Handle reception of a new ConnectionStatus.N)rc   r   r^   update_membersr   r   reset_members)r:   rc   s     r,   new_connection_statuszListener.new_connection_status   sd    =777H##%%%=*"
 
 
 H""$$$$$	
 
r+   r3   r4   c                    | j         }||vrg t                      d||<   ||         d                             | j                   t	          ||         d                   D ]}|                    | j                   dS )z Handle added audio group member.r0   r/   r/   r0   N)rX   setaddr`   rf   rJ   r:   r3   rU   r#   s       r,   r;   zListener.multizone_member_added   s    U"".0suu M ME*j-.2243CDDDU:.{;<< 	: 	:H''(89999	: 	:r+   c                    | j         }||vrg t                      d||<   ||         d                             | j                   t	          ||         d                   D ]}|                    | j                   dS )z"Handle removed audio group member.rw   r/   r0   N)rX   rx   discardr`   rf   rL   rz   s       r,   r?   z!Listener.multizone_member_removed   s    U"".0suu M ME*j-.66t7GHHHU:.{;<< 	> 	>H++D,<====	> 	>r+   c                    dS )z'Handle reception of audio group status.Nr*   rA   s    r,   rB   z"Listener.multizone_status_received   r<   r+   N)rT   r   rU   rV   r5   r6   )rc   r   r5   r6   )rc   r   r5   r6   )rm   rn   ro   rn   r5   r6   )rc   r   r5   r6   rC   rD   )r%   r&   r'   r(   rb   rj   rl   rq   ru   r;   r?   rB   r*   r+   r,   r"   r"   a   s         . . . .M M M MN N N N- - - -% % % %: : : :> > > >6 6 6 6 6 6r+   r"   c                  J    e Z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S )MultizoneManagerzManage audio groups.r5   r6   c                "    i | _         i | _        d S )N)rX   _groupsrA   s    r,   rb   zMultizoneManager.__init__   s     35-/r+   rT   r   c                j    |t          || j                  d| j        t          |j                  <   dS )zStart managing a group)r!   r#   N)r"   rX   r   r4   r]   )r:   rT   s     r,   add_multizonezMultizoneManager.add_multizone   s9     % T[99.
 .
S))***r+   r3   r   c                
   t          |          }| j                            |d          }||d         j                                         | j                                        D ]}|d                             |           dS )zStop managing a groupNr#   r/   )r4   r   popr^   rt   rX   valuesr|   )r:   r3   group_uuid_strgroupmembers        r,   remove_multizonez!MultizoneManager.remove_multizone   s    Z  66*!//111k((** 	@ 	@F&'//????	@ 	@r+   ri   r#   rH   c                    t          |          }|| j        vrg t                      d| j        |<   | j        |         d                             |           dS )aI  Register a listener for audio group changes of cast uuid.
        On update will call:
        listener.added_to_multizone(group_uuid)
            The cast has been added to group uuid
        listener.removed_from_multizone(group_uuid)
            The cast has been removed from group uuid
        listener.multizone_new_media_status(group_uuid, media_status)
            The group uuid, of which the cast is a member, has new status
        listener.multizone_new_cast_status(group_uuid, cast_status)
            The group uuid, of which the cast is a member, has new status
        rw   r0   N)r4   rX   rx   append)r:   ri   r#   member_uuid_strs       r,   r_   z"MultizoneManager.register_listener   s_     k**$+--9;RURWRW+X+XDK(O$[188BBBBBr+   c                l    | j         t          |                   d                             |           dS )z9Deregister listener for audio group changes of cast uuid.r0   N)rX   r4   remove)r:   ri   r#   s      r,   deregister_listenerz$MultizoneManager.deregister_listener   s2     	C$$%k299(CCCCCr+   	list[str]c                \    t          | j        t          |                   d                   S )zCReturn a list of audio groups in which cast member_uuid is a memberr/   )rf   rX   r4   )r:   ri   s     r,   get_multizone_membershipsz*MultizoneManager.get_multizone_memberships   s%    DKK 0 012EFGGGr+   r	   c                L    | j         t          |                   d         j        S )zGet mediacontroller of a groupr!   )r   r4   rZ   r9   s     r,   get_multizone_mediacontrollerz.MultizoneManager.get_multizone_mediacontroller   s    |C
OO,\:KKr+   NrD   )rT   r   r5   r6   )r3   r   r5   r6   )ri   r   r#   rH   r5   r6   )ri   r   r5   r   )r3   r   r5   r	   )r%   r&   r'   r(   rb   r   r   r_   r   r   r   r*   r+   r,   r   r      s        0 0 0 0
 
 
 
@ @ @ @C C C C&D D D DH H H HL L L L L Lr+   r   c                       e Zd ZdZd fdZdd	Zdd
ZddZedd            Z	ddZ
ddZddZd dZd fdZ xZS )!r\   z*Controller to monitor audio group members.r]   r   r5   r6   c                    i | _         g | _        t          |          | _        t	                                          t          d           d S )NT)target_platform)_members_status_listenersr4   _uuidsuperrb   MULTIZONE_NAMESPACE)r:   r]   	__class__s     r,   rb   zMultizoneController.__init__   sC    (*DFYY
,dCCCCCr+   r4   namec                    || j         vr^|| j         |<   t                              d| j        ||| j                    t	          | j                  D ]}|                    |           d S d S )Nz%(%s) Added member %s(%s), members: %s)r   _LOGGERdebugr   rf   r   r;   r:   r]   r   r#   s       r,   _add_memberzMultizoneController._add_member   s    t}$$"&DM$MM7
   !!788 6 6//5555 %$6 6r+   c                    | j                             |d          }t                              d| j        ||| j                    t          | j                  D ]}|                    |           d S )Nz	<Unknown>z'(%s) Removed member %s(%s), members: %s)r   r   r   r   r   rf   r   r?   r   s       r,   _remove_memberz"MultizoneController._remove_member   s    }  {335JM	
 	
 	
 T344 	4 	4H--d3333	4 	4r+   r#   r2   c                :    | j                             |           dS )zRegister a listener for audio group changes. On update will call:
        listener.multizone_member_added(uuid)
        listener.multizone_member_removed(uuid)
        listener.multizone_status_received()
        N)r   r   )r:   r#   s     r,   r_   z%MultizoneController.register_listener  s!     	%%h/////r+   r   c                N    t          | j                                                  S )z%Return a list of audio group members.)rf   r   keysrA   s    r,   re   zMultizoneController.members  s      DM&&(()))r+   c                ^    t          | j                  D ]}|                     |           dS )zReset audio group members.N)rf   r   r   )r:   r]   s     r,   rt   z!MultizoneController.reset_members  s<    '' 	& 	&D%%%%	& 	&r+   c                H    |                      t          t          i           dS )zUpdate audio group members.N)send_messager   TYPE_GET_STATUSrA   s    r,   rs   z"MultizoneController.update_members  s!    <9:::::r+   c                H    |                      t          t          i           dS )z Send GET_CASTING_GROUPS message.N)r   r   TYPE_GET_CASTING_GROUPSrA   s    r,   get_casting_groupsz&MultizoneController.get_casting_groups!  s"    <)@ABBBBBr+   _messager   datadictboolc                   |t                    t          k    r4|d         d         }|d         d         }|                     ||           dS |t                    t          k    r|d         }|                     |           dS |t                    t
          k    r4|d         d         }|d         d         }|                     ||           dS |t                    t          k    rN|d         d         }d |D             }t          t          | j	        
                                          t          |
                                          z
            }t          t          |
                                          t          | j	        
                                          z
            }t                              d| j        ||           |D ]}|                     |           |D ]}|                     |||                    t          | j                  D ]}|                                 dS |t                    t           k    rdS |t                    t"          k    rdS d	S )
z,Called when a multizone message is received.devicedeviceIdr   Trc   devicesc                ,    i | ]}|d          |d         S )r   r   r*   ).0r   s     r,   
<dictcomp>z7MultizoneController.receive_message.<locals>.<dictcomp><  s#    PPPfvj)6&>PPPr+   z*(%s) Added members %s, Removed members: %sF)r   TYPE_DEVICE_ADDEDr   TYPE_DEVICE_REMOVEDr   TYPE_DEVICE_UPDATEDTYPE_MULTIZONE_STATUSrf   rx   r   r   r   r   r   r   rB   TYPE_SESSION_UPDATEDTYPE_CASTING_GROUPS)	r:   r   r   r]   r   re   removed_membersadded_membersr#   s	            r,   receive_messagez#MultizoneController.receive_message%  sG    !222>*-D>&)DT4(((4!444
#D%%%4!444>*-D>&)DT4(((4!6668nY/GPPPPPG"3t}'9'9';';#<#<s7<<>>?R?R#RSSO W\\^^!4!4s4=;M;M;O;O7P7P!PQQMMM<
	   ( * *##D))))% 6 6  wt}5555 !788 5 52244444!5554!4444ur+   c                V    t                                                       g | _        dS )z$Called when controller is destroyed.N)r   	tear_downr   )r:   r   s    r,   r   zMultizoneController.tear_downZ  s'    !#r+   )r]   r   r5   r6   )r]   r4   r   r4   r5   r6   )r]   r4   r5   r6   )r#   r2   r5   r6   )r5   r   rD   )r   r   r   r   r5   r   )r%   r&   r'   r(   rb   r   r   r_   propertyre   rt   rs   r   r   r   __classcell__)r   s   @r,   r\   r\      s       44D D D D D D6 6 6 6
4 
4 
4 
40 0 0 0 * * * X*& & & &
; ; ; ;C C C C3 3 3 3j$ $ $ $ $ $ $ $ $ $r+   r\   )2r(   
__future__r   rE   loggingtypingr   r   r]   r    r   mediar	   r
   r   receiverr   r   constr   generated.cast_channel_pb2r   socket_clientr   r   r   r   r   r   	getLoggerr%   r   r   r   r   r   r   r   r   r   r   r    r.   ABCr2   rH   r"   r   r\   r*   r+   r,   <module>r      s    # " " " " " 



  + + + + + + + +             D D D D D D D D D D 4 4 4 4 4 4 4 4             5 4 4 4 4 4               
'
H
%
%< & " & & . * 1     	   . . . . .i . . .1 1 1 1 1#' 1 1 1 a a a a asw a a a0I6 I6 I6 I6 I6	I6 I6 I6X9L 9L 9L 9L 9L 9L 9L 9Lxu$ u$ u$ u$ u$. u$ u$ u$ u$ u$r+   