Get a set of all alarms known to the Sonos system.

    Args:
        zone (`SoCo`, optional): a SoCo instance to query. If None, a random
            instance is used. Defaults to `None`.

    Returns:
        set: A set of `Alarm` instances

    Note:
        Any existing `Alarm` instance will have its attributes updated to those
        currently stored on the Sonos system.

def get_alarms(zone=None):
    """Get a set of all alarms known to the Sonos system.

    Args:
        zone (`SoCo`, optional): a SoCo instance to query. If None, a random
            instance is used. Defaults to `None`.

    Returns:
        set: A set of `Alarm` instances

    Note:
        Any existing `Alarm` instance will have its attributes updated to those
        currently stored on the Sonos system.
    """
    # Get a soco instance to query. It doesn't matter which.
    if zone is None:
        zone = discovery.any_soco()
    response = zone.alarmClock.ListAlarms()
    alarm_list = response['CurrentAlarmList']
    tree = XML.fromstring(alarm_list.encode('utf-8'))

    # An alarm list looks like this:
    # <Alarms>
    #     <Alarm ID="14" StartTime="07:00:00"
    #         Duration="02:00:00" Recurrence="DAILY" Enabled="1"
    #         RoomUUID="RINCON_000ZZZZZZ1400"
    #         ProgramURI="x-rincon-buzzer:0" ProgramMetaData=""
    #         PlayMode="SHUFFLE_NOREPEAT" Volume="25"
    #         IncludeLinkedZones="0"/>
    #     <Alarm ID="15" StartTime="07:00:00"
    #         Duration="02:00:00" Recurrence="DAILY" Enabled="1"
    #         RoomUUID="RINCON_000ZZZZZZ01400"
    #         ProgramURI="x-rincon-buzzer:0" ProgramMetaData=""
    #         PlayMode="SHUFFLE_NOREPEAT" Volume="25"
    #          IncludeLinkedZones="0"/>
    # </Alarms>

    # pylint: disable=protected-access
    alarms = tree.findall('Alarm')
    result = set()
    for alarm in alarms:
        values = alarm.attrib
        alarm_id = values['ID']
        # If an instance already exists for this ID, update and return it.
        # Otherwise, create a new one and populate its values
        if Alarm._all_alarms.get(alarm_id):
            instance = Alarm._all_alarms.get(alarm_id)
        else:
            instance = Alarm(None)
            instance._alarm_id = alarm_id
            Alarm._all_alarms[instance._alarm_id] = instance

        instance.start_time = datetime.strptime(
            values['StartTime'], "%H:%M:%S").time()  # NB StartTime, not
        # StartLocalTime, which is used by CreateAlarm
        instance.duration = None if values['Duration'] == '' else\
            datetime.strptime(values['Duration'], "%H:%M:%S").time()
        instance.recurrence = values['Recurrence']
        instance.enabled = values['Enabled'] == '1'
        instance.zone = next((z for z in zone.all_zones
                              if z.uid == values['RoomUUID']), None)
        # some alarms are not associated to zones -> filter these out
        if instance.zone is None:
            continue
        instance.program_uri = None if values['ProgramURI'] ==\
            "x-rincon-buzzer:0" else values['ProgramURI']
        instance.program_metadata = values['ProgramMetaData']
        instance.play_mode = values['PlayMode']
        instance.volume = values['Volume']
        instance.include_linked_zones = values['IncludeLinkedZones'] == '1'

        result.add(instance)
    return result