"""Wireless API endpoints.

This file is automatically @generated from the Meraki API specification.
Do not edit this file manually.

"""

from __future__ import annotations

import urllib.parse
from typing import TYPE_CHECKING, Any, Literal

from meraki_client.schemas import (
    AssignNetworkWirelessEthernetPortsProfilesResponse,
    CreateDeviceWirelessZigbeeEnrollmentResponse,
    CreateNetworkWirelessAirMarshalRuleMatch,
    CreateNetworkWirelessAirMarshalRuleResponse,
    CreateNetworkWirelessEthernetPortsProfilePortsItem,
    CreateNetworkWirelessEthernetPortsProfileResponse,
    CreateNetworkWirelessEthernetPortsProfileUsbPortsItem,
    CreateNetworkWirelessRfProfileApBandSettings,
    CreateNetworkWirelessRfProfileFiveGhzSettings,
    CreateNetworkWirelessRfProfileFlexRadios,
    CreateNetworkWirelessRfProfilePerSsidSettings,
    CreateNetworkWirelessRfProfileResponse,
    CreateNetworkWirelessRfProfileSixGhzSettings,
    CreateNetworkWirelessRfProfileTransmission,
    CreateNetworkWirelessRfProfileTwoFourGhzSettings,
    CreateNetworkWirelessSsidIdentityPskResponse,
    CreateOrganizationWirelessDevicesRadsecCertificatesAuthorityResponse,
    CreateOrganizationWirelessLocationScanningReceiverNetwork,
    CreateOrganizationWirelessLocationScanningReceiverRadio,
    CreateOrganizationWirelessLocationScanningReceiverResponse,
    CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryClient,
    CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryNetwork,
    CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryResponse,
    CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntrySsid,
    CreateOrganizationWirelessZigbeeDisenrollmentResponse,
    DictResponse,
    GetDeviceWirelessBluetoothSettingsResponse,
    GetDeviceWirelessConnectionStatsResponse,
    GetDeviceWirelessElectronicShelfLabelResponse,
    GetDeviceWirelessRadioSettingsResponse,
    GetDeviceWirelessStatusResponse,
    GetDeviceWirelessZigbeeEnrollmentResponse,
    GetNetworkWirelessAirMarshalResponseItem,
    GetNetworkWirelessBillingResponse,
    GetNetworkWirelessBluetoothSettingsResponse,
    GetNetworkWirelessChannelUtilizationHistoryResponseItem,
    GetNetworkWirelessClientConnectionStatsResponse,
    GetNetworkWirelessClientConnectivityEventsResponseItem,
    GetNetworkWirelessClientCountHistoryResponseItem,
    GetNetworkWirelessClientLatencyHistoryResponseItem,
    GetNetworkWirelessClientsConnectionStatsResponse,
    GetNetworkWirelessClientsLatencyStatsResponse,
    GetNetworkWirelessConnectionStatsResponse,
    GetNetworkWirelessDataRateHistoryResponseItem,
    GetNetworkWirelessDevicesConnectionStatsResponseItem,
    GetNetworkWirelessDevicesLatencyStatsResponse,
    GetNetworkWirelessElectronicShelfLabelConfiguredDevicesResponseItem,
    GetNetworkWirelessElectronicShelfLabelResponse,
    GetNetworkWirelessEthernetPortsProfileResponse,
    GetNetworkWirelessEthernetPortsProfilesResponseItem,
    GetNetworkWirelessFailedConnectionsResponseItem,
    GetNetworkWirelessLatencyHistoryResponseItem,
    GetNetworkWirelessMeshStatusesResponseItem,
    GetNetworkWirelessRfProfileResponse,
    GetNetworkWirelessRfProfilesResponse,
    GetNetworkWirelessSettingsResponse,
    GetNetworkWirelessSignalQualityHistoryResponseItem,
    GetNetworkWirelessSsidBonjourForwardingResponse,
    GetNetworkWirelessSsidEapOverrideResponse,
    GetNetworkWirelessSsidFirewallL3FirewallRulesResponse,
    GetNetworkWirelessSsidFirewallL7FirewallRulesResponse,
    GetNetworkWirelessSsidHotspot20Response,
    GetNetworkWirelessSsidIdentityPskResponse,
    GetNetworkWirelessSsidIdentityPsksResponseItem,
    GetNetworkWirelessSsidResponse,
    GetNetworkWirelessSsidSchedulesResponse,
    GetNetworkWirelessSsidSplashSettingsResponse,
    GetNetworkWirelessSsidsResponseItem,
    GetNetworkWirelessSsidTrafficShapingRulesResponse,
    GetNetworkWirelessUsageHistoryResponseItem,
    GetOrganizationWirelessAirMarshalRulesResponseItemsItem,
    GetOrganizationWirelessAirMarshalSettingsByNetworkResponseItemsItem,
    GetOrganizationWirelessClientsOverviewByDeviceResponseItemsItem,
    GetOrganizationWirelessDevicesChannelUtilizationByDeviceResponseItem,
    GetOrganizationWirelessDevicesChannelUtilizationByNetworkResponseItem,
    GetOrganizationWirelessDevicesChannelUtilizationHistoryByDeviceByIntervalResponseItem,
    GetOrganizationWirelessDevicesChannelUtilizationHistoryByNetworkByIntervalResponseItem,
    GetOrganizationWirelessDevicesEthernetStatusesResponseItem,
    GetOrganizationWirelessDevicesPacketLossByClientResponseItem,
    GetOrganizationWirelessDevicesPacketLossByDeviceResponseItem,
    GetOrganizationWirelessDevicesPacketLossByNetworkResponseItem,
    GetOrganizationWirelessDevicesPowerModeHistoryResponseItemsItem,
    GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsDeltasResponseItemsItem,
    GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsResponseItemsItem,
    GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesResponseItem,
    GetOrganizationWirelessDevicesSystemCpuLoadHistoryResponseItemsItem,
    GetOrganizationWirelessDevicesWirelessControllersByDeviceResponseItemsItem,
    GetOrganizationWirelessLocationScanningByNetworkResponseItemsItem,
    GetOrganizationWirelessLocationScanningReceiversResponseItemsItem,
    GetOrganizationWirelessMqttSettingsResponseItemsItem,
    GetOrganizationWirelessRadioRrmByNetworkResponseItemsItem,
    GetOrganizationWirelessRfProfilesAssignmentsByDeviceResponseItem,
    GetOrganizationWirelessSsidsFirewallIsolationAllowlistEntriesResponseItemsItem,
    GetOrganizationWirelessSsidsOpenRoamingByNetworkResponseItemsItem,
    GetOrganizationWirelessSsidsStatusesByDeviceResponseItemsItem,
    GetOrganizationWirelessZigbeeByNetworkResponseItem,
    GetOrganizationWirelessZigbeeDevicesResponseItem,
    GetOrganizationWirelessZigbeeDisenrollmentResponse,
    GetOrganizationWirelessZigbeeDoorLocksResponseItem,
    RecalculateOrganizationWirelessRadioAutoRfChannelsResponse,
    SetNetworkWirelessEthernetPortsProfilesDefaultResponse,
    UpdateDeviceWirelessAlternateManagementInterfaceIpv6AddressesItem,
    UpdateDeviceWirelessAlternateManagementInterfaceIpv6Response,
    UpdateDeviceWirelessBluetoothSettingsResponse,
    UpdateDeviceWirelessElectronicShelfLabelResponse,
    UpdateDeviceWirelessRadioSettingsFiveGhzSettings,
    UpdateDeviceWirelessRadioSettingsResponse,
    UpdateDeviceWirelessRadioSettingsTwoFourGhzSettings,
    UpdateNetworkWirelessAirMarshalRuleMatch,
    UpdateNetworkWirelessAirMarshalRuleResponse,
    UpdateNetworkWirelessAirMarshalSettingsResponse,
    UpdateNetworkWirelessAlternateManagementInterfaceAccessPointsItem,
    UpdateNetworkWirelessBillingPlansItem,
    UpdateNetworkWirelessBillingResponse,
    UpdateNetworkWirelessBluetoothSettingsResponse,
    UpdateNetworkWirelessElectronicShelfLabelResponse,
    UpdateNetworkWirelessEthernetPortsProfilePortsItem,
    UpdateNetworkWirelessEthernetPortsProfileResponse,
    UpdateNetworkWirelessEthernetPortsProfileUsbPortsItem,
    UpdateNetworkWirelessLocationScanningApi,
    UpdateNetworkWirelessLocationScanningResponse,
    UpdateNetworkWirelessRadioRrmAi,
    UpdateNetworkWirelessRadioRrmBusyHour,
    UpdateNetworkWirelessRadioRrmChannel,
    UpdateNetworkWirelessRadioRrmFra,
    UpdateNetworkWirelessRadioRrmResponse,
    UpdateNetworkWirelessRfProfileApBandSettings,
    UpdateNetworkWirelessRfProfileFiveGhzSettings,
    UpdateNetworkWirelessRfProfileFlexRadios,
    UpdateNetworkWirelessRfProfilePerSsidSettings,
    UpdateNetworkWirelessRfProfileResponse,
    UpdateNetworkWirelessRfProfileSixGhzSettings,
    UpdateNetworkWirelessRfProfileTransmission,
    UpdateNetworkWirelessRfProfileTwoFourGhzSettings,
    UpdateNetworkWirelessSettingsMulticastToUnicastConversion,
    UpdateNetworkWirelessSettingsNamedVlans,
    UpdateNetworkWirelessSettingsResponse,
    UpdateNetworkWirelessSsidActiveDirectory,
    UpdateNetworkWirelessSsidApTagsAndVlanIdsItem,
    UpdateNetworkWirelessSsidBonjourForwardingException,
    UpdateNetworkWirelessSsidBonjourForwardingResponse,
    UpdateNetworkWirelessSsidBonjourForwardingRulesItem,
    UpdateNetworkWirelessSsidDeviceTypeGroupPoliciesDeviceTypePoliciesItem,
    UpdateNetworkWirelessSsidDnsRewrite,
    UpdateNetworkWirelessSsidDot11r,
    UpdateNetworkWirelessSsidDot11w,
    UpdateNetworkWirelessSsidEapOverrideEapolKey,
    UpdateNetworkWirelessSsidEapOverrideIdentity,
    UpdateNetworkWirelessSsidEapOverrideResponse,
    UpdateNetworkWirelessSsidFirewallL3FirewallRulesResponse,
    UpdateNetworkWirelessSsidFirewallL3FirewallRulesRulesItem,
    UpdateNetworkWirelessSsidFirewallL7FirewallRulesResponse,
    UpdateNetworkWirelessSsidFirewallL7FirewallRulesRulesItem,
    UpdateNetworkWirelessSsidGre,
    UpdateNetworkWirelessSsidHotspot20MccMncsItem,
    UpdateNetworkWirelessSsidHotspot20NaiRealmsItem,
    UpdateNetworkWirelessSsidHotspot20Operator,
    UpdateNetworkWirelessSsidHotspot20Response,
    UpdateNetworkWirelessSsidHotspot20Venue,
    UpdateNetworkWirelessSsidIdentityPskResponse,
    UpdateNetworkWirelessSsidLdap,
    UpdateNetworkWirelessSsidLocalAuthFallback,
    UpdateNetworkWirelessSsidLocalRadius,
    UpdateNetworkWirelessSsidNamedVlans,
    UpdateNetworkWirelessSsidOauth,
    UpdateNetworkWirelessSsidOpenRoamingResponse,
    UpdateNetworkWirelessSsidRadiusAccountingServersItem,
    UpdateNetworkWirelessSsidRadiusRadsec,
    UpdateNetworkWirelessSsidRadiusServersItem,
    UpdateNetworkWirelessSsidResponse,
    UpdateNetworkWirelessSsidSchedulesRangesInSecondsItem,
    UpdateNetworkWirelessSsidSchedulesRangesItem,
    UpdateNetworkWirelessSsidSchedulesResponse,
    UpdateNetworkWirelessSsidSpeedBurst,
    UpdateNetworkWirelessSsidSplashSettingsBilling,
    UpdateNetworkWirelessSsidSplashSettingsGuestSponsorship,
    UpdateNetworkWirelessSsidSplashSettingsResponse,
    UpdateNetworkWirelessSsidSplashSettingsSelfRegistration,
    UpdateNetworkWirelessSsidSplashSettingsSentryEnrollment,
    UpdateNetworkWirelessSsidSplashSettingsSplashImage,
    UpdateNetworkWirelessSsidSplashSettingsSplashLogo,
    UpdateNetworkWirelessSsidSplashSettingsSplashPrepaidFront,
    UpdateNetworkWirelessSsidTrafficShapingRulesResponse,
    UpdateNetworkWirelessSsidTrafficShapingRulesRulesItem,
    UpdateNetworkWirelessSsidVpnConcentrator,
    UpdateNetworkWirelessSsidVpnFailover,
    UpdateNetworkWirelessSsidVpnSplitTunnel,
    UpdateNetworkWirelessZigbeeDefaults,
    UpdateNetworkWirelessZigbeeIotController,
    UpdateNetworkWirelessZigbeeLockManagement,
    UpdateNetworkWirelessZigbeeResponse,
    UpdateOrganizationWirelessDevicesRadsecCertificatesAuthoritiesResponse,
    UpdateOrganizationWirelessLocationScanningReceiverRadio,
    UpdateOrganizationWirelessLocationScanningReceiverResponse,
    UpdateOrganizationWirelessMqttSettingsBle,
    UpdateOrganizationWirelessMqttSettingsMqtt,
    UpdateOrganizationWirelessMqttSettingsNetwork,
    UpdateOrganizationWirelessMqttSettingsResponse,
    UpdateOrganizationWirelessMqttSettingsWifi,
    UpdateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryClient,
    UpdateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryResponse,
    UpdateOrganizationWirelessZigbeeDeviceResponse,
    UpdateOrganizationWirelessZigbeeDoorLockResponse,
)
from meraki_client.types import (
    CreateNetworkWirelessAirMarshalRuleType,
    CreateNetworkWirelessRfProfileBandSelectionType,
    CreateNetworkWirelessRfProfileMinBitrateType,
    GetDeviceWirelessConnectionStatsBand,
    GetDeviceWirelessConnectionStatsSsid,
    GetDeviceWirelessLatencyStatsBand,
    GetDeviceWirelessLatencyStatsSsid,
    GetNetworkWirelessChannelUtilizationHistoryBand,
    GetNetworkWirelessClientConnectionStatsBand,
    GetNetworkWirelessClientConnectionStatsSsid,
    GetNetworkWirelessClientConnectivityEventsBand,
    GetNetworkWirelessClientConnectivityEventsIncludedSeverities,
    GetNetworkWirelessClientConnectivityEventsSortOrder,
    GetNetworkWirelessClientConnectivityEventsSsidNumber,
    GetNetworkWirelessClientConnectivityEventsTypes,
    GetNetworkWirelessClientCountHistoryBand,
    GetNetworkWirelessClientLatencyStatsBand,
    GetNetworkWirelessClientLatencyStatsSsid,
    GetNetworkWirelessClientsConnectionStatsBand,
    GetNetworkWirelessClientsConnectionStatsSsid,
    GetNetworkWirelessClientsLatencyStatsBand,
    GetNetworkWirelessClientsLatencyStatsSsid,
    GetNetworkWirelessConnectionStatsBand,
    GetNetworkWirelessConnectionStatsSsid,
    GetNetworkWirelessDataRateHistoryBand,
    GetNetworkWirelessDevicesConnectionStatsBand,
    GetNetworkWirelessDevicesConnectionStatsSsid,
    GetNetworkWirelessDevicesLatencyStatsBand,
    GetNetworkWirelessDevicesLatencyStatsSsid,
    GetNetworkWirelessFailedConnectionsBand,
    GetNetworkWirelessFailedConnectionsSsid,
    GetNetworkWirelessLatencyHistoryAccessCategory,
    GetNetworkWirelessLatencyHistoryBand,
    GetNetworkWirelessLatencyStatsBand,
    GetNetworkWirelessLatencyStatsSsid,
    GetNetworkWirelessSignalQualityHistoryBand,
    GetNetworkWirelessUsageHistoryBand,
    GetOrganizationWirelessRadioRrmByNetworkSortOrder,
    GetOrganizationWirelessRfProfilesAssignmentsByDeviceProductTypes,
    GetOrganizationWirelessSsidsFirewallIsolationAllowlistEntriesSsids,
    UpdateNetworkWirelessAirMarshalRuleType,
    UpdateNetworkWirelessAirMarshalSettingsDefaultPolicy,
    UpdateNetworkWirelessAlternateManagementInterfaceProtocols,
    UpdateNetworkWirelessBluetoothSettingsMajorMinorAssignmentMode,
    UpdateNetworkWirelessElectronicShelfLabelMode,
    UpdateNetworkWirelessRfProfileBandSelectionType,
    UpdateNetworkWirelessRfProfileMinBitrateType,
    UpdateNetworkWirelessSettingsUpgradeStrategy,
    UpdateNetworkWirelessSsidAuthMode,
    UpdateNetworkWirelessSsidEncryptionMode,
    UpdateNetworkWirelessSsidEnterpriseAdminAccess,
    UpdateNetworkWirelessSsidHotspot20NetworkAccessType,
    UpdateNetworkWirelessSsidRadiusAttributeForGroupPolicies,
    UpdateNetworkWirelessSsidRadiusFailoverPolicy,
    UpdateNetworkWirelessSsidRadiusLoadBalancingPolicy,
    UpdateNetworkWirelessSsidSplashPage,
    UpdateNetworkWirelessSsidSplashSettingsControllerDisconnectionBehavior,
    UpdateNetworkWirelessSsidSplashSettingsSplashTimeout,
    UpdateNetworkWirelessSsidWpaEncryptionMode,
)

if TYPE_CHECKING:
    from meraki_client.aio._session import AsyncPaginatedResponse, Session


class Wireless:
    """Wireless class."""

    def __init__(self, session: Session) -> None:
        self._session = session

    async def update_device_wireless_alternate_management_interface_ipv6(
        self,
        serial: str,
        *,
        addresses: list[UpdateDeviceWirelessAlternateManagementInterfaceIpv6AddressesItem]
        | None = None,
    ) -> UpdateDeviceWirelessAlternateManagementInterfaceIpv6Response:
        """Update alternate management interface IPv6 address.

        [API documentation: updateDeviceWirelessAlternateManagementInterfaceIpv6](https://developer.cisco.com/meraki/api-v1/#!update-device-wireless-alternate-management-interface-ipv-6)

        Args:
            serial: Serial.
            addresses: configured alternate management interface addresses.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "addresses": [
                {
                  "protocol": "ipv6",
                  "assignmentMode": "static",
                  "address": "2001:db8:3c4d:15::1",
                  "gateway": "fe80:db8:c15:c0:d0c::10ca:1d02",
                  "prefix": "2001:db8:3c4d:15::/64",
                  "nameservers": {
                    "addresses": [
                      "2001:db8:3c4d:15::1",
                      "2001:db8:3c4d:15::1"
                    ]
                  }
                }
              ]
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/alternateManagementInterface/ipv6"

        payload: dict[str, Any] = {}
        if addresses is not None:
            payload["addresses"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in addresses
            ]

        return await self._session.put(
            scope="wireless",
            operation_id="updateDeviceWirelessAlternateManagementInterfaceIpv6",
            path=path,
            json=payload,
            response_schema=UpdateDeviceWirelessAlternateManagementInterfaceIpv6Response,
        )

    async def get_device_wireless_bluetooth_settings(
        self, serial: str
    ) -> GetDeviceWirelessBluetoothSettingsResponse:
        """Return the bluetooth settings for a wireless device.

        [API documentation: getDeviceWirelessBluetoothSettings](https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-bluetooth-settings)

        Args:
            serial: Serial.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "uuid": "00000000-0000-0000-000-000000000000",
              "major": 13,
              "minor": 125
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/bluetooth/settings"

        return await self._session.get(
            scope="wireless",
            operation_id="getDeviceWirelessBluetoothSettings",
            path=path,
            response_schema=GetDeviceWirelessBluetoothSettingsResponse,
        )

    async def update_device_wireless_bluetooth_settings(
        self,
        serial: str,
        *,
        uuid: str | None = None,
        major: int | None = None,
        minor: int | None = None,
    ) -> UpdateDeviceWirelessBluetoothSettingsResponse:
        """Update the bluetooth settings for a wireless device.

        [API documentation: updateDeviceWirelessBluetoothSettings](https://developer.cisco.com/meraki/api-v1/#!update-device-wireless-bluetooth-settings)

        Args:
            serial: Serial.
            uuid: Desired UUID of the beacon. If the value is set to null it will reset to
                Dashboard's automatically generated value.
            major: Desired major value of the beacon. If the value is set to null it will reset to
                Dashboard's automatically generated value.
            minor: Desired minor value of the beacon. If the value is set to null it will reset to
                Dashboard's automatically generated value.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "uuid": "00000000-0000-0000-000-000000000000",
              "major": 13,
              "minor": 125
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/bluetooth/settings"

        payload: dict[str, Any] = {}
        if uuid is not None:
            payload["uuid"] = uuid
        if major is not None:
            payload["major"] = major
        if minor is not None:
            payload["minor"] = minor

        return await self._session.put(
            scope="wireless",
            operation_id="updateDeviceWirelessBluetoothSettings",
            path=path,
            json=payload,
            response_schema=UpdateDeviceWirelessBluetoothSettingsResponse,
        )

    async def get_device_wireless_connection_stats(
        self,
        serial: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetDeviceWirelessConnectionStatsBand | None = None,
        ssid: GetDeviceWirelessConnectionStatsSsid | None = None,
        ap_tag: str | None = None,
    ) -> GetDeviceWirelessConnectionStatsResponse:
        """Aggregated connectivity info for a given AP on this network.

        [API documentation: getDeviceWirelessConnectionStats](https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-connection-stats)

        Args:
            serial: Serial.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "serial": "Q234-ABCD-5678",
              "connectionStats": {
                "assoc": 0,
                "auth": 1,
                "dhcp": 0,
                "dns": 0,
                "success": 43
              }
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/connectionStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag

        return await self._session.get(
            scope="wireless",
            operation_id="getDeviceWirelessConnectionStats",
            path=path,
            params=params,
            response_schema=GetDeviceWirelessConnectionStatsResponse,
        )

    async def get_device_wireless_electronic_shelf_label(
        self, serial: str
    ) -> GetDeviceWirelessElectronicShelfLabelResponse:
        """Return the ESL settings of a device.

        [API documentation: getDeviceWirelessElectronicShelfLabel](https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-electronic-shelf-label)

        Args:
            serial: Serial.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "apEslId": 16777216,
              "serial": "Q234-ABCD-5678",
              "channel": "1",
              "enabled": true,
              "networkId": "N_24329156",
              "hostname": "localhost:700",
              "provider": "imagotag"
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/electronicShelfLabel"

        return await self._session.get(
            scope="wireless",
            operation_id="getDeviceWirelessElectronicShelfLabel",
            path=path,
            response_schema=GetDeviceWirelessElectronicShelfLabelResponse,
        )

    async def update_device_wireless_electronic_shelf_label(
        self, serial: str, *, channel: str | None = None, enabled: bool | None = None
    ) -> UpdateDeviceWirelessElectronicShelfLabelResponse:
        """Update the ESL settings of a device.

        [API documentation: updateDeviceWirelessElectronicShelfLabel](https://developer.cisco.com/meraki/api-v1/#!update-device-wireless-electronic-shelf-label)

        Args:
            serial: Serial.
            channel: Desired ESL channel for the device, or 'Auto' (case insensitive) to use the
                recommended channel.
            enabled: Turn ESL features on and off for this device.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "apEslId": 16777216,
              "serial": "Q234-ABCD-5678",
              "channel": "1",
              "enabled": true,
              "networkId": "N_24329156",
              "hostname": "localhost:700",
              "provider": "imagotag"
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/electronicShelfLabel"

        payload: dict[str, Any] = {}
        if channel is not None:
            payload["channel"] = channel
        if enabled is not None:
            payload["enabled"] = enabled

        return await self._session.put(
            scope="wireless",
            operation_id="updateDeviceWirelessElectronicShelfLabel",
            path=path,
            json=payload,
            response_schema=UpdateDeviceWirelessElectronicShelfLabelResponse,
        )

    async def get_device_wireless_latency_stats(
        self,
        serial: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetDeviceWirelessLatencyStatsBand | None = None,
        ssid: GetDeviceWirelessLatencyStatsSsid | None = None,
        ap_tag: str | None = None,
        vlan: int | None = None,
        fields: str | None = None,
    ) -> DictResponse:
        """Aggregated latency info for a given AP on this network.

        [API documentation: getDeviceWirelessLatencyStats](https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-latency-stats)

        Args:
            serial: Serial.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.
            vlan: Filter results by VLAN.
            fields: Partial selection: If present, this call will return only the selected fields of
                ["rawDistribution", "avg"]. All fields will be returned by default.
                Selected fields must be entered as a comma separated string.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "serial": "Q2JC-2MJM-FHRD",
              "latencyStats": {
                "backgroundTraffic": {
                  "rawDistribution": {
                    "0": 1234,
                    "1": 2345,
                    "2": 3456,
                    "4": 4567,
                    "8": 5678,
                    "16": 6789,
                    "32": 7890,
                    "64": 8901,
                    "128": 9012,
                    "256": 83,
                    "512": 1234,
                    "1024": 2345,
                    "2048": 9999
                  },
                  "avg": 606.52
                },
                "bestEffortTraffic": "same shape as backgroundTraffic",
                "videoTraffic": "same shape as backgroundTraffic",
                "voiceTraffic": "same shape as backgroundTraffic"
              }
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/latencyStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if vlan is not None:
            params["vlan"] = vlan
        if fields is not None:
            params["fields"] = fields

        return await self._session.get(
            scope="wireless",
            operation_id="getDeviceWirelessLatencyStats",
            path=path,
            params=params,
            response_schema=DictResponse,
        )

    async def get_device_wireless_radio_settings(
        self, serial: str
    ) -> GetDeviceWirelessRadioSettingsResponse:
        """Return the manually configured radio settings overrides of a device, which take precedence over RF profiles.

        [API documentation: getDeviceWirelessRadioSettings](https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-radio-settings)

        Args:
            serial: Serial.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "serial": "Q234-ABCD-5678",
              "rfProfileId": "1234",
              "twoFourGhzSettings": {
                "channel": 11,
                "targetPower": 21
              },
              "fiveGhzSettings": {
                "channel": 149,
                "channelWidth": 20,
                "targetPower": 15
              }
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/radio/settings"

        return await self._session.get(
            scope="wireless",
            operation_id="getDeviceWirelessRadioSettings",
            path=path,
            response_schema=GetDeviceWirelessRadioSettingsResponse,
        )

    async def update_device_wireless_radio_settings(
        self,
        serial: str,
        *,
        rf_profile_id: str | None = None,
        two_four_ghz_settings: UpdateDeviceWirelessRadioSettingsTwoFourGhzSettings | None = None,
        five_ghz_settings: UpdateDeviceWirelessRadioSettingsFiveGhzSettings | None = None,
    ) -> UpdateDeviceWirelessRadioSettingsResponse:
        """Update the radio settings overrides of a device, which take precedence over RF profiles.

        [API documentation: updateDeviceWirelessRadioSettings](https://developer.cisco.com/meraki/api-v1/#!update-device-wireless-radio-settings)

        Args:
            serial: Serial.
            rf_profile_id: The ID of an RF profile to assign to the device. If the value of this
                parameter is null, the appropriate basic RF profile (indoor or outdoor)
                will be assigned to the device. Assigning an RF profile will clear ALL
                manually configured overrides on the device (channel width, channel,
                power).
            two_four_ghz_settings: Manual radio settings for 2.4 GHz.
            five_ghz_settings: Manual radio settings for 5 GHz.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "serial": "Q234-ABCD-5678",
              "rfProfileId": "1234",
              "twoFourGhzSettings": {
                "channel": 11,
                "targetPower": 21
              },
              "fiveGhzSettings": {
                "channel": 149,
                "channelWidth": 20,
                "targetPower": 15
              }
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/radio/settings"

        payload: dict[str, Any] = {}
        if rf_profile_id is not None:
            payload["rfProfileId"] = rf_profile_id
        if two_four_ghz_settings is not None:
            payload["twoFourGhzSettings"] = two_four_ghz_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if five_ghz_settings is not None:
            payload["fiveGhzSettings"] = five_ghz_settings.model_dump(
                by_alias=True, exclude_none=True
            )

        return await self._session.put(
            scope="wireless",
            operation_id="updateDeviceWirelessRadioSettings",
            path=path,
            json=payload,
            response_schema=UpdateDeviceWirelessRadioSettingsResponse,
        )

    async def get_device_wireless_status(self, serial: str) -> GetDeviceWirelessStatusResponse:
        """Return the SSID statuses of an access point.

        [API documentation: getDeviceWirelessStatus](https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-status)

        Args:
            serial: Serial.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "basicServiceSets": [
                {
                  "ssidName": "My SSID",
                  "ssidNumber": 0,
                  "enabled": true,
                  "band": "2.4 GHz",
                  "bssid": "8A:15:04:00:00:00",
                  "channel": 11,
                  "channelWidth": "20 MHz",
                  "power": "18 dBm",
                  "visible": true,
                  "broadcasting": true
                }
              ]
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/status"

        return await self._session.get(
            scope="wireless",
            operation_id="getDeviceWirelessStatus",
            path=path,
            response_schema=GetDeviceWirelessStatusResponse,
        )

    async def create_device_wireless_zigbee_enrollment(
        self, serial: str
    ) -> CreateDeviceWirelessZigbeeEnrollmentResponse:
        """Enqueue a job to start enrolling door locks on zigbee configured wireless devices.

        [API documentation: createDeviceWirelessZigbeeEnrollment](https://developer.cisco.com/meraki/api-v1/#!create-device-wireless-zigbee-enrollment)

        Args:
            serial: Serial.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enrollmentId": "1234",
              "url": "/devices/SERIAL/wireless/zigbee/enrollments/1234",
              "request": {
                "serial": "Q234-ABCD-5678"
              },
              "status": "complete"
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/devices/{serial}/wireless/zigbee/enrollments"

        return await self._session.post(
            scope="wireless",
            operation_id="createDeviceWirelessZigbeeEnrollment",
            path=path,
            response_schema=CreateDeviceWirelessZigbeeEnrollmentResponse,
        )

    async def get_device_wireless_zigbee_enrollment(
        self, *, serial: str, enrollment_id: str
    ) -> GetDeviceWirelessZigbeeEnrollmentResponse:
        """Return an enrollment.

        [API documentation: getDeviceWirelessZigbeeEnrollment](https://developer.cisco.com/meraki/api-v1/#!get-device-wireless-zigbee-enrollment)

        Args:
            serial: Serial.
            enrollment_id: Enrollment ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enrollmentId": "1234",
              "url": "/devices/SERIAL/wireless/zigbee/enrollments/1234",
              "request": {
                "serial": "Q234-ABCD-5678"
              },
              "status": "complete",
              "enrollmentStartedAt": "complete",
              "doorLocks": [
                {
                  "doorLockId": "1",
                  "name": "Door Lock 123",
                  "shortId": "ABE123",
                  "lqi": "1",
                  "rssi": "1",
                  "status": "online",
                  "eui64": "DL403",
                  "enrolledAt": "2023-08-14T19:57:06Z",
                  "lastSeenAt": "2023-08-14T19:59:01Z",
                  "network": {
                    "id": "N_24329156",
                    "name": "Main Office"
                  },
                  "gateway": {
                    "name": "My AP",
                    "serial": "Q234-ABCD-5678"
                  }
                }
              ]
            }
            ```

        """
        serial = urllib.parse.quote(str(serial), safe="")
        enrollment_id = urllib.parse.quote(str(enrollment_id), safe="")
        path = f"/devices/{serial}/wireless/zigbee/enrollments/{enrollment_id}"

        return await self._session.get(
            scope="wireless",
            operation_id="getDeviceWirelessZigbeeEnrollment",
            path=path,
            response_schema=GetDeviceWirelessZigbeeEnrollmentResponse,
        )

    def get_network_wireless_air_marshal(
        self, network_id: str, *, t0: str | None = None, timespan: float | None = None
    ) -> AsyncPaginatedResponse[GetNetworkWirelessAirMarshalResponseItem]:
        """List Air Marshal scan results from a network.

        [API documentation: getNetworkWirelessAirMarshal](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-air-marshal)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameter t0. The value must be in seconds and
                be less than or equal to 31 days. The default is 7 days.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "ssid": "linksys",
                "bssids": [
                  {
                    "bssid": "00:11:22:33:44:55",
                    "contained": false,
                    "detectedBy": [
                      {
                        "device": "Q234-ABCD-5678",
                        "rssi": 17
                      }
                    ]
                  }
                ],
                "channels": [
                  36,
                  40
                ],
                "firstSeen": 1518365681,
                "lastSeen": 1526087474,
                "wiredMacs": [
                  "00:11:22:33:44:55"
                ],
                "wiredVlans": [
                  0,
                  108
                ],
                "wiredLastSeen": 1526087474
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/airMarshal"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessAirMarshal",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessAirMarshalResponseItem,
        )

    async def create_network_wireless_air_marshal_rule(
        self,
        *,
        network_id: str,
        type_: CreateNetworkWirelessAirMarshalRuleType,
        match: CreateNetworkWirelessAirMarshalRuleMatch,
    ) -> CreateNetworkWirelessAirMarshalRuleResponse:
        """Creates a new rule.

        [API documentation: createNetworkWirelessAirMarshalRule](https://developer.cisco.com/meraki/api-v1/#!create-network-wireless-air-marshal-rule)

        Args:
            network_id: Network ID.
            type_: Indicates if this rule will allow, block, or alert.
            match: Object describing the rule specification.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "network": {
                "id": "N_12345",
                "name": "Network 1"
              },
              "ruleId": "5239",
              "type": "allow",
              "updatedAt": "2023-05-23 12:02:46.298",
              "createdAt": "2023-05-23 12:02:46.298",
              "match": {
                "string": "ipsum",
                "type": "contains"
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/airMarshal/rules"

        payload: dict[str, Any] = {}
        if type_ is not None:
            payload["type"] = type_
        if match is not None:
            payload["match"] = match.model_dump(by_alias=True, exclude_none=True)

        return await self._session.post(
            scope="wireless",
            operation_id="createNetworkWirelessAirMarshalRule",
            path=path,
            json=payload,
            response_schema=CreateNetworkWirelessAirMarshalRuleResponse,
        )

    async def update_network_wireless_air_marshal_rule(
        self,
        *,
        network_id: str,
        rule_id: str,
        type_: UpdateNetworkWirelessAirMarshalRuleType | None = None,
        match: UpdateNetworkWirelessAirMarshalRuleMatch | None = None,
    ) -> UpdateNetworkWirelessAirMarshalRuleResponse:
        """Update a rule.

        [API documentation: updateNetworkWirelessAirMarshalRule](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-air-marshal-rule)

        Args:
            network_id: Network ID.
            rule_id: Rule ID.
            type_: Indicates if this rule will allow, block, or alert.
            match: Object describing the rule specification.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "network": {
                "id": "N_12345",
                "name": "Network 1"
              },
              "ruleId": "5239",
              "type": "allow",
              "updatedAt": "2023-05-23 12:02:46.298",
              "createdAt": "2023-05-23 12:02:46.298",
              "match": {
                "string": "ipsum",
                "type": "contains"
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        rule_id = urllib.parse.quote(str(rule_id), safe="")
        path = f"/networks/{network_id}/wireless/airMarshal/rules/{rule_id}"

        payload: dict[str, Any] = {}
        if type_ is not None:
            payload["type"] = type_
        if match is not None:
            payload["match"] = match.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessAirMarshalRule",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessAirMarshalRuleResponse,
        )

    async def delete_network_wireless_air_marshal_rule(
        self, *, network_id: str, rule_id: str
    ) -> None:
        """Delete an Air Marshal rule.

        [API documentation: deleteNetworkWirelessAirMarshalRule](https://developer.cisco.com/meraki/api-v1/#!delete-network-wireless-air-marshal-rule)

        Args:
            network_id: Network ID.
            rule_id: Rule ID.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        rule_id = urllib.parse.quote(str(rule_id), safe="")
        path = f"/networks/{network_id}/wireless/airMarshal/rules/{rule_id}"

        return await self._session.delete(
            scope="wireless", operation_id="deleteNetworkWirelessAirMarshalRule", path=path
        )

    async def update_network_wireless_air_marshal_settings(
        self,
        *,
        network_id: str,
        default_policy: UpdateNetworkWirelessAirMarshalSettingsDefaultPolicy,
    ) -> UpdateNetworkWirelessAirMarshalSettingsResponse:
        """Updates Air Marshal settings.

        [API documentation: updateNetworkWirelessAirMarshalSettings](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-air-marshal-settings)

        Args:
            network_id: Network ID.
            default_policy: Allows clients to access rogue networks. Blocked by default.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "networkId": "N_12345",
              "defaultPolicy": "allow"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/airMarshal/settings"

        payload: dict[str, Any] = {}
        if default_policy is not None:
            payload["defaultPolicy"] = default_policy

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessAirMarshalSettings",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessAirMarshalSettingsResponse,
        )

    async def get_network_wireless_alternate_management_interface(
        self, network_id: str
    ) -> DictResponse:
        """Return alternate management interface and devices with IP assigned.

        [API documentation: getNetworkWirelessAlternateManagementInterface](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-alternate-management-interface)

        Args:
            network_id: Network ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "vlanId": 100,
              "protocols": [
                "radius",
                "snmp",
                "syslog",
                "ldap"
              ],
              "accessPoints": [
                {
                  "serial": "Q234-ABCD-5678",
                  "alternateManagementIp": "1.2.3.4",
                  "subnetMask": "255.255.255.0",
                  "gateway": "1.2.3.5",
                  "dns1": "8.8.8.8",
                  "dns2": "8.8.4.4"
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/alternateManagementInterface"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessAlternateManagementInterface",
            path=path,
            response_schema=DictResponse,
        )

    async def update_network_wireless_alternate_management_interface(
        self,
        network_id: str,
        *,
        enabled: bool | None = None,
        vlan_id: int | None = None,
        protocols: UpdateNetworkWirelessAlternateManagementInterfaceProtocols | None = None,
        access_points: list[UpdateNetworkWirelessAlternateManagementInterfaceAccessPointsItem]
        | None = None,
    ) -> DictResponse:
        """Update alternate management interface and device static IP.

        [API documentation: updateNetworkWirelessAlternateManagementInterface](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-alternate-management-interface)

        Args:
            network_id: Network ID.
            enabled: Boolean value to enable or disable alternate management interface.
            vlan_id: Alternate management interface VLAN, must be between 1 and 4094.
            protocols: Can be one or more of the following values: 'radius', 'snmp', 'syslog' or
                'ldap'.
            access_points: Array of access point serial number and IP assignment. Note: accessPoints
                IP assignment is not applicable for template networks, in other words,
                do not put 'accessPoints' in the body when updating template networks.
                Also, an empty 'accessPoints' array will remove all previous static IP
                assignments.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "vlanId": 100,
              "protocols": [
                "radius",
                "snmp",
                "syslog",
                "ldap"
              ],
              "accessPoints": [
                {
                  "serial": "Q234-ABCD-5678",
                  "alternateManagementIp": "1.2.3.4",
                  "subnetMask": "255.255.255.0",
                  "gateway": "1.2.3.5",
                  "dns1": "8.8.8.8",
                  "dns2": "8.8.4.4"
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/alternateManagementInterface"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if vlan_id is not None:
            payload["vlanId"] = vlan_id
        if protocols is not None:
            payload["protocols"] = protocols
        if access_points is not None:
            payload["accessPoints"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in access_points
            ]

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessAlternateManagementInterface",
            path=path,
            json=payload,
            response_schema=DictResponse,
        )

    async def get_network_wireless_billing(
        self, network_id: str
    ) -> GetNetworkWirelessBillingResponse:
        """Return the billing settings of this network.

        [API documentation: getNetworkWirelessBilling](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-billing)

        Args:
            network_id: Network ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "currency": "USD",
              "plans": [
                {
                  "id": "1",
                  "price": 5.0,
                  "bandwidthLimits": {
                    "limitUp": 1000,
                    "limitDown": 1000
                  },
                  "timeLimit": "1 hour"
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/billing"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessBilling",
            path=path,
            response_schema=GetNetworkWirelessBillingResponse,
        )

    async def update_network_wireless_billing(
        self,
        network_id: str,
        *,
        currency: str | None = None,
        plans: list[UpdateNetworkWirelessBillingPlansItem] | None = None,
    ) -> UpdateNetworkWirelessBillingResponse:
        """Update the billing settings.

        [API documentation: updateNetworkWirelessBilling](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-billing)

        Args:
            network_id: Network ID.
            currency: The currency code of this node group's billing plans.
            plans: Array of billing plans in the node group. (Can configure a maximum of 5).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "currency": "USD",
              "plans": [
                {
                  "id": "1",
                  "price": 5.0,
                  "bandwidthLimits": {
                    "limitUp": 1000,
                    "limitDown": 1000
                  },
                  "timeLimit": "1 hour"
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/billing"

        payload: dict[str, Any] = {}
        if currency is not None:
            payload["currency"] = currency
        if plans is not None:
            payload["plans"] = [item.model_dump(by_alias=True, exclude_none=True) for item in plans]

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessBilling",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessBillingResponse,
        )

    async def get_network_wireless_bluetooth_settings(
        self, network_id: str
    ) -> GetNetworkWirelessBluetoothSettingsResponse:
        """Return the Bluetooth settings for a network. <a href="https://documentation.meraki.com/MR/Bluetooth/Bluetooth_Low_Energy_(BLE)">Bluetooth settings</a> must be enabled on the network.

        [API documentation: getNetworkWirelessBluetoothSettings](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-bluetooth-settings)

        Args:
            network_id: Network ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "scanningEnabled": true,
              "advertisingEnabled": true,
              "uuid": "00000000-0000-0000-000-000000000000",
              "majorMinorAssignmentMode": "Non-unique",
              "major": 1,
              "minor": 1,
              "eslEnabled": true
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/bluetooth/settings"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessBluetoothSettings",
            path=path,
            response_schema=GetNetworkWirelessBluetoothSettingsResponse,
        )

    async def update_network_wireless_bluetooth_settings(
        self,
        network_id: str,
        *,
        scanning_enabled: bool | None = None,
        advertising_enabled: bool | None = None,
        uuid: str | None = None,
        major_minor_assignment_mode: UpdateNetworkWirelessBluetoothSettingsMajorMinorAssignmentMode
        | None = None,
        major: int | None = None,
        minor: int | None = None,
    ) -> UpdateNetworkWirelessBluetoothSettingsResponse:
        """Update the Bluetooth settings for a network.

        [API documentation: updateNetworkWirelessBluetoothSettings](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-bluetooth-settings)

        Args:
            network_id: Network ID.
            scanning_enabled: Whether APs will scan for Bluetooth enabled clients.
            advertising_enabled: Whether APs will advertise beacons.
            uuid: The UUID to be used in the beacon identifier.
            major_minor_assignment_mode: The way major and minor number should be assigned to nodes
                in the network. ('Unique', 'Non-unique').
            major: The major number to be used in the beacon identifier. Only valid in 'Non-unique'
                mode.
            minor: The minor number to be used in the beacon identifier. Only valid in 'Non-unique'
                mode.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "scanningEnabled": true,
              "advertisingEnabled": true,
              "uuid": "00000000-0000-0000-000-000000000000",
              "majorMinorAssignmentMode": "Non-unique",
              "major": 1,
              "minor": 1,
              "eslEnabled": true
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/bluetooth/settings"

        payload: dict[str, Any] = {}
        if scanning_enabled is not None:
            payload["scanningEnabled"] = scanning_enabled
        if advertising_enabled is not None:
            payload["advertisingEnabled"] = advertising_enabled
        if uuid is not None:
            payload["uuid"] = uuid
        if major_minor_assignment_mode is not None:
            payload["majorMinorAssignmentMode"] = major_minor_assignment_mode
        if major is not None:
            payload["major"] = major
        if minor is not None:
            payload["minor"] = minor

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessBluetoothSettings",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessBluetoothSettingsResponse,
        )

    def get_network_wireless_channel_utilization_history(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        resolution: int | None = None,
        auto_resolution: bool | None = None,
        client_id: str | None = None,
        device_serial: str | None = None,
        ap_tag: str | None = None,
        band: GetNetworkWirelessChannelUtilizationHistoryBand | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessChannelUtilizationHistoryResponseItem]:
        """Return AP channel utilization over time for a device or network client.

        [API documentation: getNetworkWirelessChannelUtilizationHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-channel-utilization-history)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 7 days.
            resolution: The time resolution in seconds for returned data. The valid resolutions are:
                600, 1200, 3600, 14400, 86400. The default is 86400.
            auto_resolution: Automatically select a data resolution based on the given timespan;
                this overrides the value specified by the 'resolution' parameter. The
                default setting is false.
            client_id: Filter results by network client to return per-device, per-band AP channel
                utilization metrics inner joined by the queried client's connection
                history.
            device_serial: Filter results by device to return AP channel utilization metrics for the
                queried device; either :band or :clientId must be jointly specified.
            ap_tag: Filter results by AP tag to return AP channel utilization metrics for devices
                labeled with the given tag; either :clientId or :deviceSerial must be
                jointly specified.
            band: Filter results by band (either '2.4', '5' or '6').

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2020-01-01T00:00:00Z",
                "endTs": "2020-01-01T01:00:00Z",
                "utilizationTotal": 9.89,
                "utilization80211": 7.22,
                "utilizationNon80211": 2.67
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/channelUtilizationHistory"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if resolution is not None:
            params["resolution"] = resolution
        if auto_resolution is not None:
            params["autoResolution"] = auto_resolution
        if client_id is not None:
            params["clientId"] = client_id
        if device_serial is not None:
            params["deviceSerial"] = device_serial
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if band is not None:
            params["band"] = band

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessChannelUtilizationHistory",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessChannelUtilizationHistoryResponseItem,
        )

    def get_network_wireless_client_count_history(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        resolution: int | None = None,
        auto_resolution: bool | None = None,
        client_id: str | None = None,
        device_serial: str | None = None,
        ap_tag: str | None = None,
        band: GetNetworkWirelessClientCountHistoryBand | None = None,
        ssid: int | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessClientCountHistoryResponseItem]:
        """Return wireless client counts over time for a network, device, or network client.

        [API documentation: getNetworkWirelessClientCountHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-client-count-history)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 7 days.
            resolution: The time resolution in seconds for returned data. The valid resolutions are:
                300, 600, 1200, 3600, 14400, 86400. The default is 86400.
            auto_resolution: Automatically select a data resolution based on the given timespan;
                this overrides the value specified by the 'resolution' parameter. The
                default setting is false.
            client_id: Filter results by network client to return per-device client counts over time
                inner joined by the queried client's connection history.
            device_serial: Filter results by device.
            ap_tag: Filter results by AP tag.
            band: Filter results by band (either '2.4', '5' or '6').
            ssid: Filter results by SSID number.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2020-01-01T00:00:00Z",
                "endTs": "2020-01-01T01:00:00Z",
                "clientCount": 14
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/clientCountHistory"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if resolution is not None:
            params["resolution"] = resolution
        if auto_resolution is not None:
            params["autoResolution"] = auto_resolution
        if client_id is not None:
            params["clientId"] = client_id
        if device_serial is not None:
            params["deviceSerial"] = device_serial
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessClientCountHistory",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessClientCountHistoryResponseItem,
        )

    def get_network_wireless_clients_connection_stats(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessClientsConnectionStatsBand | None = None,
        ssid: GetNetworkWirelessClientsConnectionStatsSsid | None = None,
        ap_tag: str | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessClientsConnectionStatsResponse]:
        """Aggregated connectivity info for this network, grouped by clients.

        [API documentation: getNetworkWirelessClientsConnectionStats](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-clients-connection-stats)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "mac": "00:61:71:c8:51:27",
                "connectionStats": {
                  "assoc": 0,
                  "auth": 4,
                  "dhcp": 0,
                  "dns": 0,
                  "success": 10
                }
              },
              {
                "mac": "1c:4d:70:7f:5e:5e",
                "connectionStats": {
                  "assoc": 0,
                  "auth": 1,
                  "dhcp": 0,
                  "dns": 0,
                  "success": 24
                }
              },
              {
                "mac": "1c:4d:70:81:8d:0a",
                "connectionStats": {
                  "assoc": 1,
                  "auth": 0,
                  "dhcp": 0,
                  "dns": 0,
                  "success": 16
                }
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/clients/connectionStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessClientsConnectionStats",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessClientsConnectionStatsResponse,
        )

    def get_network_wireless_clients_latency_stats(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessClientsLatencyStatsBand | None = None,
        ssid: GetNetworkWirelessClientsLatencyStatsSsid | None = None,
        ap_tag: str | None = None,
        vlan: int | None = None,
        fields: str | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessClientsLatencyStatsResponse]:
        """Aggregated latency info for this network, grouped by clients.

        [API documentation: getNetworkWirelessClientsLatencyStats](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-clients-latency-stats)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.
            vlan: Filter results by VLAN.
            fields: Partial selection: If present, this call will return only the selected fields of
                ["rawDistribution", "avg"]. All fields will be returned by default.
                Selected fields must be entered as a comma separated string.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "mac": "00:61:71:c8:51:27",
                "latencyStats": {
                  "backgroundTraffic": {
                    "rawDistribution": {
                      "0": 1234,
                      "1": 2345,
                      "2": 3456,
                      "4": 4567,
                      "8": 5678,
                      "16": 6789,
                      "32": 7890,
                      "64": 8901,
                      "128": 9012,
                      "256": 83,
                      "512": 1234,
                      "1024": 2345,
                      "2048": 9999
                    },
                    "avg": 606.52
                  },
                  "bestEffortTraffic": "same shape as backgroundTraffic",
                  "videoTraffic": "same shape as backgroundTraffic",
                  "voiceTraffic": "same shape as backgroundTraffic"
                }
              },
              {
                "mac": "1c:4d:70:7f:5e:5e",
                "latencyStats": {
                  "backgroundTraffic": {
                    "rawDistribution": {
                      "0": 1234,
                      "1": 2345,
                      "2": 3456,
                      "4": 4567,
                      "8": 5678,
                      "16": 6789,
                      "32": 7890,
                      "64": 8901,
                      "128": 9012,
                      "256": 83,
                      "512": 1234,
                      "1024": 2345,
                      "2048": 9999
                    },
                    "avg": 606.52
                  },
                  "bestEffortTraffic": "same shape as backgroundTraffic",
                  "videoTraffic": "same shape as backgroundTraffic",
                  "voiceTraffic": "same shape as backgroundTraffic"
                }
              },
              {
                "mac": "1c:4d:70:81:8d:0a",
                "latencyStats": {
                  "backgroundTraffic": {
                    "rawDistribution": {
                      "0": 1234,
                      "1": 2345,
                      "2": 3456,
                      "4": 4567,
                      "8": 5678,
                      "16": 6789,
                      "32": 7890,
                      "64": 8901,
                      "128": 9012,
                      "256": 83,
                      "512": 1234,
                      "1024": 2345,
                      "2048": 9999
                    },
                    "avg": 606.52
                  },
                  "bestEffortTraffic": "same shape as backgroundTraffic",
                  "videoTraffic": "same shape as backgroundTraffic",
                  "voiceTraffic": "same shape as backgroundTraffic"
                }
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/clients/latencyStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if vlan is not None:
            params["vlan"] = vlan
        if fields is not None:
            params["fields"] = fields

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessClientsLatencyStats",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessClientsLatencyStatsResponse,
        )

    async def get_network_wireless_client_connection_stats(
        self,
        *,
        network_id: str,
        client_id: str,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessClientConnectionStatsBand | None = None,
        ssid: GetNetworkWirelessClientConnectionStatsSsid | None = None,
        ap_tag: str | None = None,
    ) -> GetNetworkWirelessClientConnectionStatsResponse:
        """Aggregated connectivity info for a given client on this network.

        [API documentation: getNetworkWirelessClientConnectionStats](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-client-connection-stats)

        Args:
            network_id: Network ID.
            client_id: Client ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "mac": "00:11:22:33:44:55",
              "connectionStats": {
                "assoc": 3,
                "auth": 4,
                "dhcp": 4,
                "success": 5
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        client_id = urllib.parse.quote(str(client_id), safe="")
        path = f"/networks/{network_id}/wireless/clients/{client_id}/connectionStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessClientConnectionStats",
            path=path,
            params=params,
            response_schema=GetNetworkWirelessClientConnectionStatsResponse,
        )

    def get_network_wireless_client_connectivity_events(
        self,
        *,
        network_id: str,
        client_id: str,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        sort_order: GetNetworkWirelessClientConnectivityEventsSortOrder | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        types: GetNetworkWirelessClientConnectivityEventsTypes | None = None,
        band: GetNetworkWirelessClientConnectivityEventsBand | None = None,
        ssid_number: GetNetworkWirelessClientConnectivityEventsSsidNumber | None = None,
        included_severities: GetNetworkWirelessClientConnectivityEventsIncludedSeverities
        | None = None,
        device_serial: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetNetworkWirelessClientConnectivityEventsResponseItem]:
        """List the wireless connectivity events for a client within a network in the timespan.

        [API documentation: getNetworkWirelessClientConnectivityEvents](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-client-connectivity-events)

        Args:
            network_id: Network ID.
            client_id: Client ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            sort_order: Sorted order of entries. Order options are 'ascending' and 'descending'.
                Default is 'ascending'.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 1 day.
            types: A list of event types to include. If not specified, events of all types will be
                returned. Valid types are 'assoc', 'disassoc', 'auth', 'deauth', 'dns',
                'dhcp', 'roam', 'connection' and/or 'sticky'.
            band: Filter results by band. Valid bands are '2.4', '5' or '6'.
            ssid_number: Filter results by SSID. If not specified, events for all SSIDs will be
                returned.
            included_severities: A list of severities to include. If not specified, events of all
                severities will be returned. Valid severities are 'good', 'info', 'warn'
                and/or 'bad'.
            device_serial: Filter results by an AP's serial number.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "occurredAt": "2018-02-11T00:00:00.090210Z",
                "band": "5",
                "ssidNumber": 1,
                "type": "auth",
                "subtype": "success",
                "severity": "bad",
                "durationMs": 100,
                "channel": 44,
                "rssi": 80,
                "deviceSerial": "Q234-ABCD-5678",
                "captureId": "123456"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        client_id = urllib.parse.quote(str(client_id), safe="")
        path = f"/networks/{network_id}/wireless/clients/{client_id}/connectivityEvents"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if sort_order is not None:
            params["sortOrder"] = sort_order
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if types is not None:
            params["types[]"] = types
        if band is not None:
            params["band"] = band
        if ssid_number is not None:
            params["ssidNumber"] = ssid_number
        if included_severities is not None:
            params["includedSeverities[]"] = included_severities
        if device_serial is not None:
            params["deviceSerial"] = device_serial

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessClientConnectivityEvents",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkWirelessClientConnectivityEventsResponseItem,
        )

    def get_network_wireless_client_latency_history(
        self,
        *,
        network_id: str,
        client_id: str,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        resolution: int | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessClientLatencyHistoryResponseItem]:
        """Return the latency history for a client.

        [API documentation: getNetworkWirelessClientLatencyHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-client-latency-history)

        Args:
            network_id: Network ID.
            client_id: Client ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 791 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 791 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 791 days. The default is 1 day.
            resolution: The time resolution in seconds for returned data. The valid resolutions are:
                86400. The default is 86400.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "t0": 1550534400,
                "t1": 1550620800,
                "latencyBinsByCategory": {
                  "backgroundTraffic": {
                    "0.5": 41750,
                    "1.0": 21552,
                    "2.0": 59940,
                    "4.0": 146622,
                    "8.0": 57354,
                    "16.0": 0,
                    "32.0": 9954,
                    "64.0": 0,
                    "128.0": 0,
                    "256.0": 1896,
                    "512.0": 0,
                    "1024.0": 0,
                    "2048.0": 0
                  },
                  "bestEffortTraffic": {
                    "0.5": 1840899,
                    "1.0": 1644506,
                    "2.0": 629958,
                    "4.0": 449564,
                    "8.0": 2009658,
                    "16.0": 1329568,
                    "32.0": 282168,
                    "64.0": 97573,
                    "128.0": 191977,
                    "256.0": 30560,
                    "512.0": 26032,
                    "1024.0": 4943,
                    "2048.0": 12072
                  },
                  "videoTraffic": {
                    "0.5": 0,
                    "1.0": 0,
                    "2.0": 0,
                    "4.0": 0,
                    "8.0": 0,
                    "16.0": 0,
                    "32.0": 0,
                    "64.0": 0,
                    "128.0": 0,
                    "256.0": 0,
                    "512.0": 0,
                    "1024.0": 0,
                    "2048.0": 0
                  },
                  "voiceTraffic": {
                    "0.5": 716,
                    "1.0": 948,
                    "2.0": 474,
                    "4.0": 78,
                    "8.0": 0,
                    "16.0": 0,
                    "32.0": 0,
                    "64.0": 0,
                    "128.0": 0,
                    "256.0": 0,
                    "512.0": 0,
                    "1024.0": 0,
                    "2048.0": 0
                  }
                }
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        client_id = urllib.parse.quote(str(client_id), safe="")
        path = f"/networks/{network_id}/wireless/clients/{client_id}/latencyHistory"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if resolution is not None:
            params["resolution"] = resolution

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessClientLatencyHistory",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessClientLatencyHistoryResponseItem,
        )

    async def get_network_wireless_client_latency_stats(
        self,
        *,
        network_id: str,
        client_id: str,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessClientLatencyStatsBand | None = None,
        ssid: GetNetworkWirelessClientLatencyStatsSsid | None = None,
        ap_tag: str | None = None,
        vlan: int | None = None,
        fields: str | None = None,
    ) -> DictResponse:
        """Aggregated latency info for a given client on this network.

        [API documentation: getNetworkWirelessClientLatencyStats](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-client-latency-stats)

        Args:
            network_id: Network ID.
            client_id: Client ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.
            vlan: Filter results by VLAN.
            fields: Partial selection: If present, this call will return only the selected fields of
                ["rawDistribution", "avg"]. All fields will be returned by default.
                Selected fields must be entered as a comma separated string.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "mac": "00:61:71:c8:51:27",
              "latencyStats": {
                "backgroundTraffic": {
                  "rawDistribution": {
                    "0": 1234,
                    "1": 2345,
                    "2": 3456,
                    "4": 4567,
                    "8": 5678,
                    "16": 6789,
                    "32": 7890,
                    "64": 8901,
                    "128": 9012,
                    "256": 83,
                    "512": 1234,
                    "1024": 2345,
                    "2048": 9999
                  },
                  "avg": 606.52
                },
                "bestEffortTraffic": "same shape as backgroundTraffic",
                "videoTraffic": "same shape as backgroundTraffic",
                "voiceTraffic": "same shape as backgroundTraffic"
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        client_id = urllib.parse.quote(str(client_id), safe="")
        path = f"/networks/{network_id}/wireless/clients/{client_id}/latencyStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if vlan is not None:
            params["vlan"] = vlan
        if fields is not None:
            params["fields"] = fields

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessClientLatencyStats",
            path=path,
            params=params,
            response_schema=DictResponse,
        )

    async def get_network_wireless_connection_stats(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessConnectionStatsBand | None = None,
        ssid: GetNetworkWirelessConnectionStatsSsid | None = None,
        ap_tag: str | None = None,
    ) -> GetNetworkWirelessConnectionStatsResponse:
        """Aggregated connectivity info for this network.

        [API documentation: getNetworkWirelessConnectionStats](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-connection-stats)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "assoc": 1,
              "auth": 5,
              "dhcp": 0,
              "dns": 0,
              "success": 51
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/connectionStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessConnectionStats",
            path=path,
            params=params,
            response_schema=GetNetworkWirelessConnectionStatsResponse,
        )

    def get_network_wireless_data_rate_history(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        resolution: int | None = None,
        auto_resolution: bool | None = None,
        client_id: str | None = None,
        device_serial: str | None = None,
        ap_tag: str | None = None,
        band: GetNetworkWirelessDataRateHistoryBand | None = None,
        ssid: int | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessDataRateHistoryResponseItem]:
        """Return PHY data rates over time for a network, device, or network client.

        [API documentation: getNetworkWirelessDataRateHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-data-rate-history)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 7 days.
            resolution: The time resolution in seconds for returned data. The valid resolutions are:
                300, 600, 1200, 3600, 14400, 86400. The default is 86400.
            auto_resolution: Automatically select a data resolution based on the given timespan;
                this overrides the value specified by the 'resolution' parameter. The
                default setting is false.
            client_id: Filter results by network client.
            device_serial: Filter results by device.
            ap_tag: Filter results by AP tag.
            band: Filter results by band (either '2.4', '5' or '6').
            ssid: Filter results by SSID number.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2020-01-01T00:00:00Z",
                "endTs": "2020-01-01T01:00:00Z",
                "averageKbps": 151806,
                "downloadKbps": 144839,
                "uploadKbps": 158837
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/dataRateHistory"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if resolution is not None:
            params["resolution"] = resolution
        if auto_resolution is not None:
            params["autoResolution"] = auto_resolution
        if client_id is not None:
            params["clientId"] = client_id
        if device_serial is not None:
            params["deviceSerial"] = device_serial
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessDataRateHistory",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessDataRateHistoryResponseItem,
        )

    def get_network_wireless_devices_connection_stats(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessDevicesConnectionStatsBand | None = None,
        ssid: GetNetworkWirelessDevicesConnectionStatsSsid | None = None,
        ap_tag: str | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessDevicesConnectionStatsResponseItem]:
        """Aggregated connectivity info for this network, grouped by node.

        [API documentation: getNetworkWirelessDevicesConnectionStats](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-devices-connection-stats)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "serial": "Q234-ABCD-5678",
                "connectionStats": {
                  "assoc": 0,
                  "auth": 1,
                  "dhcp": 0,
                  "dns": 0,
                  "success": 43
                }
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/devices/connectionStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessDevicesConnectionStats",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessDevicesConnectionStatsResponseItem,
        )

    def get_network_wireless_devices_latency_stats(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessDevicesLatencyStatsBand | None = None,
        ssid: GetNetworkWirelessDevicesLatencyStatsSsid | None = None,
        ap_tag: str | None = None,
        vlan: int | None = None,
        fields: str | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessDevicesLatencyStatsResponse]:
        """Aggregated latency info for this network, grouped by node.

        [API documentation: getNetworkWirelessDevicesLatencyStats](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-devices-latency-stats)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.
            vlan: Filter results by VLAN.
            fields: Partial selection: If present, this call will return only the selected fields of
                ["rawDistribution", "avg"]. All fields will be returned by default.
                Selected fields must be entered as a comma separated string.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "serial": "Q2JC-2MJM-FHRD",
                "latencyStats": {
                  "backgroundTraffic": {
                    "rawDistribution": {
                      "0": 1234,
                      "1": 2345,
                      "2": 3456,
                      "4": 4567,
                      "8": 5678,
                      "16": 6789,
                      "32": 7890,
                      "64": 8901,
                      "128": 9012,
                      "256": 83,
                      "512": 1234,
                      "1024": 2345,
                      "2048": 9999
                    },
                    "avg": 606.52
                  },
                  "bestEffortTraffic": "same shape as backgroundTraffic",
                  "videoTraffic": "same shape as backgroundTraffic",
                  "voiceTraffic": "same shape as backgroundTraffic"
                }
              },
              {
                "serial": "Q2FJ-3SHB-Y2K2",
                "latencyStats": {
                  "backgroundTraffic": {
                    "rawDistribution": {
                      "0": 1234,
                      "1": 2345,
                      "2": 3456,
                      "4": 4567,
                      "8": 5678,
                      "16": 6789,
                      "32": 7890,
                      "64": 8901,
                      "128": 9012,
                      "256": 83,
                      "512": 1234,
                      "1024": 2345,
                      "2048": 9999
                    },
                    "avg": 606.52
                  },
                  "bestEffortTraffic": "same shape as backgroundTraffic",
                  "videoTraffic": "same shape as backgroundTraffic",
                  "voiceTraffic": "same shape as backgroundTraffic"
                }
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/devices/latencyStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if vlan is not None:
            params["vlan"] = vlan
        if fields is not None:
            params["fields"] = fields

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessDevicesLatencyStats",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessDevicesLatencyStatsResponse,
        )

    async def get_network_wireless_electronic_shelf_label(
        self, network_id: str
    ) -> GetNetworkWirelessElectronicShelfLabelResponse:
        """Return the ESL settings of a wireless network.

        [API documentation: getNetworkWirelessElectronicShelfLabel](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-electronic-shelf-label)

        Args:
            network_id: Network ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "hostname": "example.com",
              "enabled": true,
              "mode": "high frequency"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/electronicShelfLabel"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessElectronicShelfLabel",
            path=path,
            response_schema=GetNetworkWirelessElectronicShelfLabelResponse,
        )

    async def update_network_wireless_electronic_shelf_label(
        self,
        network_id: str,
        *,
        hostname: str | None = None,
        enabled: bool | None = None,
        mode: UpdateNetworkWirelessElectronicShelfLabelMode | None = None,
    ) -> UpdateNetworkWirelessElectronicShelfLabelResponse:
        """Update the ESL settings of a wireless network.

        [API documentation: updateNetworkWirelessElectronicShelfLabel](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-electronic-shelf-label)

        Args:
            network_id: Network ID.
            hostname: Desired ESL hostname of the network.
            enabled: Turn ESL features on and off for this network.
            mode: Electronic shelf label mode of the network. Valid options are 'Bluetooth', 'high
                frequency'.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "hostname": "example.com",
              "enabled": true,
              "mode": "high frequency"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/electronicShelfLabel"

        payload: dict[str, Any] = {}
        if hostname is not None:
            payload["hostname"] = hostname
        if enabled is not None:
            payload["enabled"] = enabled
        if mode is not None:
            payload["mode"] = mode

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessElectronicShelfLabel",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessElectronicShelfLabelResponse,
        )

    def get_network_wireless_electronic_shelf_label_configured_devices(
        self, network_id: str
    ) -> AsyncPaginatedResponse[
        GetNetworkWirelessElectronicShelfLabelConfiguredDevicesResponseItem
    ]:
        """Get a list of all ESL eligible devices of a network.

        [API documentation: getNetworkWirelessElectronicShelfLabelConfiguredDevices](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-electronic-shelf-label-configured-devices)

        Args:
            network_id: Network ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "hostname": "example.com",
                "enabled": true,
                "mode": "high frequency"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/electronicShelfLabel/configuredDevices"

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessElectronicShelfLabelConfiguredDevices",
            path=path,
            item_schema=GetNetworkWirelessElectronicShelfLabelConfiguredDevicesResponseItem,
        )

    def get_network_wireless_ethernet_ports_profiles(
        self, network_id: str
    ) -> AsyncPaginatedResponse[GetNetworkWirelessEthernetPortsProfilesResponseItem]:
        """List the AP port profiles for this network.

        [API documentation: getNetworkWirelessEthernetPortsProfiles](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ethernet-ports-profiles)

        Args:
            network_id: Network ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "profileId": "1001",
                "name": "Ap Port Profile Name",
                "isDefault": false,
                "ports": [
                  {
                    "name": "port 1",
                    "number": 1,
                    "enabled": true,
                    "ssid": 1,
                    "pskGroupId": "100"
                  }
                ],
                "usbPorts": [
                  {
                    "name": "usb port",
                    "enabled": true,
                    "ssid": 5
                  }
                ]
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/ethernet/ports/profiles"

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessEthernetPortsProfiles",
            path=path,
            item_schema=GetNetworkWirelessEthernetPortsProfilesResponseItem,
        )

    async def create_network_wireless_ethernet_ports_profile(
        self,
        *,
        network_id: str,
        name: str,
        ports: list[CreateNetworkWirelessEthernetPortsProfilePortsItem],
        usb_ports: list[CreateNetworkWirelessEthernetPortsProfileUsbPortsItem] | None = None,
    ) -> CreateNetworkWirelessEthernetPortsProfileResponse:
        """Create an AP port profile.

        [API documentation: createNetworkWirelessEthernetPortsProfile](https://developer.cisco.com/meraki/api-v1/#!create-network-wireless-ethernet-ports-profile)

        Args:
            network_id: Network ID.
            name: AP port profile name.
            ports: AP ports configuration.
            usb_ports: AP usb ports configuration.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "profileId": "1001",
              "name": "Ap Port Profile Name",
              "isDefault": false,
              "ports": [
                {
                  "name": "port 1",
                  "number": 1,
                  "enabled": true,
                  "ssid": 1,
                  "pskGroupId": "100"
                }
              ],
              "usbPorts": [
                {
                  "name": "usb port",
                  "enabled": true,
                  "ssid": 5
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/ethernet/ports/profiles"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if ports is not None:
            payload["ports"] = [item.model_dump(by_alias=True, exclude_none=True) for item in ports]
        if usb_ports is not None:
            payload["usbPorts"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in usb_ports
            ]

        return await self._session.post(
            scope="wireless",
            operation_id="createNetworkWirelessEthernetPortsProfile",
            path=path,
            json=payload,
            response_schema=CreateNetworkWirelessEthernetPortsProfileResponse,
        )

    async def assign_network_wireless_ethernet_ports_profiles(
        self, *, network_id: str, serials: list[str], profile_id: str
    ) -> AssignNetworkWirelessEthernetPortsProfilesResponse:
        """Assign AP port profile to list of APs.

        [API documentation: assignNetworkWirelessEthernetPortsProfiles](https://developer.cisco.com/meraki/api-v1/#!assign-network-wireless-ethernet-ports-profiles)

        Args:
            network_id: Network ID.
            serials: List of AP serials.
            profile_id: AP profile ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "serials": [
                "Q234-ABCD-0001",
                "Q234-ABCD-0002",
                "Q234-ABCD-0003"
              ],
              "profileId": "1001"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/ethernet/ports/profiles/assign"

        payload: dict[str, Any] = {}
        if serials is not None:
            payload["serials"] = serials
        if profile_id is not None:
            payload["profileId"] = profile_id

        return await self._session.post(
            scope="wireless",
            operation_id="assignNetworkWirelessEthernetPortsProfiles",
            path=path,
            json=payload,
            response_schema=AssignNetworkWirelessEthernetPortsProfilesResponse,
        )

    async def set_network_wireless_ethernet_ports_profiles_default(
        self, *, network_id: str, profile_id: str
    ) -> SetNetworkWirelessEthernetPortsProfilesDefaultResponse:
        """Set the AP port profile to be default for this network.

        [API documentation: setNetworkWirelessEthernetPortsProfilesDefault](https://developer.cisco.com/meraki/api-v1/#!set-network-wireless-ethernet-ports-profiles-default)

        Args:
            network_id: Network ID.
            profile_id: AP profile ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "profileId": "1001"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/ethernet/ports/profiles/setDefault"

        payload: dict[str, Any] = {}
        if profile_id is not None:
            payload["profileId"] = profile_id

        return await self._session.post(
            scope="wireless",
            operation_id="setNetworkWirelessEthernetPortsProfilesDefault",
            path=path,
            json=payload,
            response_schema=SetNetworkWirelessEthernetPortsProfilesDefaultResponse,
        )

    async def get_network_wireless_ethernet_ports_profile(
        self, *, network_id: str, profile_id: str
    ) -> GetNetworkWirelessEthernetPortsProfileResponse:
        """Show the AP port profile by ID for this network.

        [API documentation: getNetworkWirelessEthernetPortsProfile](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ethernet-ports-profile)

        Args:
            network_id: Network ID.
            profile_id: Profile ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "profileId": "1001",
              "name": "Ap Port Profile Name",
              "isDefault": false,
              "ports": [
                {
                  "name": "port 1",
                  "number": 1,
                  "enabled": true,
                  "ssid": 1,
                  "pskGroupId": "100"
                }
              ],
              "usbPorts": [
                {
                  "name": "usb port",
                  "enabled": true,
                  "ssid": 5
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        profile_id = urllib.parse.quote(str(profile_id), safe="")
        path = f"/networks/{network_id}/wireless/ethernet/ports/profiles/{profile_id}"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessEthernetPortsProfile",
            path=path,
            response_schema=GetNetworkWirelessEthernetPortsProfileResponse,
        )

    async def update_network_wireless_ethernet_ports_profile(
        self,
        *,
        network_id: str,
        profile_id: str,
        name: str | None = None,
        ports: list[UpdateNetworkWirelessEthernetPortsProfilePortsItem] | None = None,
        usb_ports: list[UpdateNetworkWirelessEthernetPortsProfileUsbPortsItem] | None = None,
    ) -> UpdateNetworkWirelessEthernetPortsProfileResponse:
        """Update the AP port profile by ID for this network.

        [API documentation: updateNetworkWirelessEthernetPortsProfile](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ethernet-ports-profile)

        Args:
            network_id: Network ID.
            profile_id: Profile ID.
            name: AP port profile name.
            ports: AP ports configuration.
            usb_ports: AP usb ports configuration.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "profileId": "1001",
              "name": "Ap Port Profile Name",
              "isDefault": false,
              "ports": [
                {
                  "name": "port 1",
                  "number": 1,
                  "enabled": true,
                  "ssid": 1,
                  "pskGroupId": "100"
                }
              ],
              "usbPorts": [
                {
                  "name": "usb port",
                  "enabled": true,
                  "ssid": 5
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        profile_id = urllib.parse.quote(str(profile_id), safe="")
        path = f"/networks/{network_id}/wireless/ethernet/ports/profiles/{profile_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if ports is not None:
            payload["ports"] = [item.model_dump(by_alias=True, exclude_none=True) for item in ports]
        if usb_ports is not None:
            payload["usbPorts"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in usb_ports
            ]

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessEthernetPortsProfile",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessEthernetPortsProfileResponse,
        )

    async def delete_network_wireless_ethernet_ports_profile(
        self, *, network_id: str, profile_id: str
    ) -> None:
        """Delete an AP port profile.

        [API documentation: deleteNetworkWirelessEthernetPortsProfile](https://developer.cisco.com/meraki/api-v1/#!delete-network-wireless-ethernet-ports-profile)

        Args:
            network_id: Network ID.
            profile_id: Profile ID.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        profile_id = urllib.parse.quote(str(profile_id), safe="")
        path = f"/networks/{network_id}/wireless/ethernet/ports/profiles/{profile_id}"

        return await self._session.delete(
            scope="wireless", operation_id="deleteNetworkWirelessEthernetPortsProfile", path=path
        )

    def get_network_wireless_failed_connections(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessFailedConnectionsBand | None = None,
        ssid: GetNetworkWirelessFailedConnectionsSsid | None = None,
        ap_tag: str | None = None,
        serial: str | None = None,
        client_id: str | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessFailedConnectionsResponseItem]:
        """List of all failed client connection events on this network in a given time range.

        [API documentation: getNetworkWirelessFailedConnections](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-failed-connections)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.
            serial: Filter by AP.
            client_id: Filter by client MAC.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "ssidNumber": 1,
                "vlan": 100,
                "clientMac": "22:33:44:55:66:77",
                "serial": "Q234-ABCD-5678",
                "radio": 0,
                "failureStep": "dns",
                "type": "802.1X auth fail",
                "ts": "2018-02-11T00:00:00.090210Z"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/failedConnections"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if serial is not None:
            params["serial"] = serial
        if client_id is not None:
            params["clientId"] = client_id

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessFailedConnections",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessFailedConnectionsResponseItem,
        )

    def get_network_wireless_latency_history(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        resolution: int | None = None,
        auto_resolution: bool | None = None,
        client_id: str | None = None,
        device_serial: str | None = None,
        ap_tag: str | None = None,
        band: GetNetworkWirelessLatencyHistoryBand | None = None,
        ssid: int | None = None,
        access_category: GetNetworkWirelessLatencyHistoryAccessCategory | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessLatencyHistoryResponseItem]:
        """Return average wireless latency over time for a network, device, or network client.

        [API documentation: getNetworkWirelessLatencyHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-latency-history)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 7 days.
            resolution: The time resolution in seconds for returned data. The valid resolutions are:
                300, 600, 1200, 3600, 14400, 86400. The default is 86400.
            auto_resolution: Automatically select a data resolution based on the given timespan;
                this overrides the value specified by the 'resolution' parameter. The
                default setting is false.
            client_id: Filter results by network client.
            device_serial: Filter results by device.
            ap_tag: Filter results by AP tag.
            band: Filter results by band (either '2.4', '5' or '6').
            ssid: Filter results by SSID number.
            access_category: Filter by access category.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2020-01-01T00:00:00Z",
                "endTs": "2020-01-01T01:00:00Z",
                "avgLatencyMs": 29
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/latencyHistory"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if resolution is not None:
            params["resolution"] = resolution
        if auto_resolution is not None:
            params["autoResolution"] = auto_resolution
        if client_id is not None:
            params["clientId"] = client_id
        if device_serial is not None:
            params["deviceSerial"] = device_serial
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if access_category is not None:
            params["accessCategory"] = access_category

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessLatencyHistory",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessLatencyHistoryResponseItem,
        )

    async def get_network_wireless_latency_stats(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        band: GetNetworkWirelessLatencyStatsBand | None = None,
        ssid: GetNetworkWirelessLatencyStatsSsid | None = None,
        ap_tag: str | None = None,
        vlan: int | None = None,
        fields: str | None = None,
    ) -> DictResponse:
        """Aggregated latency info for this network.

        [API documentation: getNetworkWirelessLatencyStats](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-latency-stats)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 180 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 7 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 7 days.
            band: Filter results by band (either '2.4', '5' or '6'). Note that data prior to
                February 2020 will not have band information.
            ssid: Filter results by SSID.
            ap_tag: Filter results by AP Tag.
            vlan: Filter results by VLAN.
            fields: Partial selection: If present, this call will return only the selected fields of
                ["rawDistribution", "avg"]. All fields will be returned by default.
                Selected fields must be entered as a comma separated string.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "backgroundTraffic": {
                "rawDistribution": {
                  "0": 1234,
                  "1": 2345,
                  "2": 3456,
                  "4": 4567,
                  "8": 5678,
                  "16": 6789,
                  "32": 7890,
                  "64": 8901,
                  "128": 9012,
                  "256": 83,
                  "512": 1234,
                  "1024": 2345,
                  "2048": 9999
                },
                "avg": 606.52
              },
              "bestEffortTraffic": "same shape as backgroundTraffic",
              "videoTraffic": "same shape as backgroundTraffic",
              "voiceTraffic": "same shape as backgroundTraffic"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/latencyStats"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if vlan is not None:
            params["vlan"] = vlan
        if fields is not None:
            params["fields"] = fields

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessLatencyStats",
            path=path,
            params=params,
            response_schema=DictResponse,
        )

    async def update_network_wireless_location_scanning(
        self,
        network_id: str,
        *,
        enabled: bool | None = None,
        api: UpdateNetworkWirelessLocationScanningApi | None = None,
    ) -> UpdateNetworkWirelessLocationScanningResponse:
        """Change scanning API settings.

        [API documentation: updateNetworkWirelessLocationScanning](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-location-scanning)

        Args:
            network_id: Network ID.
            enabled: Collect location and scanning analytics.
            api: Enable push API for scanning events, analytics must be enabled.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "api": {
                "enabled": true,
                "validator": {
                  "string": "sample_validator"
                }
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/location/scanning"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if api is not None:
            payload["api"] = api.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessLocationScanning",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessLocationScanningResponse,
        )

    def get_network_wireless_mesh_statuses(
        self,
        network_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetNetworkWirelessMeshStatusesResponseItem]:
        """List wireless mesh statuses for repeaters.

        [API documentation: getNetworkWirelessMeshStatuses](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-mesh-statuses)

        Args:
            network_id: Network ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 500. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "serial": "Q234-ABCD-5678",
                "meshRoute": [
                  "Q234-ABCD-5678",
                  "QWEY-SKTD-ST01",
                  "QWEY-SKTD-ST02"
                ],
                "latestMeshPerformance": {
                  "mbps": 43,
                  "metric": 12345,
                  "usagePercentage": "100%"
                }
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/meshStatuses"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessMeshStatuses",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkWirelessMeshStatusesResponseItem,
        )

    async def update_network_wireless_radio_rrm(
        self,
        network_id: str,
        *,
        busy_hour: UpdateNetworkWirelessRadioRrmBusyHour | None = None,
        channel: UpdateNetworkWirelessRadioRrmChannel | None = None,
        fra: UpdateNetworkWirelessRadioRrmFra | None = None,
        ai: UpdateNetworkWirelessRadioRrmAi | None = None,
    ) -> UpdateNetworkWirelessRadioRrmResponse:
        """Update the AutoRF settings for a wireless network.

        [API documentation: updateNetworkWirelessRadioRrm](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-radio-rrm)

        Args:
            network_id: Network ID.
            busy_hour: Busy Hour settings.
            channel: Channel settings.
            fra: FRA settings.
            ai: AI settings.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "networkId": "L_12345",
              "name": "My Network",
              "timeZone": "America/Los_Angeles",
              "busyHour": {
                "schedule": {
                  "mode": "automatic",
                  "automatic": {
                    "start": "08:00",
                    "end": "17:00"
                  },
                  "manual": {
                    "start": "10:00",
                    "end": "15:00"
                  }
                },
                "minimizeChanges": {
                  "enabled": true
                }
              },
              "channel": {
                "avoidance": {
                  "enabled": true
                }
              },
              "fra": {
                "enabled": false
              },
              "ai": {
                "enabled": true,
                "lastEnabledAt": "2026-01-04T09:07:45Z"
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/radio/rrm"

        payload: dict[str, Any] = {}
        if busy_hour is not None:
            payload["busyHour"] = busy_hour.model_dump(by_alias=True, exclude_none=True)
        if channel is not None:
            payload["channel"] = channel.model_dump(by_alias=True, exclude_none=True)
        if fra is not None:
            payload["fra"] = fra.model_dump(by_alias=True, exclude_none=True)
        if ai is not None:
            payload["ai"] = ai.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessRadioRrm",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessRadioRrmResponse,
        )

    def get_network_wireless_rf_profiles(
        self, network_id: str, *, include_template_profiles: bool | None = None
    ) -> AsyncPaginatedResponse[GetNetworkWirelessRfProfilesResponse]:
        """List RF profiles for this network.

        [API documentation: getNetworkWirelessRfProfiles](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-rf-profiles)

        Args:
            network_id: Network ID.
            include_template_profiles: If the network is bound to a template, this parameter
                controls whether or not the non-basic RF profiles defined on the
                template should be included in the response alongside the non-basic
                profiles defined on the bound network. Defaults to false.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "id": "1234",
              "networkId": "N_24329156",
              "name": "Main Office",
              "clientBalancingEnabled": true,
              "minBitrateType": "band",
              "bandSelectionType": "ap",
              "apBandSettings": {
                "bandOperationMode": "dual",
                "bands": {
                  "enabled": [
                    "2.4",
                    "5"
                  ]
                },
                "bandSteeringEnabled": true
              },
              "twoFourGhzSettings": {
                "maxPower": 30,
                "minPower": 5,
                "minBitrate": 11.0,
                "validAutoChannels": [
                  1,
                  6,
                  11
                ],
                "axEnabled": true,
                "rxsop": -95
              },
              "fiveGhzSettings": {
                "maxPower": 30,
                "minPower": 8,
                "minBitrate": 12,
                "validAutoChannels": [
                  36,
                  40,
                  44,
                  48,
                  52,
                  56,
                  60,
                  64,
                  100,
                  104,
                  108,
                  112,
                  116,
                  120,
                  124,
                  128,
                  132,
                  136,
                  140,
                  144,
                  149,
                  153,
                  157,
                  161,
                  165
                ],
                "channelWidth": "auto",
                "rxsop": -95
              },
              "sixGhzSettings": {
                "maxPower": 30,
                "minPower": 8,
                "minBitrate": 12,
                "validAutoChannels": [
                  1,
                  5,
                  9,
                  13,
                  17,
                  21,
                  25,
                  29,
                  33,
                  37,
                  41,
                  45,
                  49,
                  53,
                  57,
                  61,
                  65,
                  69,
                  73,
                  77,
                  81,
                  85,
                  89,
                  93,
                  97,
                  101,
                  105,
                  109,
                  113,
                  117,
                  121,
                  125,
                  129,
                  133,
                  137,
                  141,
                  145,
                  149,
                  153,
                  157,
                  161,
                  165,
                  169,
                  173,
                  177,
                  181,
                  185,
                  189,
                  193,
                  197,
                  201,
                  205,
                  209,
                  213,
                  217,
                  221,
                  225,
                  229,
                  233
                ],
                "channelWidth": "auto",
                "rxsop": -95
              },
              "transmission": {
                "enabled": true
              },
              "perSsidSettings": {
                "0": {
                  "name": "SSID 0",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "1": {
                  "name": "SSID 1",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "2": {
                  "name": "SSID 2",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "3": {
                  "name": "SSID 3",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "4": {
                  "name": "SSID 4",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "5": {
                  "name": "SSID 5",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "6": {
                  "name": "SSID 6",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "7": {
                  "name": "SSID 7",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "8": {
                  "name": "SSID 8",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "9": {
                  "name": "SSID 9",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "10": {
                  "name": "SSID 10",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "11": {
                  "name": "SSID 11",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "12": {
                  "name": "SSID 12",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "13": {
                  "name": "SSID 13",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "14": {
                  "name": "SSID 14",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                }
              },
              "isIndoorDefault": false,
              "isOutdoorDefault": false
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/rfProfiles"

        params: dict[str, Any] = {}
        if include_template_profiles is not None:
            params["includeTemplateProfiles"] = include_template_profiles

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessRfProfiles",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessRfProfilesResponse,
        )

    async def create_network_wireless_rf_profile(
        self,
        *,
        network_id: str,
        name: str,
        band_selection_type: CreateNetworkWirelessRfProfileBandSelectionType,
        client_balancing_enabled: bool | None = None,
        min_bitrate_type: CreateNetworkWirelessRfProfileMinBitrateType | None = None,
        ap_band_settings: CreateNetworkWirelessRfProfileApBandSettings | None = None,
        two_four_ghz_settings: CreateNetworkWirelessRfProfileTwoFourGhzSettings | None = None,
        five_ghz_settings: CreateNetworkWirelessRfProfileFiveGhzSettings | None = None,
        six_ghz_settings: CreateNetworkWirelessRfProfileSixGhzSettings | None = None,
        transmission: CreateNetworkWirelessRfProfileTransmission | None = None,
        per_ssid_settings: CreateNetworkWirelessRfProfilePerSsidSettings | None = None,
        flex_radios: CreateNetworkWirelessRfProfileFlexRadios | None = None,
    ) -> CreateNetworkWirelessRfProfileResponse:
        """Creates new RF profile for this network.

        [API documentation: createNetworkWirelessRfProfile](https://developer.cisco.com/meraki/api-v1/#!create-network-wireless-rf-profile)

        Args:
            network_id: Network ID.
            name: The name of the new profile. Must be unique. This param is required on creation.
            client_balancing_enabled: Steers client to best available access point. Can be either
                true or false. Defaults to true.
            min_bitrate_type: Minimum bitrate can be set to either 'band' or 'ssid'. Defaults to
                band.
            band_selection_type: Band selection can be set to either 'ssid' or 'ap'. This param is
                required on creation.
            ap_band_settings: Settings that will be enabled if selectionType is set to 'ap'.
            two_four_ghz_settings: Settings related to 2.4Ghz band.
            five_ghz_settings: Settings related to 5Ghz band.
            six_ghz_settings: Settings related to 6Ghz band. Only applicable to networks with 6Ghz
                capable APs.
            transmission: Settings related to radio transmission.
            per_ssid_settings: Per-SSID radio settings by number.
            flex_radios: Flex radio settings.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "networkId": "N_24329156",
              "name": "Main Office",
              "clientBalancingEnabled": true,
              "minBitrateType": "band",
              "bandSelectionType": "ap",
              "apBandSettings": {
                "bandOperationMode": "dual",
                "bands": {
                  "enabled": [
                    "2.4",
                    "5"
                  ]
                },
                "bandSteeringEnabled": true
              },
              "twoFourGhzSettings": {
                "maxPower": 30,
                "minPower": 5,
                "minBitrate": 11.0,
                "validAutoChannels": [
                  1,
                  6,
                  11
                ],
                "axEnabled": true,
                "rxsop": -95
              },
              "fiveGhzSettings": {
                "maxPower": 30,
                "minPower": 8,
                "minBitrate": 12,
                "validAutoChannels": [
                  36,
                  40,
                  44,
                  48,
                  52,
                  56,
                  60,
                  64,
                  100,
                  104,
                  108,
                  112,
                  116,
                  120,
                  124,
                  128,
                  132,
                  136,
                  140,
                  144,
                  149,
                  153,
                  157,
                  161,
                  165
                ],
                "channelWidth": "auto",
                "rxsop": -95
              },
              "sixGhzSettings": {
                "maxPower": 30,
                "minPower": 8,
                "minBitrate": 12,
                "validAutoChannels": [
                  1,
                  5,
                  9,
                  13,
                  17,
                  21,
                  25,
                  29,
                  33,
                  37,
                  41,
                  45,
                  49,
                  53,
                  57,
                  61,
                  65,
                  69,
                  73,
                  77,
                  81,
                  85,
                  89,
                  93,
                  97,
                  101,
                  105,
                  109,
                  113,
                  117,
                  121,
                  125,
                  129,
                  133,
                  137,
                  141,
                  145,
                  149,
                  153,
                  157,
                  161,
                  165,
                  169,
                  173,
                  177,
                  181,
                  185,
                  189,
                  193,
                  197,
                  201,
                  205,
                  209,
                  213,
                  217,
                  221,
                  225,
                  229,
                  233
                ],
                "channelWidth": "auto",
                "rxsop": -95
              },
              "transmission": {
                "enabled": true
              },
              "perSsidSettings": {
                "0": {
                  "name": "SSID 0",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "1": {
                  "name": "SSID 1",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "2": {
                  "name": "SSID 2",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "3": {
                  "name": "SSID 3",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "4": {
                  "name": "SSID 4",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "5": {
                  "name": "SSID 5",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "6": {
                  "name": "SSID 6",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "7": {
                  "name": "SSID 7",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "8": {
                  "name": "SSID 8",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "9": {
                  "name": "SSID 9",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "10": {
                  "name": "SSID 10",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "11": {
                  "name": "SSID 11",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "12": {
                  "name": "SSID 12",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "13": {
                  "name": "SSID 13",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "14": {
                  "name": "SSID 14",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                }
              },
              "isIndoorDefault": false,
              "isOutdoorDefault": false
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/rfProfiles"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if client_balancing_enabled is not None:
            payload["clientBalancingEnabled"] = client_balancing_enabled
        if min_bitrate_type is not None:
            payload["minBitrateType"] = min_bitrate_type
        if band_selection_type is not None:
            payload["bandSelectionType"] = band_selection_type
        if ap_band_settings is not None:
            payload["apBandSettings"] = ap_band_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if two_four_ghz_settings is not None:
            payload["twoFourGhzSettings"] = two_four_ghz_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if five_ghz_settings is not None:
            payload["fiveGhzSettings"] = five_ghz_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if six_ghz_settings is not None:
            payload["sixGhzSettings"] = six_ghz_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if transmission is not None:
            payload["transmission"] = transmission.model_dump(by_alias=True, exclude_none=True)
        if per_ssid_settings is not None:
            payload["perSsidSettings"] = per_ssid_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if flex_radios is not None:
            payload["flexRadios"] = flex_radios.model_dump(by_alias=True, exclude_none=True)

        return await self._session.post(
            scope="wireless",
            operation_id="createNetworkWirelessRfProfile",
            path=path,
            json=payload,
            response_schema=CreateNetworkWirelessRfProfileResponse,
        )

    async def get_network_wireless_rf_profile(
        self, *, network_id: str, rf_profile_id: str
    ) -> GetNetworkWirelessRfProfileResponse:
        """Return a RF profile.

        [API documentation: getNetworkWirelessRfProfile](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-rf-profile)

        Args:
            network_id: Network ID.
            rf_profile_id: Rf profile ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "networkId": "N_24329156",
              "name": "Main Office",
              "clientBalancingEnabled": true,
              "minBitrateType": "band",
              "bandSelectionType": "ap",
              "apBandSettings": {
                "bandOperationMode": "dual",
                "bands": {
                  "enabled": [
                    "2.4",
                    "5"
                  ]
                },
                "bandSteeringEnabled": true
              },
              "twoFourGhzSettings": {
                "maxPower": 30,
                "minPower": 5,
                "minBitrate": 11.0,
                "validAutoChannels": [
                  1,
                  6,
                  11
                ],
                "axEnabled": true,
                "rxsop": -95
              },
              "fiveGhzSettings": {
                "maxPower": 30,
                "minPower": 8,
                "minBitrate": 12,
                "validAutoChannels": [
                  36,
                  40,
                  44,
                  48,
                  52,
                  56,
                  60,
                  64,
                  100,
                  104,
                  108,
                  112,
                  116,
                  120,
                  124,
                  128,
                  132,
                  136,
                  140,
                  144,
                  149,
                  153,
                  157,
                  161,
                  165
                ],
                "channelWidth": "auto",
                "rxsop": -95
              },
              "sixGhzSettings": {
                "maxPower": 30,
                "minPower": 8,
                "minBitrate": 12,
                "validAutoChannels": [
                  1,
                  5,
                  9,
                  13,
                  17,
                  21,
                  25,
                  29,
                  33,
                  37,
                  41,
                  45,
                  49,
                  53,
                  57,
                  61,
                  65,
                  69,
                  73,
                  77,
                  81,
                  85,
                  89,
                  93,
                  97,
                  101,
                  105,
                  109,
                  113,
                  117,
                  121,
                  125,
                  129,
                  133,
                  137,
                  141,
                  145,
                  149,
                  153,
                  157,
                  161,
                  165,
                  169,
                  173,
                  177,
                  181,
                  185,
                  189,
                  193,
                  197,
                  201,
                  205,
                  209,
                  213,
                  217,
                  221,
                  225,
                  229,
                  233
                ],
                "channelWidth": "auto",
                "rxsop": -95
              },
              "transmission": {
                "enabled": true
              },
              "perSsidSettings": {
                "0": {
                  "name": "SSID 0",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "1": {
                  "name": "SSID 1",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "2": {
                  "name": "SSID 2",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "3": {
                  "name": "SSID 3",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "4": {
                  "name": "SSID 4",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "5": {
                  "name": "SSID 5",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "6": {
                  "name": "SSID 6",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "7": {
                  "name": "SSID 7",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "8": {
                  "name": "SSID 8",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "9": {
                  "name": "SSID 9",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "10": {
                  "name": "SSID 10",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "11": {
                  "name": "SSID 11",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "12": {
                  "name": "SSID 12",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "13": {
                  "name": "SSID 13",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "14": {
                  "name": "SSID 14",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                }
              },
              "isIndoorDefault": false,
              "isOutdoorDefault": false
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        rf_profile_id = urllib.parse.quote(str(rf_profile_id), safe="")
        path = f"/networks/{network_id}/wireless/rfProfiles/{rf_profile_id}"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessRfProfile",
            path=path,
            response_schema=GetNetworkWirelessRfProfileResponse,
        )

    async def update_network_wireless_rf_profile(
        self,
        *,
        network_id: str,
        rf_profile_id: str,
        name: str | None = None,
        is_indoor_default: bool | None = None,
        is_outdoor_default: bool | None = None,
        client_balancing_enabled: bool | None = None,
        min_bitrate_type: UpdateNetworkWirelessRfProfileMinBitrateType | None = None,
        band_selection_type: UpdateNetworkWirelessRfProfileBandSelectionType | None = None,
        ap_band_settings: UpdateNetworkWirelessRfProfileApBandSettings | None = None,
        two_four_ghz_settings: UpdateNetworkWirelessRfProfileTwoFourGhzSettings | None = None,
        five_ghz_settings: UpdateNetworkWirelessRfProfileFiveGhzSettings | None = None,
        six_ghz_settings: UpdateNetworkWirelessRfProfileSixGhzSettings | None = None,
        transmission: UpdateNetworkWirelessRfProfileTransmission | None = None,
        per_ssid_settings: UpdateNetworkWirelessRfProfilePerSsidSettings | None = None,
        flex_radios: UpdateNetworkWirelessRfProfileFlexRadios | None = None,
    ) -> UpdateNetworkWirelessRfProfileResponse:
        """Updates specified RF profile for this network.

        [API documentation: updateNetworkWirelessRfProfile](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-rf-profile)

        Args:
            network_id: Network ID.
            rf_profile_id: Rf profile ID.
            name: The name of the new profile. Must be unique.
            is_indoor_default: Set this profile as the default indoor rf profile. If the profile ID
                is one of 'indoor' or 'outdoor', then a new profile will be created from
                the respective ID and set as the default.
            is_outdoor_default: Set this profile as the default outdoor rf profile. If the profile
                ID is one of 'indoor' or 'outdoor', then a new profile will be created
                from the respective ID and set as the default.
            client_balancing_enabled: Steers client to best available access point. Can be either
                true or false.
            min_bitrate_type: Minimum bitrate can be set to either 'band' or 'ssid'.
            band_selection_type: Band selection can be set to either 'ssid' or 'ap'.
            ap_band_settings: Settings that will be enabled if selectionType is set to 'ap'.
            two_four_ghz_settings: Settings related to 2.4Ghz band.
            five_ghz_settings: Settings related to 5Ghz band.
            six_ghz_settings: Settings related to 6Ghz band. Only applicable to networks with 6Ghz
                capable APs.
            transmission: Settings related to radio transmission.
            per_ssid_settings: Per-SSID radio settings by number.
            flex_radios: Flex radio settings.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "networkId": "N_24329156",
              "name": "Main Office",
              "clientBalancingEnabled": true,
              "minBitrateType": "band",
              "bandSelectionType": "ap",
              "apBandSettings": {
                "bandOperationMode": "dual",
                "bands": {
                  "enabled": [
                    "2.4",
                    "5"
                  ]
                },
                "bandSteeringEnabled": true
              },
              "twoFourGhzSettings": {
                "maxPower": 30,
                "minPower": 5,
                "minBitrate": 11.0,
                "validAutoChannels": [
                  1,
                  6,
                  11
                ],
                "axEnabled": true,
                "rxsop": -95
              },
              "fiveGhzSettings": {
                "maxPower": 30,
                "minPower": 8,
                "minBitrate": 12,
                "validAutoChannels": [
                  36,
                  40,
                  44,
                  48,
                  52,
                  56,
                  60,
                  64,
                  100,
                  104,
                  108,
                  112,
                  116,
                  120,
                  124,
                  128,
                  132,
                  136,
                  140,
                  144,
                  149,
                  153,
                  157,
                  161,
                  165
                ],
                "channelWidth": "auto",
                "rxsop": -95
              },
              "sixGhzSettings": {
                "maxPower": 30,
                "minPower": 8,
                "minBitrate": 12,
                "validAutoChannels": [
                  1,
                  5,
                  9,
                  13,
                  17,
                  21,
                  25,
                  29,
                  33,
                  37,
                  41,
                  45,
                  49,
                  53,
                  57,
                  61,
                  65,
                  69,
                  73,
                  77,
                  81,
                  85,
                  89,
                  93,
                  97,
                  101,
                  105,
                  109,
                  113,
                  117,
                  121,
                  125,
                  129,
                  133,
                  137,
                  141,
                  145,
                  149,
                  153,
                  157,
                  161,
                  165,
                  169,
                  173,
                  177,
                  181,
                  185,
                  189,
                  193,
                  197,
                  201,
                  205,
                  209,
                  213,
                  217,
                  221,
                  225,
                  229,
                  233
                ],
                "channelWidth": "auto",
                "rxsop": -95
              },
              "transmission": {
                "enabled": true
              },
              "perSsidSettings": {
                "0": {
                  "name": "SSID 0",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "1": {
                  "name": "SSID 1",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "2": {
                  "name": "SSID 2",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "3": {
                  "name": "SSID 3",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "4": {
                  "name": "SSID 4",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "5": {
                  "name": "SSID 5",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "6": {
                  "name": "SSID 6",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "7": {
                  "name": "SSID 7",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "8": {
                  "name": "SSID 8",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "9": {
                  "name": "SSID 9",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "10": {
                  "name": "SSID 10",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "11": {
                  "name": "SSID 11",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "12": {
                  "name": "SSID 12",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "13": {
                  "name": "SSID 13",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                },
                "14": {
                  "name": "SSID 14",
                  "minBitrate": 11,
                  "bandOperationMode": "dual",
                  "bands": {
                    "enabled": [
                      "2.4",
                      "5"
                    ]
                  },
                  "bandSteeringEnabled": true
                }
              },
              "isIndoorDefault": false,
              "isOutdoorDefault": false
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        rf_profile_id = urllib.parse.quote(str(rf_profile_id), safe="")
        path = f"/networks/{network_id}/wireless/rfProfiles/{rf_profile_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if is_indoor_default is not None:
            payload["isIndoorDefault"] = is_indoor_default
        if is_outdoor_default is not None:
            payload["isOutdoorDefault"] = is_outdoor_default
        if client_balancing_enabled is not None:
            payload["clientBalancingEnabled"] = client_balancing_enabled
        if min_bitrate_type is not None:
            payload["minBitrateType"] = min_bitrate_type
        if band_selection_type is not None:
            payload["bandSelectionType"] = band_selection_type
        if ap_band_settings is not None:
            payload["apBandSettings"] = ap_band_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if two_four_ghz_settings is not None:
            payload["twoFourGhzSettings"] = two_four_ghz_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if five_ghz_settings is not None:
            payload["fiveGhzSettings"] = five_ghz_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if six_ghz_settings is not None:
            payload["sixGhzSettings"] = six_ghz_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if transmission is not None:
            payload["transmission"] = transmission.model_dump(by_alias=True, exclude_none=True)
        if per_ssid_settings is not None:
            payload["perSsidSettings"] = per_ssid_settings.model_dump(
                by_alias=True, exclude_none=True
            )
        if flex_radios is not None:
            payload["flexRadios"] = flex_radios.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessRfProfile",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessRfProfileResponse,
        )

    async def delete_network_wireless_rf_profile(
        self, *, network_id: str, rf_profile_id: str
    ) -> None:
        """Delete a RF Profile.

        [API documentation: deleteNetworkWirelessRfProfile](https://developer.cisco.com/meraki/api-v1/#!delete-network-wireless-rf-profile)

        Args:
            network_id: Network ID.
            rf_profile_id: Rf profile ID.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        rf_profile_id = urllib.parse.quote(str(rf_profile_id), safe="")
        path = f"/networks/{network_id}/wireless/rfProfiles/{rf_profile_id}"

        return await self._session.delete(
            scope="wireless", operation_id="deleteNetworkWirelessRfProfile", path=path
        )

    async def get_network_wireless_settings(
        self, network_id: str
    ) -> GetNetworkWirelessSettingsResponse:
        """Return the wireless settings for a network.

        [API documentation: getNetworkWirelessSettings](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-settings)

        Args:
            network_id: Network ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "meshingEnabled": true,
              "ipv6BridgeEnabled": false,
              "locationAnalyticsEnabled": false,
              "upgradeStrategy": "minimizeUpgradeTime",
              "ledLightsOn": false,
              "multicastToUnicastConversion": {
                "enabled": true
              },
              "namedVlans": {
                "poolDhcpMonitoring": {
                  "enabled": true,
                  "duration": 5
                }
              },
              "regulatoryDomain": {
                "name": "FCC",
                "countryCode": "US",
                "permits6e": true
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/settings"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSettings",
            path=path,
            response_schema=GetNetworkWirelessSettingsResponse,
        )

    async def update_network_wireless_settings(
        self,
        network_id: str,
        *,
        meshing_enabled: bool | None = None,
        ipv6_bridge_enabled: bool | None = None,
        location_analytics_enabled: bool | None = None,
        upgrade_strategy: UpdateNetworkWirelessSettingsUpgradeStrategy | None = None,
        led_lights_on: bool | None = None,
        multicast_to_unicast_conversion: UpdateNetworkWirelessSettingsMulticastToUnicastConversion
        | None = None,
        named_vlans: UpdateNetworkWirelessSettingsNamedVlans | None = None,
    ) -> UpdateNetworkWirelessSettingsResponse:
        """Update the wireless settings for a network.

        [API documentation: updateNetworkWirelessSettings](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-settings)

        Args:
            network_id: Network ID.
            meshing_enabled: Toggle for enabling or disabling meshing in a network.
            ipv6_bridge_enabled: Toggle for enabling or disabling IPv6 bridging in a network (Note:
                if enabled, SSIDs must also be configured to use bridge mode).
            location_analytics_enabled: Toggle for enabling or disabling location analytics for your
                network.
            upgrade_strategy: The default strategy that network devices will use to perform an
                upgrade. Requires firmware version MR 26.8 or higher.
            led_lights_on: Toggle for enabling or disabling LED lights on all APs in the network
                (making them run dark).
            multicast_to_unicast_conversion: Multicast-to-unicast conversion settings across the
                network.
            named_vlans: Named VLAN settings for wireless networks.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "meshingEnabled": true,
              "ipv6BridgeEnabled": false,
              "locationAnalyticsEnabled": false,
              "upgradeStrategy": "minimizeUpgradeTime",
              "ledLightsOn": false,
              "multicastToUnicastConversion": {
                "enabled": true
              },
              "namedVlans": {
                "poolDhcpMonitoring": {
                  "enabled": true,
                  "duration": 5
                }
              },
              "regulatoryDomain": {
                "name": "FCC",
                "countryCode": "US",
                "permits6e": true
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/settings"

        payload: dict[str, Any] = {}
        if meshing_enabled is not None:
            payload["meshingEnabled"] = meshing_enabled
        if ipv6_bridge_enabled is not None:
            payload["ipv6BridgeEnabled"] = ipv6_bridge_enabled
        if location_analytics_enabled is not None:
            payload["locationAnalyticsEnabled"] = location_analytics_enabled
        if upgrade_strategy is not None:
            payload["upgradeStrategy"] = upgrade_strategy
        if led_lights_on is not None:
            payload["ledLightsOn"] = led_lights_on
        if multicast_to_unicast_conversion is not None:
            payload["multicastToUnicastConversion"] = multicast_to_unicast_conversion.model_dump(
                by_alias=True, exclude_none=True
            )
        if named_vlans is not None:
            payload["namedVlans"] = named_vlans.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSettings",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSettingsResponse,
        )

    def get_network_wireless_signal_quality_history(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        resolution: int | None = None,
        auto_resolution: bool | None = None,
        client_id: str | None = None,
        device_serial: str | None = None,
        ap_tag: str | None = None,
        band: GetNetworkWirelessSignalQualityHistoryBand | None = None,
        ssid: int | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessSignalQualityHistoryResponseItem]:
        """Return signal quality (SNR/RSSI) over time for a device or network client.

        [API documentation: getNetworkWirelessSignalQualityHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-signal-quality-history)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 7 days.
            resolution: The time resolution in seconds for returned data. The valid resolutions are:
                300, 600, 1200, 3600, 14400, 86400. The default is 86400.
            auto_resolution: Automatically select a data resolution based on the given timespan;
                this overrides the value specified by the 'resolution' parameter. The
                default setting is false.
            client_id: Filter results by network client.
            device_serial: Filter results by device.
            ap_tag: Filter results by AP tag; either :clientId or :deviceSerial must be jointly
                specified.
            band: Filter results by band (either '2.4', '5' or '6').
            ssid: Filter results by SSID number.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2020-01-01T00:00:00Z",
                "endTs": "2020-01-01T01:00:00Z",
                "snr": 27,
                "rssi": -77
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/signalQualityHistory"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if resolution is not None:
            params["resolution"] = resolution
        if auto_resolution is not None:
            params["autoResolution"] = auto_resolution
        if client_id is not None:
            params["clientId"] = client_id
        if device_serial is not None:
            params["deviceSerial"] = device_serial
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessSignalQualityHistory",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessSignalQualityHistoryResponseItem,
        )

    def get_network_wireless_ssids(
        self, network_id: str
    ) -> AsyncPaginatedResponse[GetNetworkWirelessSsidsResponseItem]:
        r"""List the MR SSIDs in a network.

        [API documentation: getNetworkWirelessSsids](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssids)

        Args:
            network_id: Network ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "number": 0,
                "name": "My SSID",
                "enabled": true,
                "splashPage": "Click-through splash page",
                "ssidAdminAccessible": false,
                "localAuth": false,
                "authMode": "8021x-radius",
                "encryptionMode": "wpa",
                "wpaEncryptionMode": "WPA2 only",
                "radiusServers": [
                  {
                    "host": "0.0.0.0",
                    "port": 3000,
                    "openRoamingCertificateId": 2,
                    "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
                  }
                ],
                "radiusAccountingServers": [
                  {
                    "host": "0.0.0.0",
                    "port": 3000,
                    "openRoamingCertificateId": 2,
                    "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
                  }
                ],
                "radiusAccountingEnabled": false,
                "radiusEnabled": true,
                "radiusAttributeForGroupPolicies": "Filter-Id",
                "radiusFailoverPolicy": "Deny access",
                "radiusLoadBalancingPolicy": "Round robin",
                "ipAssignmentMode": "NAT mode",
                "adminSplashUrl": "http://example.com",
                "splashTimeout": "30 minutes",
                "walledGardenEnabled": true,
                "walledGardenRanges": [
                  "example.com",
                  "1.1.1.1/32"
                ],
                "minBitrate": 11,
                "bandSelection": "5 GHz band only",
                "perClientBandwidthLimitUp": 0,
                "perClientBandwidthLimitDown": 0,
                "visible": true,
                "availableOnAllAps": false,
                "availabilityTags": [
                  "tag1",
                  "tag2"
                ],
                "perSsidBandwidthLimitUp": 0,
                "perSsidBandwidthLimitDown": 0,
                "mandatoryDhcpEnabled": false
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/ssids"

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessSsids",
            path=path,
            item_schema=GetNetworkWirelessSsidsResponseItem,
        )

    async def get_network_wireless_ssid(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidResponse:
        r"""Return a single MR SSID.

        [API documentation: getNetworkWirelessSsid](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "number": 0,
              "name": "My SSID",
              "enabled": true,
              "splashPage": "Click-through splash page",
              "ssidAdminAccessible": false,
              "localAuth": false,
              "authMode": "8021x-radius",
              "encryptionMode": "wpa",
              "wpaEncryptionMode": "WPA2 only",
              "radiusServers": [
                {
                  "host": "0.0.0.0",
                  "port": 3000,
                  "openRoamingCertificateId": 2,
                  "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
                }
              ],
              "radiusAccountingServers": [
                {
                  "host": "0.0.0.0",
                  "port": 3000,
                  "openRoamingCertificateId": 2,
                  "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
                }
              ],
              "radiusAccountingEnabled": false,
              "radiusEnabled": true,
              "radiusAttributeForGroupPolicies": "Filter-Id",
              "radiusFailoverPolicy": "Deny access",
              "radiusLoadBalancingPolicy": "Round robin",
              "ipAssignmentMode": "NAT mode",
              "adminSplashUrl": "http://example.com",
              "splashTimeout": "30 minutes",
              "walledGardenEnabled": true,
              "walledGardenRanges": [
                "example.com",
                "1.1.1.1/32"
              ],
              "minBitrate": 11,
              "bandSelection": "5 GHz band only",
              "perClientBandwidthLimitUp": 0,
              "perClientBandwidthLimitDown": 0,
              "visible": true,
              "availableOnAllAps": false,
              "availabilityTags": [
                "tag1",
                "tag2"
              ],
              "perSsidBandwidthLimitUp": 0,
              "perSsidBandwidthLimitDown": 0,
              "mandatoryDhcpEnabled": false
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsid",
            path=path,
            response_schema=GetNetworkWirelessSsidResponse,
        )

    async def update_network_wireless_ssid(
        self,
        *,
        network_id: str,
        number: str,
        name: str | None = None,
        enabled: bool | None = None,
        auth_mode: UpdateNetworkWirelessSsidAuthMode | None = None,
        enterprise_admin_access: UpdateNetworkWirelessSsidEnterpriseAdminAccess | None = None,
        encryption_mode: UpdateNetworkWirelessSsidEncryptionMode | None = None,
        psk: str | None = None,
        wpa_encryption_mode: UpdateNetworkWirelessSsidWpaEncryptionMode | None = None,
        dot11w: UpdateNetworkWirelessSsidDot11w | None = None,
        dot11r: UpdateNetworkWirelessSsidDot11r | None = None,
        splash_page: UpdateNetworkWirelessSsidSplashPage | None = None,
        splash_guest_sponsor_domains: list[str] | None = None,
        oauth: UpdateNetworkWirelessSsidOauth | None = None,
        local_radius: UpdateNetworkWirelessSsidLocalRadius | None = None,
        ldap: UpdateNetworkWirelessSsidLdap | None = None,
        active_directory: UpdateNetworkWirelessSsidActiveDirectory | None = None,
        radius_servers: list[UpdateNetworkWirelessSsidRadiusServersItem] | None = None,
        radius_proxy_enabled: bool | None = None,
        radius_testing_enabled: bool | None = None,
        radius_called_station_id: str | None = None,
        radius_authentication_nas_id: str | None = None,
        radius_server_timeout: int | None = None,
        radius_server_attempts_limit: int | None = None,
        radius_fallback_enabled: bool | None = None,
        radius_radsec: UpdateNetworkWirelessSsidRadiusRadsec | None = None,
        radius_coa_enabled: bool | None = None,
        radius_failover_policy: UpdateNetworkWirelessSsidRadiusFailoverPolicy | None = None,
        radius_load_balancing_policy: UpdateNetworkWirelessSsidRadiusLoadBalancingPolicy
        | None = None,
        radius_accounting_enabled: bool | None = None,
        radius_accounting_servers: list[UpdateNetworkWirelessSsidRadiusAccountingServersItem]
        | None = None,
        radius_accounting_interim_interval: int | None = None,
        radius_attribute_for_group_policies: UpdateNetworkWirelessSsidRadiusAttributeForGroupPolicies
        | None = None,
        ip_assignment_mode: str | None = None,
        use_vlan_tagging: bool | None = None,
        concentrator_network_id: str | None = None,
        secondary_concentrator_network_id: str | None = None,
        disassociate_clients_on_vpn_failover: bool | None = None,
        vlan_id: int | None = None,
        default_vlan_id: int | None = None,
        ap_tags_and_vlan_ids: list[UpdateNetworkWirelessSsidApTagsAndVlanIdsItem] | None = None,
        walled_garden_enabled: bool | None = None,
        walled_garden_ranges: list[str] | None = None,
        gre: UpdateNetworkWirelessSsidGre | None = None,
        radius_override: bool | None = None,
        radius_guest_vlan_enabled: bool | None = None,
        radius_guest_vlan_id: int | None = None,
        min_bitrate: float | None = None,
        band_selection: str | None = None,
        per_client_bandwidth_limit_up: int | None = None,
        per_client_bandwidth_limit_down: int | None = None,
        per_ssid_bandwidth_limit_up: int | None = None,
        per_ssid_bandwidth_limit_down: int | None = None,
        lan_isolation_enabled: bool | None = None,
        visible: bool | None = None,
        available_on_all_aps: bool | None = None,
        availability_tags: list[str] | None = None,
        adaptive_policy_group_id: str | None = None,
        mandatory_dhcp_enabled: bool | None = None,
        adult_content_filtering_enabled: bool | None = None,
        dns_rewrite: UpdateNetworkWirelessSsidDnsRewrite | None = None,
        speed_burst: UpdateNetworkWirelessSsidSpeedBurst | None = None,
        named_vlans: UpdateNetworkWirelessSsidNamedVlans | None = None,
        local_auth_fallback: UpdateNetworkWirelessSsidLocalAuthFallback | None = None,
        radius_accounting_start_delay: int | None = None,
    ) -> UpdateNetworkWirelessSsidResponse:
        r"""Update the attributes of an MR SSID.

        [API documentation: updateNetworkWirelessSsid](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid)

        Args:
            network_id: Network ID.
            number: Number.
            name: The name of the SSID.
            enabled: Whether or not the SSID is enabled.
            auth_mode: The association control method for the SSID ('open', 'open-enhanced', 'psk',
                'open-with-radius', 'open-with-nac', '8021x-meraki', '8021x-nac',
                '8021x-radius', '8021x-google', '8021x-entra', '8021x-localradius',
                'ipsk-with-radius', 'ipsk-without-radius', 'ipsk-with-nac' or 'ipsk-
                with-radius-easy-psk').
            enterprise_admin_access: Whether or not an SSID is accessible by 'enterprise'
                administrators ('access disabled' or 'access enabled').
            encryption_mode: The psk encryption mode for the SSID ('wep' or 'wpa'). This param is
                only valid if the authMode is 'psk'.
            psk: The passkey for the SSID. This param is only valid if the authMode is 'psk'.
            wpa_encryption_mode: The types of WPA encryption. ('WPA1 only', 'WPA1 and WPA2', 'WPA2
                only', 'WPA3 Transition Mode', 'WPA3 only' or 'WPA3 192-bit Security').
            dot11w: The current setting for Protected Management Frames (802.11w).
            dot11r: The current setting for 802.11r.
            splash_page: The type of splash page for the SSID ('None', 'Click-through splash page',
                'Billing', 'Password-protected with Meraki RADIUS', 'Password-protected
                with custom RADIUS', 'Password-protected with Active Directory',
                'Password-protected with LDAP', 'SMS authentication', 'Systems Manager
                Sentry', 'Facebook Wi-Fi', 'Google OAuth', 'Microsoft Entra ID',
                'Sponsored guest', 'Cisco ISE' or 'Google Apps domain').This attribute
                is not supported for template children.
            splash_guest_sponsor_domains: Array of valid sponsor email domains for sponsored guest
                splash type.
            oauth: The OAuth settings of this SSID. Only valid if splashPage is 'Google OAuth'.
            local_radius: The current setting for Local Authentication, a built-in RADIUS server on
                the access point. Only valid if authMode is '8021x-localradius'.
            ldap: The current setting for LDAP. Only valid if splashPage is 'Password-protected with
                LDAP'.
            active_directory: The current setting for Active Directory. Only valid if splashPage is
                'Password-protected with Active Directory'.
            radius_servers: The RADIUS 802.1X servers to be used for authentication. This param is
                only valid if the authMode is 'open-with-radius', '8021x-radius' or
                'ipsk-with-radius'.
            radius_proxy_enabled: If true, Meraki devices will proxy RADIUS messages through the
                Meraki cloud to the configured RADIUS auth and accounting servers.
            radius_testing_enabled: If true, Meraki devices will periodically send Access-Request
                messages to configured RADIUS servers using identity 'meraki_8021x_test'
                to ensure that the RADIUS servers are reachable.
            radius_called_station_id: The template of the called station identifier to be used for
                RADIUS (ex. $NODE_MAC$:$VAP_NUM$).
            radius_authentication_nas_id: The template of the NAS identifier to be used for RADIUS
                authentication (ex. $NODE_MAC$:$VAP_NUM$).
            radius_server_timeout: The amount of time for which a RADIUS client waits for a reply
                from the RADIUS server (must be between 1-10 seconds).
            radius_server_attempts_limit: The maximum number of transmit attempts after which a
                RADIUS server is failed over (must be between 1-5).
            radius_fallback_enabled: Whether or not higher priority RADIUS servers should be retried
                after 60 seconds.
            radius_radsec: The current settings for RADIUS RADSec.
            radius_coa_enabled: If true, Meraki devices will act as a RADIUS Dynamic Authorization
                Server and will respond to RADIUS Change-of-Authorization and Disconnect
                messages sent by the RADIUS server.
            radius_failover_policy: This policy determines how authentication requests should be
                handled in the event that all of the configured RADIUS servers are
                unreachable ('Deny access' or 'Allow access').
            radius_load_balancing_policy: This policy determines which RADIUS server will be
                contacted first in an authentication attempt and the ordering of any
                necessary retry attempts ('Strict priority order' or 'Round robin').
            radius_accounting_enabled: Whether or not RADIUS accounting is enabled. This param is
                only valid if the authMode is 'open-with-radius', '8021x-radius' or
                'ipsk-with-radius'.
            radius_accounting_servers: The RADIUS accounting 802.1X servers to be used for
                authentication. This param is only valid if the authMode is 'open-with-
                radius', '8021x-radius' or 'ipsk-with-radius' and
                radiusAccountingEnabled is 'true'.
            radius_accounting_interim_interval: The interval (in seconds) in which accounting
                information is updated and sent to the RADIUS accounting server.
            radius_attribute_for_group_policies: Specify the RADIUS attribute used to look up group
                policies ('Filter-Id', 'Reply-Message', 'Airespace-ACL-Name' or 'Aruba-
                User-Role'). Access points must receive this attribute in the RADIUS
                Access-Accept message.
            ip_assignment_mode: The client IP assignment mode ('NAT mode', 'Bridge mode', 'Layer 3
                roaming', 'Ethernet over GRE', 'Layer 3 roaming with a concentrator',
                'VPN' or 'Campus Gateway').
            use_vlan_tagging: Whether or not traffic should be directed to use specific VLANs. This
                param is only valid if the ipAssignmentMode is 'Bridge mode' or 'Layer 3
                roaming'.
            concentrator_network_id: The concentrator to use when the ipAssignmentMode is 'Layer 3
                roaming with a concentrator' or 'VPN'.
            secondary_concentrator_network_id: The secondary concentrator to use when the
                ipAssignmentMode is 'VPN'. If configured, the APs will switch to using
                this concentrator if the primary concentrator is unreachable. This param
                is optional. ('disabled' represents no secondary concentrator.).
            disassociate_clients_on_vpn_failover: Disassociate clients when 'VPN' concentrator
                failover occurs in order to trigger clients to re-associate and generate
                new DHCP requests. This param is only valid if ipAssignmentMode is
                'VPN'.
            vlan_id: The VLAN ID used for VLAN tagging. This param is only valid when the
                ipAssignmentMode is 'Layer 3 roaming with a concentrator' or 'VPN'.
            default_vlan_id: The default VLAN ID used for 'all other APs'. This param is only valid
                when the ipAssignmentMode is 'Bridge mode' or 'Layer 3 roaming'.
            ap_tags_and_vlan_ids: The list of tags and VLAN IDs used for VLAN tagging. This param is
                only valid when the ipAssignmentMode is 'Bridge mode' or 'Layer 3
                roaming'.
            walled_garden_enabled: Allow access to a configurable list of IP ranges, which users may
                access prior to sign-on.
            walled_garden_ranges: Specify your walled garden by entering an array of addresses,
                ranges using CIDR notation, domain names, and domain wildcards (e.g.
                '192.168.1.1/24', '192.168.37.10/32', 'www.yahoo.com', '*.google.com']).
                Meraki's splash page is automatically included in your walled garden.
            gre: Ethernet over GRE settings.
            radius_override: If true, the RADIUS response can override VLAN tag. This is not valid
                when ipAssignmentMode is 'NAT mode'.
            radius_guest_vlan_enabled: Whether or not RADIUS Guest VLAN is enabled. This param is
                only valid if the authMode is 'open-with-radius' and addressing mode is
                not set to 'isolated' or 'nat' mode.
            radius_guest_vlan_id: VLAN ID of the RADIUS Guest VLAN. This param is only valid if the
                authMode is 'open-with-radius' and addressing mode is not set to
                'isolated' or 'nat' mode.
            min_bitrate: The minimum bitrate in Mbps of this SSID in the default indoor RF profile.
                ('1', '2', '5.5', '6', '9', '11', '12', '18', '24', '36', '48' or '54').
            band_selection: The client-serving radio frequencies of this SSID in the default indoor
                RF profile. ('Dual band operation', '5 GHz band only' or 'Dual band
                operation with Band Steering').
            per_client_bandwidth_limit_up: The upload bandwidth limit in Kbps. (0 represents no
                limit.).
            per_client_bandwidth_limit_down: The download bandwidth limit in Kbps. (0 represents no
                limit.).
            per_ssid_bandwidth_limit_up: The total upload bandwidth limit in Kbps. (0 represents no
                limit.).
            per_ssid_bandwidth_limit_down: The total download bandwidth limit in Kbps. (0 represents
                no limit.).
            lan_isolation_enabled: Boolean indicating whether Layer 2 LAN isolation should be
                enabled or disabled. Only configurable when ipAssignmentMode is 'Bridge
                mode'.
            visible: Boolean indicating whether APs should advertise or hide this SSID. APs will
                only broadcast this SSID if set to true.
            available_on_all_aps: Boolean indicating whether all APs should broadcast the SSID or if
                it should be restricted to APs matching any availability tags. Can only
                be false if the SSID has availability tags.
            availability_tags: Accepts a list of tags for this SSID. If availableOnAllAps is false,
                then the SSID will only be broadcast by APs with tags matching any of
                the tags in this list.
            adaptive_policy_group_id: Adaptive policy group ID this SSID is assigned to.
            mandatory_dhcp_enabled: If true, Mandatory DHCP will enforce that clients connecting to
                this SSID must use the IP address assigned by the DHCP server. Clients
                who use a static IP address won't be able to associate.
            adult_content_filtering_enabled: Boolean indicating whether or not adult content will be
                blocked.
            dns_rewrite: DNS servers rewrite settings.
            speed_burst: The SpeedBurst setting for this SSID'.
            named_vlans: Named VLAN settings.
            local_auth_fallback: The current configuration for Local Authentication Fallback.
                Enables the Access Point (AP) to store client authentication data for a
                specified duration that can be adjusted as needed.
            radius_accounting_start_delay: The delay (in seconds) before sending the first RADIUS
                accounting start message. Must be between 0 and 60 seconds.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "number": 0,
              "name": "My SSID",
              "enabled": true,
              "splashPage": "Click-through splash page",
              "ssidAdminAccessible": false,
              "localAuth": false,
              "authMode": "8021x-radius",
              "encryptionMode": "wpa",
              "wpaEncryptionMode": "WPA2 only",
              "radiusServers": [
                {
                  "host": "0.0.0.0",
                  "port": 3000,
                  "openRoamingCertificateId": 2,
                  "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
                }
              ],
              "radiusAccountingServers": [
                {
                  "host": "0.0.0.0",
                  "port": 3000,
                  "openRoamingCertificateId": 2,
                  "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
                }
              ],
              "radiusAccountingEnabled": false,
              "radiusEnabled": true,
              "radiusAttributeForGroupPolicies": "Filter-Id",
              "radiusFailoverPolicy": "Deny access",
              "radiusLoadBalancingPolicy": "Round robin",
              "ipAssignmentMode": "NAT mode",
              "adminSplashUrl": "http://example.com",
              "splashTimeout": "30 minutes",
              "walledGardenEnabled": true,
              "walledGardenRanges": [
                "example.com",
                "1.1.1.1/32"
              ],
              "minBitrate": 11,
              "bandSelection": "5 GHz band only",
              "perClientBandwidthLimitUp": 0,
              "perClientBandwidthLimitDown": 0,
              "visible": true,
              "availableOnAllAps": false,
              "availabilityTags": [
                "tag1",
                "tag2"
              ],
              "perSsidBandwidthLimitUp": 0,
              "perSsidBandwidthLimitDown": 0,
              "mandatoryDhcpEnabled": false
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if enabled is not None:
            payload["enabled"] = enabled
        if auth_mode is not None:
            payload["authMode"] = auth_mode
        if enterprise_admin_access is not None:
            payload["enterpriseAdminAccess"] = enterprise_admin_access
        if encryption_mode is not None:
            payload["encryptionMode"] = encryption_mode
        if psk is not None:
            payload["psk"] = psk
        if wpa_encryption_mode is not None:
            payload["wpaEncryptionMode"] = wpa_encryption_mode
        if dot11w is not None:
            payload["dot11w"] = dot11w.model_dump(by_alias=True, exclude_none=True)
        if dot11r is not None:
            payload["dot11r"] = dot11r.model_dump(by_alias=True, exclude_none=True)
        if splash_page is not None:
            payload["splashPage"] = splash_page
        if splash_guest_sponsor_domains is not None:
            payload["splashGuestSponsorDomains"] = splash_guest_sponsor_domains
        if oauth is not None:
            payload["oauth"] = oauth.model_dump(by_alias=True, exclude_none=True)
        if local_radius is not None:
            payload["localRadius"] = local_radius.model_dump(by_alias=True, exclude_none=True)
        if ldap is not None:
            payload["ldap"] = ldap.model_dump(by_alias=True, exclude_none=True)
        if active_directory is not None:
            payload["activeDirectory"] = active_directory.model_dump(
                by_alias=True, exclude_none=True
            )
        if radius_servers is not None:
            payload["radiusServers"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in radius_servers
            ]
        if radius_proxy_enabled is not None:
            payload["radiusProxyEnabled"] = radius_proxy_enabled
        if radius_testing_enabled is not None:
            payload["radiusTestingEnabled"] = radius_testing_enabled
        if radius_called_station_id is not None:
            payload["radiusCalledStationId"] = radius_called_station_id
        if radius_authentication_nas_id is not None:
            payload["radiusAuthenticationNasId"] = radius_authentication_nas_id
        if radius_server_timeout is not None:
            payload["radiusServerTimeout"] = radius_server_timeout
        if radius_server_attempts_limit is not None:
            payload["radiusServerAttemptsLimit"] = radius_server_attempts_limit
        if radius_fallback_enabled is not None:
            payload["radiusFallbackEnabled"] = radius_fallback_enabled
        if radius_radsec is not None:
            payload["radiusRadsec"] = radius_radsec.model_dump(by_alias=True, exclude_none=True)
        if radius_coa_enabled is not None:
            payload["radiusCoaEnabled"] = radius_coa_enabled
        if radius_failover_policy is not None:
            payload["radiusFailoverPolicy"] = radius_failover_policy
        if radius_load_balancing_policy is not None:
            payload["radiusLoadBalancingPolicy"] = radius_load_balancing_policy
        if radius_accounting_enabled is not None:
            payload["radiusAccountingEnabled"] = radius_accounting_enabled
        if radius_accounting_servers is not None:
            payload["radiusAccountingServers"] = [
                item.model_dump(by_alias=True, exclude_none=True)
                for item in radius_accounting_servers
            ]
        if radius_accounting_interim_interval is not None:
            payload["radiusAccountingInterimInterval"] = radius_accounting_interim_interval
        if radius_attribute_for_group_policies is not None:
            payload["radiusAttributeForGroupPolicies"] = radius_attribute_for_group_policies
        if ip_assignment_mode is not None:
            payload["ipAssignmentMode"] = ip_assignment_mode
        if use_vlan_tagging is not None:
            payload["useVlanTagging"] = use_vlan_tagging
        if concentrator_network_id is not None:
            payload["concentratorNetworkId"] = concentrator_network_id
        if secondary_concentrator_network_id is not None:
            payload["secondaryConcentratorNetworkId"] = secondary_concentrator_network_id
        if disassociate_clients_on_vpn_failover is not None:
            payload["disassociateClientsOnVpnFailover"] = disassociate_clients_on_vpn_failover
        if vlan_id is not None:
            payload["vlanId"] = vlan_id
        if default_vlan_id is not None:
            payload["defaultVlanId"] = default_vlan_id
        if ap_tags_and_vlan_ids is not None:
            payload["apTagsAndVlanIds"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in ap_tags_and_vlan_ids
            ]
        if walled_garden_enabled is not None:
            payload["walledGardenEnabled"] = walled_garden_enabled
        if walled_garden_ranges is not None:
            payload["walledGardenRanges"] = walled_garden_ranges
        if gre is not None:
            payload["gre"] = gre.model_dump(by_alias=True, exclude_none=True)
        if radius_override is not None:
            payload["radiusOverride"] = radius_override
        if radius_guest_vlan_enabled is not None:
            payload["radiusGuestVlanEnabled"] = radius_guest_vlan_enabled
        if radius_guest_vlan_id is not None:
            payload["radiusGuestVlanId"] = radius_guest_vlan_id
        if min_bitrate is not None:
            payload["minBitrate"] = min_bitrate
        if band_selection is not None:
            payload["bandSelection"] = band_selection
        if per_client_bandwidth_limit_up is not None:
            payload["perClientBandwidthLimitUp"] = per_client_bandwidth_limit_up
        if per_client_bandwidth_limit_down is not None:
            payload["perClientBandwidthLimitDown"] = per_client_bandwidth_limit_down
        if per_ssid_bandwidth_limit_up is not None:
            payload["perSsidBandwidthLimitUp"] = per_ssid_bandwidth_limit_up
        if per_ssid_bandwidth_limit_down is not None:
            payload["perSsidBandwidthLimitDown"] = per_ssid_bandwidth_limit_down
        if lan_isolation_enabled is not None:
            payload["lanIsolationEnabled"] = lan_isolation_enabled
        if visible is not None:
            payload["visible"] = visible
        if available_on_all_aps is not None:
            payload["availableOnAllAps"] = available_on_all_aps
        if availability_tags is not None:
            payload["availabilityTags"] = availability_tags
        if adaptive_policy_group_id is not None:
            payload["adaptivePolicyGroupId"] = adaptive_policy_group_id
        if mandatory_dhcp_enabled is not None:
            payload["mandatoryDhcpEnabled"] = mandatory_dhcp_enabled
        if adult_content_filtering_enabled is not None:
            payload["adultContentFilteringEnabled"] = adult_content_filtering_enabled
        if dns_rewrite is not None:
            payload["dnsRewrite"] = dns_rewrite.model_dump(by_alias=True, exclude_none=True)
        if speed_burst is not None:
            payload["speedBurst"] = speed_burst.model_dump(by_alias=True, exclude_none=True)
        if named_vlans is not None:
            payload["namedVlans"] = named_vlans.model_dump(by_alias=True, exclude_none=True)
        if local_auth_fallback is not None:
            payload["localAuthFallback"] = local_auth_fallback.model_dump(
                by_alias=True, exclude_none=True
            )
        if radius_accounting_start_delay is not None:
            payload["radiusAccountingStartDelay"] = radius_accounting_start_delay

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsid",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidResponse,
        )

    async def get_network_wireless_ssid_bonjour_forwarding(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidBonjourForwardingResponse:
        """List the Bonjour forwarding setting and rules for the SSID.

        [API documentation: getNetworkWirelessSsidBonjourForwarding](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-bonjour-forwarding)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "exception": {
                "enabled": true
              },
              "rules": [
                {
                  "description": "A simple bonjour rule",
                  "vlanId": "1",
                  "services": [
                    "All Services"
                  ]
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/bonjourForwarding"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidBonjourForwarding",
            path=path,
            response_schema=GetNetworkWirelessSsidBonjourForwardingResponse,
        )

    async def update_network_wireless_ssid_bonjour_forwarding(
        self,
        *,
        network_id: str,
        number: str,
        enabled: bool | None = None,
        rules: list[UpdateNetworkWirelessSsidBonjourForwardingRulesItem] | None = None,
        exception: UpdateNetworkWirelessSsidBonjourForwardingException | None = None,
    ) -> UpdateNetworkWirelessSsidBonjourForwardingResponse:
        """Update the bonjour forwarding setting and rules for the SSID.

        [API documentation: updateNetworkWirelessSsidBonjourForwarding](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-bonjour-forwarding)

        Args:
            network_id: Network ID.
            number: Number.
            enabled: If true, Bonjour forwarding is enabled on this SSID.
            rules: List of bonjour forwarding rules.
            exception: Bonjour forwarding exception.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "exception": {
                "enabled": true
              },
              "rules": [
                {
                  "description": "A simple bonjour rule",
                  "vlanId": "1",
                  "services": [
                    "All Services"
                  ]
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/bonjourForwarding"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if rules is not None:
            payload["rules"] = [item.model_dump(by_alias=True, exclude_none=True) for item in rules]
        if exception is not None:
            payload["exception"] = exception.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidBonjourForwarding",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidBonjourForwardingResponse,
        )

    async def get_network_wireless_ssid_device_type_group_policies(
        self, *, network_id: str, number: str
    ) -> DictResponse:
        """List the device type group policies for the SSID.

        [API documentation: getNetworkWirelessSsidDeviceTypeGroupPolicies](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-device-type-group-policies)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "deviceTypePolicies": [
                {
                  "deviceType": "Android",
                  "devicePolicy": "Allowed"
                },
                {
                  "deviceType": "iPhone",
                  "devicePolicy": "Group policy",
                  "groupPolicyId": 101
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/deviceTypeGroupPolicies"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidDeviceTypeGroupPolicies",
            path=path,
            response_schema=DictResponse,
        )

    async def update_network_wireless_ssid_device_type_group_policies(
        self,
        *,
        network_id: str,
        number: str,
        enabled: bool | None = None,
        device_type_policies: list[
            UpdateNetworkWirelessSsidDeviceTypeGroupPoliciesDeviceTypePoliciesItem
        ]
        | None = None,
    ) -> DictResponse:
        """Update the device type group policies for the SSID.

        [API documentation: updateNetworkWirelessSsidDeviceTypeGroupPolicies](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-device-type-group-policies)

        Args:
            network_id: Network ID.
            number: Number.
            enabled: If true, the SSID device type group policies are enabled.
            device_type_policies: List of device type policies.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "deviceTypePolicies": [
                {
                  "deviceType": "Android",
                  "devicePolicy": "Allowed"
                },
                {
                  "deviceType": "iPhone",
                  "devicePolicy": "Group policy",
                  "groupPolicyId": 101
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/deviceTypeGroupPolicies"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if device_type_policies is not None:
            payload["deviceTypePolicies"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in device_type_policies
            ]

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidDeviceTypeGroupPolicies",
            path=path,
            json=payload,
            response_schema=DictResponse,
        )

    async def get_network_wireless_ssid_eap_override(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidEapOverrideResponse:
        """Return the EAP overridden parameters for an SSID.

        [API documentation: getNetworkWirelessSsidEapOverride](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-eap-override)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "timeout": 50,
              "maxRetries": 5,
              "identity": {
                "retries": 5,
                "timeout": 50
              },
              "eapolKey": {
                "retries": 50,
                "timeoutInMs": 5000
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/eapOverride"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidEapOverride",
            path=path,
            response_schema=GetNetworkWirelessSsidEapOverrideResponse,
        )

    async def update_network_wireless_ssid_eap_override(
        self,
        *,
        network_id: str,
        number: str,
        timeout: int | None = None,
        identity: UpdateNetworkWirelessSsidEapOverrideIdentity | None = None,
        max_retries: int | None = None,
        eapol_key: UpdateNetworkWirelessSsidEapOverrideEapolKey | None = None,
    ) -> UpdateNetworkWirelessSsidEapOverrideResponse:
        """Update the EAP overridden parameters for an SSID.

        [API documentation: updateNetworkWirelessSsidEapOverride](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-eap-override)

        Args:
            network_id: Network ID.
            number: Number.
            timeout: General EAP timeout in seconds.
            identity: EAP settings for identity requests.
            max_retries: Maximum number of general EAP retries.
            eapol_key: EAPOL Key settings.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "timeout": 50,
              "maxRetries": 5,
              "identity": {
                "retries": 5,
                "timeout": 50
              },
              "eapolKey": {
                "retries": 50,
                "timeoutInMs": 5000
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/eapOverride"

        payload: dict[str, Any] = {}
        if timeout is not None:
            payload["timeout"] = timeout
        if identity is not None:
            payload["identity"] = identity.model_dump(by_alias=True, exclude_none=True)
        if max_retries is not None:
            payload["maxRetries"] = max_retries
        if eapol_key is not None:
            payload["eapolKey"] = eapol_key.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidEapOverride",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidEapOverrideResponse,
        )

    async def get_network_wireless_ssid_firewall_l3_firewall_rules(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidFirewallL3FirewallRulesResponse:
        """Return the L3 firewall rules for an SSID on an MR network.

        [API documentation: getNetworkWirelessSsidFirewallL3FirewallRules](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-firewall-l-3-firewall-rules)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "rules": [
                {
                  "comment": "Allow TCP traffic to subnet with HTTP servers.",
                  "policy": "allow",
                  "ipVer": "both",
                  "protocol": "tcp",
                  "destPort": "443",
                  "destCidr": "192.168.1.0/24"
                }
              ],
              "allowLanAccess": false
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/firewall/l3FirewallRules"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidFirewallL3FirewallRules",
            path=path,
            response_schema=GetNetworkWirelessSsidFirewallL3FirewallRulesResponse,
        )

    async def update_network_wireless_ssid_firewall_l3_firewall_rules(
        self,
        *,
        network_id: str,
        number: str,
        rules: list[UpdateNetworkWirelessSsidFirewallL3FirewallRulesRulesItem] | None = None,
        allow_lan_access: bool | None = None,
    ) -> UpdateNetworkWirelessSsidFirewallL3FirewallRulesResponse:
        """Update the L3 firewall rules of an SSID on an MR network.

        [API documentation: updateNetworkWirelessSsidFirewallL3FirewallRules](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-firewall-l-3-firewall-rules)

        Args:
            network_id: Network ID.
            number: Number.
            rules: An ordered array of the firewall rules for this SSID.
            allow_lan_access: Allow wireless client access to local LAN (boolean value - true allows
                access and false denies access) (optional).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "rules": [
                {
                  "comment": "Allow TCP traffic to subnet with HTTP servers.",
                  "policy": "allow",
                  "ipVer": "both",
                  "protocol": "tcp",
                  "destPort": "443",
                  "destCidr": "192.168.1.0/24"
                }
              ],
              "allowLanAccess": false
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/firewall/l3FirewallRules"

        payload: dict[str, Any] = {}
        if rules is not None:
            payload["rules"] = [item.model_dump(by_alias=True, exclude_none=True) for item in rules]
        if allow_lan_access is not None:
            payload["allowLanAccess"] = allow_lan_access

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidFirewallL3FirewallRules",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidFirewallL3FirewallRulesResponse,
        )

    async def get_network_wireless_ssid_firewall_l7_firewall_rules(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidFirewallL7FirewallRulesResponse:
        """Return the L7 firewall rules for an SSID on an MR network.

        [API documentation: getNetworkWirelessSsidFirewallL7FirewallRules](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-firewall-l-7-firewall-rules)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "rules": [
                {
                  "policy": "deny",
                  "type": "host",
                  "value": "google.com"
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/firewall/l7FirewallRules"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidFirewallL7FirewallRules",
            path=path,
            response_schema=GetNetworkWirelessSsidFirewallL7FirewallRulesResponse,
        )

    async def update_network_wireless_ssid_firewall_l7_firewall_rules(
        self,
        *,
        network_id: str,
        number: str,
        rules: list[UpdateNetworkWirelessSsidFirewallL7FirewallRulesRulesItem] | None = None,
    ) -> UpdateNetworkWirelessSsidFirewallL7FirewallRulesResponse:
        """Update the L7 firewall rules of an SSID on an MR network.

        [API documentation: updateNetworkWirelessSsidFirewallL7FirewallRules](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-firewall-l-7-firewall-rules)

        Args:
            network_id: Network ID.
            number: Number.
            rules: An array of L7 firewall rules for this SSID. Rules will get applied in the same
                order user has specified in request. Empty array will clear the L7
                firewall rule configuration.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "rules": [
                {
                  "policy": "deny",
                  "type": "host",
                  "value": "google.com"
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/firewall/l7FirewallRules"

        payload: dict[str, Any] = {}
        if rules is not None:
            payload["rules"] = [item.model_dump(by_alias=True, exclude_none=True) for item in rules]

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidFirewallL7FirewallRules",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidFirewallL7FirewallRulesResponse,
        )

    async def get_network_wireless_ssid_hotspot20(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidHotspot20Response:
        """Return the Hotspot 2.0 settings for an SSID.

        [API documentation: getNetworkWirelessSsidHotspot20](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-hotspot-20)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "operator": {
                "name": "Meraki Product Management"
              },
              "venue": {
                "name": "SF Branch",
                "type": "Unspecified Assembly"
              },
              "networkAccessType": "Private network",
              "domains": [
                "meraki.local",
                "domain2.com"
              ],
              "roamConsortOis": [
                "ABC123",
                "456EFG"
              ],
              "mccMncs": [
                {
                  "mcc": "123",
                  "mnc": "456"
                }
              ],
              "naiRealms": [
                {
                  "format": "1",
                  "name": "Realm 1",
                  "methods": [
                    {
                      "id": "1",
                      "authenticationTypes": {
                        "nonEapInnerAuthentication": [
                          "MSCHAP"
                        ],
                        "eapInnerAuthentication": [
                          "EAP-TTLS with MSCHAPv2"
                        ],
                        "credentials": [],
                        "tunneledEapMethodCredentials": []
                      }
                    }
                  ]
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/hotspot20"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidHotspot20",
            path=path,
            response_schema=GetNetworkWirelessSsidHotspot20Response,
        )

    async def update_network_wireless_ssid_hotspot20(
        self,
        *,
        network_id: str,
        number: str,
        enabled: bool | None = None,
        operator: UpdateNetworkWirelessSsidHotspot20Operator | None = None,
        venue: UpdateNetworkWirelessSsidHotspot20Venue | None = None,
        network_access_type: UpdateNetworkWirelessSsidHotspot20NetworkAccessType | None = None,
        domains: list[str] | None = None,
        roam_consort_ois: list[str] | None = None,
        mcc_mncs: list[UpdateNetworkWirelessSsidHotspot20MccMncsItem] | None = None,
        nai_realms: list[UpdateNetworkWirelessSsidHotspot20NaiRealmsItem] | None = None,
    ) -> UpdateNetworkWirelessSsidHotspot20Response:
        """Update the Hotspot 2.0 settings of an SSID.

        [API documentation: updateNetworkWirelessSsidHotspot20](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-hotspot-20)

        Args:
            network_id: Network ID.
            number: Number.
            enabled: Whether or not Hotspot 2.0 for this SSID is enabled.
            operator: Operator settings for this SSID.
            venue: Venue settings for this SSID.
            network_access_type: The network type of this SSID ('Private network', 'Private network
                with guest access', 'Chargeable public network', 'Free public network',
                'Personal device network', 'Emergency services only network', 'Test or
                experimental', 'Wildcard').
            domains: An array of domain names.
            roam_consort_ois: An array of roaming consortium OIs (hexadecimal number 3-5 octets in
                length).
            mcc_mncs: An array of MCC/MNC pairs.
            nai_realms: An array of NAI realms.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "operator": {
                "name": "Meraki Product Management"
              },
              "venue": {
                "name": "SF Branch",
                "type": "Unspecified Assembly"
              },
              "networkAccessType": "Private network",
              "domains": [
                "meraki.local",
                "domain2.com"
              ],
              "roamConsortOis": [
                "ABC123",
                "456EFG"
              ],
              "mccMncs": [
                {
                  "mcc": "123",
                  "mnc": "456"
                }
              ],
              "naiRealms": [
                {
                  "format": "1",
                  "name": "Realm 1",
                  "methods": [
                    {
                      "id": "1",
                      "authenticationTypes": {
                        "nonEapInnerAuthentication": [
                          "MSCHAP"
                        ],
                        "eapInnerAuthentication": [
                          "EAP-TTLS with MSCHAPv2"
                        ],
                        "credentials": [],
                        "tunneledEapMethodCredentials": []
                      }
                    }
                  ]
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/hotspot20"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if operator is not None:
            payload["operator"] = operator.model_dump(by_alias=True, exclude_none=True)
        if venue is not None:
            payload["venue"] = venue.model_dump(by_alias=True, exclude_none=True)
        if network_access_type is not None:
            payload["networkAccessType"] = network_access_type
        if domains is not None:
            payload["domains"] = domains
        if roam_consort_ois is not None:
            payload["roamConsortOis"] = roam_consort_ois
        if mcc_mncs is not None:
            payload["mccMncs"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in mcc_mncs
            ]
        if nai_realms is not None:
            payload["naiRealms"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in nai_realms
            ]

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidHotspot20",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidHotspot20Response,
        )

    def get_network_wireless_ssid_identity_psks(
        self, *, network_id: str, number: str
    ) -> AsyncPaginatedResponse[GetNetworkWirelessSsidIdentityPsksResponseItem]:
        """List all Identity PSKs in a wireless network.

        [API documentation: getNetworkWirelessSsidIdentityPsks](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-identity-psks)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "Sample Identity PSK",
                "id": "1284392014819",
                "groupPolicyId": "101",
                "passphrase": "secret",
                "wifiPersonalNetworkId": "1284392014819",
                "email": "miles@meraki.com",
                "expiresAt": "2018-02-11T00:00:00.090210Z"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/identityPsks"

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessSsidIdentityPsks",
            path=path,
            item_schema=GetNetworkWirelessSsidIdentityPsksResponseItem,
        )

    async def create_network_wireless_ssid_identity_psk(
        self,
        *,
        network_id: str,
        number: str,
        name: str,
        group_policy_id: str,
        passphrase: str | None = None,
        expires_at: str | None = None,
    ) -> CreateNetworkWirelessSsidIdentityPskResponse:
        """Create an Identity PSK.

        [API documentation: createNetworkWirelessSsidIdentityPsk](https://developer.cisco.com/meraki/api-v1/#!create-network-wireless-ssid-identity-psk)

        Args:
            network_id: Network ID.
            number: Number.
            name: The name of the Identity PSK.
            passphrase: The passphrase for client authentication. If left blank, one will be auto-
                generated.
            group_policy_id: The group policy to be applied to clients.
            expires_at: Timestamp for when the Identity PSK expires. Will not expire if left blank.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "name": "Sample Identity PSK",
              "id": "1284392014819",
              "groupPolicyId": "101",
              "passphrase": "secret",
              "wifiPersonalNetworkId": "1284392014819",
              "email": "miles@meraki.com",
              "expiresAt": "2018-02-11T00:00:00.090210Z"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/identityPsks"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if passphrase is not None:
            payload["passphrase"] = passphrase
        if group_policy_id is not None:
            payload["groupPolicyId"] = group_policy_id
        if expires_at is not None:
            payload["expiresAt"] = expires_at

        return await self._session.post(
            scope="wireless",
            operation_id="createNetworkWirelessSsidIdentityPsk",
            path=path,
            json=payload,
            response_schema=CreateNetworkWirelessSsidIdentityPskResponse,
        )

    async def get_network_wireless_ssid_identity_psk(
        self, *, network_id: str, number: str, identity_psk_id: str
    ) -> GetNetworkWirelessSsidIdentityPskResponse:
        """Return an Identity PSK.

        [API documentation: getNetworkWirelessSsidIdentityPsk](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-identity-psk)

        Args:
            network_id: Network ID.
            number: Number.
            identity_psk_id: Identity psk ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "name": "Sample Identity PSK",
              "id": "1284392014819",
              "groupPolicyId": "101",
              "passphrase": "secret",
              "wifiPersonalNetworkId": "1284392014819",
              "email": "miles@meraki.com",
              "expiresAt": "2018-02-11T00:00:00.090210Z"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        identity_psk_id = urllib.parse.quote(str(identity_psk_id), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/identityPsks/{identity_psk_id}"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidIdentityPsk",
            path=path,
            response_schema=GetNetworkWirelessSsidIdentityPskResponse,
        )

    async def update_network_wireless_ssid_identity_psk(
        self,
        *,
        network_id: str,
        number: str,
        identity_psk_id: str,
        name: str | None = None,
        passphrase: str | None = None,
        group_policy_id: str | None = None,
        expires_at: str | None = None,
    ) -> UpdateNetworkWirelessSsidIdentityPskResponse:
        """Update an Identity PSK.

        [API documentation: updateNetworkWirelessSsidIdentityPsk](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-identity-psk)

        Args:
            network_id: Network ID.
            number: Number.
            identity_psk_id: Identity psk ID.
            name: The name of the Identity PSK.
            passphrase: The passphrase for client authentication.
            group_policy_id: The group policy to be applied to clients.
            expires_at: Timestamp for when the Identity PSK expires, or 'null' to never expire.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "name": "Sample Identity PSK",
              "id": "1284392014819",
              "groupPolicyId": "101",
              "passphrase": "secret",
              "wifiPersonalNetworkId": "1284392014819",
              "email": "miles@meraki.com",
              "expiresAt": "2018-02-11T00:00:00.090210Z"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        identity_psk_id = urllib.parse.quote(str(identity_psk_id), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/identityPsks/{identity_psk_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if passphrase is not None:
            payload["passphrase"] = passphrase
        if group_policy_id is not None:
            payload["groupPolicyId"] = group_policy_id
        if expires_at is not None:
            payload["expiresAt"] = expires_at

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidIdentityPsk",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidIdentityPskResponse,
        )

    async def delete_network_wireless_ssid_identity_psk(
        self, *, network_id: str, number: str, identity_psk_id: str
    ) -> None:
        """Delete an Identity PSK.

        [API documentation: deleteNetworkWirelessSsidIdentityPsk](https://developer.cisco.com/meraki/api-v1/#!delete-network-wireless-ssid-identity-psk)

        Args:
            network_id: Network ID.
            number: Number.
            identity_psk_id: Identity psk ID.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        identity_psk_id = urllib.parse.quote(str(identity_psk_id), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/identityPsks/{identity_psk_id}"

        return await self._session.delete(
            scope="wireless", operation_id="deleteNetworkWirelessSsidIdentityPsk", path=path
        )

    async def update_network_wireless_ssid_open_roaming(
        self,
        *,
        network_id: str,
        number: str,
        enabled: bool | None = None,
        tenant_id: str | None = None,
    ) -> UpdateNetworkWirelessSsidOpenRoamingResponse:
        """Update the OpenRoaming setting for the SSID.

        [API documentation: updateNetworkWirelessSsidOpenRoaming](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-open-roaming)

        Args:
            network_id: Network ID.
            number: Number.
            enabled: If true, OpenRoaming is enabled on this SSID.
            tenant_id: The OpenRoaming DNA Spaces tenant ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "tenantId": "123-456"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/openRoaming"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if tenant_id is not None:
            payload["tenantId"] = tenant_id

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidOpenRoaming",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidOpenRoamingResponse,
        )

    async def get_network_wireless_ssid_schedules(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidSchedulesResponse:
        """List the outage schedule for the SSID.

        [API documentation: getNetworkWirelessSsidSchedules](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-schedules)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "ranges": [
                {
                  "startDay": "Tuesday",
                  "startTime": "01:00",
                  "endDay": "Tuesday",
                  "endTime": "05:00"
                }
              ],
              "rangesInSeconds": [
                {
                  "start": 604800,
                  "end": 0
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/schedules"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidSchedules",
            path=path,
            response_schema=GetNetworkWirelessSsidSchedulesResponse,
        )

    async def update_network_wireless_ssid_schedules(
        self,
        *,
        network_id: str,
        number: str,
        enabled: bool | None = None,
        ranges: list[UpdateNetworkWirelessSsidSchedulesRangesItem] | None = None,
        ranges_in_seconds: list[UpdateNetworkWirelessSsidSchedulesRangesInSecondsItem]
        | None = None,
    ) -> UpdateNetworkWirelessSsidSchedulesResponse:
        """Update the outage schedule for the SSID.

        [API documentation: updateNetworkWirelessSsidSchedules](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-schedules)

        Args:
            network_id: Network ID.
            number: Number.
            enabled: If true, the SSID outage schedule is enabled.
            ranges: List of outage ranges. Has a start date and time, and end date and time. If this
                parameter is passed in along with rangesInSeconds parameter, this will
                take precedence.
            ranges_in_seconds: List of outage ranges in seconds since Sunday at Midnight. Has a
                start and end. If this parameter is passed in along with the ranges
                parameter, ranges will take precedence.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "ranges": [
                {
                  "startDay": "Tuesday",
                  "startTime": "01:00",
                  "endDay": "Tuesday",
                  "endTime": "05:00"
                }
              ],
              "rangesInSeconds": [
                {
                  "start": 604800,
                  "end": 0
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/schedules"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if ranges is not None:
            payload["ranges"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in ranges
            ]
        if ranges_in_seconds is not None:
            payload["rangesInSeconds"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in ranges_in_seconds
            ]

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidSchedules",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidSchedulesResponse,
        )

    async def get_network_wireless_ssid_splash_settings(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidSplashSettingsResponse:
        """Display the splash page settings for the given SSID.

        [API documentation: getNetworkWirelessSsidSplashSettings](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-splash-settings)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "ssidNumber": 0,
              "splashPage": "Click-through splash page",
              "useSplashUrl": true,
              "splashUrl": "https://www.custom_splash_url.com",
              "splashTimeout": 1440,
              "redirectUrl": "https://example.com",
              "useRedirectUrl": true,
              "welcomeMessage": "Welcome!",
              "themeId": "c3ddcb4f16785ee747ab5ffc10867d6c8ea704be",
              "splashLogo": {
                "md5": "abcd1234",
                "extension": "jpg"
              },
              "splashImage": {
                "md5": "542cccac8d7dedee0f185311d154d194",
                "extension": "jpg"
              },
              "splashPrepaidFront": {
                "md5": "542cccac8d7dedee0f185311d154d194",
                "extension": "jpg"
              },
              "guestSponsorship": {
                "durationInMinutes": 30,
                "guestCanRequestTimeframe": false
              },
              "blockAllTrafficBeforeSignOn": false,
              "controllerDisconnectionBehavior": "default",
              "allowSimultaneousLogins": false,
              "billing": {
                "freeAccess": {
                  "enabled": true,
                  "durationInMinutes": 120
                },
                "prepaidAccessFastLoginEnabled": true,
                "replyToEmailAddress": "user@email.com"
              },
              "sentryEnrollment": {
                "systemsManagerNetwork": {
                  "id": "N_1234"
                },
                "strength": "focused",
                "enforcedSystems": [
                  "iOS"
                ]
              },
              "selfRegistration": {
                "enabled": true,
                "authorizationType": "admin"
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/splash/settings"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidSplashSettings",
            path=path,
            response_schema=GetNetworkWirelessSsidSplashSettingsResponse,
        )

    async def update_network_wireless_ssid_splash_settings(
        self,
        *,
        network_id: str,
        number: str,
        splash_url: str | None = None,
        use_splash_url: bool | None = None,
        splash_timeout: UpdateNetworkWirelessSsidSplashSettingsSplashTimeout | None = None,
        redirect_url: str | None = None,
        use_redirect_url: bool | None = None,
        welcome_message: str | None = None,
        theme_id: str | None = None,
        splash_logo: UpdateNetworkWirelessSsidSplashSettingsSplashLogo | None = None,
        splash_image: UpdateNetworkWirelessSsidSplashSettingsSplashImage | None = None,
        splash_prepaid_front: UpdateNetworkWirelessSsidSplashSettingsSplashPrepaidFront
        | None = None,
        block_all_traffic_before_sign_on: bool | None = None,
        controller_disconnection_behavior: UpdateNetworkWirelessSsidSplashSettingsControllerDisconnectionBehavior
        | None = None,
        allow_simultaneous_logins: bool | None = None,
        guest_sponsorship: UpdateNetworkWirelessSsidSplashSettingsGuestSponsorship | None = None,
        billing: UpdateNetworkWirelessSsidSplashSettingsBilling | None = None,
        sentry_enrollment: UpdateNetworkWirelessSsidSplashSettingsSentryEnrollment | None = None,
        self_registration: UpdateNetworkWirelessSsidSplashSettingsSelfRegistration | None = None,
    ) -> UpdateNetworkWirelessSsidSplashSettingsResponse:
        """Modify the splash page settings for the given SSID.

        [API documentation: updateNetworkWirelessSsidSplashSettings](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-splash-settings)

        Args:
            network_id: Network ID.
            number: Number.
            splash_url: [optional] The custom splash URL of the click-through splash page. Note that
                the URL can be configured without necessarily being used. In order to
                enable the custom URL, see 'useSplashUrl'.
            use_splash_url: [optional] Boolean indicating whether the users will be redirected to
                the custom splash url. A custom splash URL must be set if this is true.
                Note that depending on your SSID's access control settings, it may not
                be possible to use the custom splash URL.
            splash_timeout: Splash timeout in minutes. This will determine how often users will see
                the splash page.
            redirect_url: The custom redirect URL where the users will go after the splash page.
            use_redirect_url: The Boolean indicating whether the the user will be redirected to the
                custom redirect URL after the splash page. A custom redirect URL must be
                set if this is true.
            welcome_message: The welcome message for the users on the splash page.
            theme_id: The id of the selected splash theme.
            splash_logo: The logo used in the splash page.
            splash_image: The image used in the splash page.
            splash_prepaid_front: The prepaid front image used in the splash page.
            block_all_traffic_before_sign_on: How restricted allowing traffic should be. If true,
                all traffic types are blocked until the splash page is acknowledged. If
                false, all non-HTTP traffic is allowed before the splash page is
                acknowledged.
            controller_disconnection_behavior: How login attempts should be handled when the
                controller is unreachable. Can be either 'open', 'restricted', or
                'default'.
            allow_simultaneous_logins: Whether or not to allow simultaneous logins from different
                devices.
            guest_sponsorship: Details associated with guest sponsored splash.
            billing: Details associated with billing splash.
            sentry_enrollment: Systems Manager sentry enrollment splash settings.
            self_registration: Self-registration settings for splash with Meraki authentication.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "ssidNumber": 0,
              "splashPage": "Click-through splash page",
              "useSplashUrl": true,
              "splashUrl": "https://www.custom_splash_url.com",
              "splashTimeout": 1440,
              "redirectUrl": "https://example.com",
              "useRedirectUrl": true,
              "welcomeMessage": "Welcome!",
              "themeId": "c3ddcb4f16785ee747ab5ffc10867d6c8ea704be",
              "splashLogo": {
                "md5": "abcd1234",
                "extension": "jpg"
              },
              "splashImage": {
                "md5": "542cccac8d7dedee0f185311d154d194",
                "extension": "jpg"
              },
              "splashPrepaidFront": {
                "md5": "542cccac8d7dedee0f185311d154d194",
                "extension": "jpg"
              },
              "guestSponsorship": {
                "durationInMinutes": 30,
                "guestCanRequestTimeframe": false
              },
              "blockAllTrafficBeforeSignOn": false,
              "controllerDisconnectionBehavior": "default",
              "allowSimultaneousLogins": false,
              "billing": {
                "freeAccess": {
                  "enabled": true,
                  "durationInMinutes": 120
                },
                "prepaidAccessFastLoginEnabled": true,
                "replyToEmailAddress": "user@email.com"
              },
              "sentryEnrollment": {
                "systemsManagerNetwork": {
                  "id": "N_1234"
                },
                "strength": "focused",
                "enforcedSystems": [
                  "iOS"
                ]
              },
              "selfRegistration": {
                "enabled": true,
                "authorizationType": "admin"
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/splash/settings"

        payload: dict[str, Any] = {}
        if splash_url is not None:
            payload["splashUrl"] = splash_url
        if use_splash_url is not None:
            payload["useSplashUrl"] = use_splash_url
        if splash_timeout is not None:
            payload["splashTimeout"] = splash_timeout
        if redirect_url is not None:
            payload["redirectUrl"] = redirect_url
        if use_redirect_url is not None:
            payload["useRedirectUrl"] = use_redirect_url
        if welcome_message is not None:
            payload["welcomeMessage"] = welcome_message
        if theme_id is not None:
            payload["themeId"] = theme_id
        if splash_logo is not None:
            payload["splashLogo"] = splash_logo.model_dump(by_alias=True, exclude_none=True)
        if splash_image is not None:
            payload["splashImage"] = splash_image.model_dump(by_alias=True, exclude_none=True)
        if splash_prepaid_front is not None:
            payload["splashPrepaidFront"] = splash_prepaid_front.model_dump(
                by_alias=True, exclude_none=True
            )
        if block_all_traffic_before_sign_on is not None:
            payload["blockAllTrafficBeforeSignOn"] = block_all_traffic_before_sign_on
        if controller_disconnection_behavior is not None:
            payload["controllerDisconnectionBehavior"] = controller_disconnection_behavior
        if allow_simultaneous_logins is not None:
            payload["allowSimultaneousLogins"] = allow_simultaneous_logins
        if guest_sponsorship is not None:
            payload["guestSponsorship"] = guest_sponsorship.model_dump(
                by_alias=True, exclude_none=True
            )
        if billing is not None:
            payload["billing"] = billing.model_dump(by_alias=True, exclude_none=True)
        if sentry_enrollment is not None:
            payload["sentryEnrollment"] = sentry_enrollment.model_dump(
                by_alias=True, exclude_none=True
            )
        if self_registration is not None:
            payload["selfRegistration"] = self_registration.model_dump(
                by_alias=True, exclude_none=True
            )

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidSplashSettings",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidSplashSettingsResponse,
        )

    async def get_network_wireless_ssid_traffic_shaping_rules(
        self, *, network_id: str, number: str
    ) -> GetNetworkWirelessSsidTrafficShapingRulesResponse:
        """Display the traffic shaping settings for a SSID on an MR network.

        [API documentation: getNetworkWirelessSsidTrafficShapingRules](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-traffic-shaping-rules)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "trafficShapingEnabled": true,
              "defaultRulesEnabled": true,
              "rules": [
                {
                  "definitions": [
                    {
                      "type": "host",
                      "value": "google.com"
                    }
                  ],
                  "perClientBandwidthLimits": {
                    "settings": "custom",
                    "bandwidthLimits": {
                      "limitUp": 1000000,
                      "limitDown": 1000000
                    }
                  },
                  "dscpTagValue": 0,
                  "pcpTagValue": 0
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/trafficShaping/rules"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidTrafficShapingRules",
            path=path,
            response_schema=GetNetworkWirelessSsidTrafficShapingRulesResponse,
        )

    async def update_network_wireless_ssid_traffic_shaping_rules(
        self,
        *,
        network_id: str,
        number: str,
        traffic_shaping_enabled: bool | None = None,
        default_rules_enabled: bool | None = None,
        rules: list[UpdateNetworkWirelessSsidTrafficShapingRulesRulesItem] | None = None,
    ) -> UpdateNetworkWirelessSsidTrafficShapingRulesResponse:
        """Update the traffic shaping rules for an SSID on an MR network.

        [API documentation: updateNetworkWirelessSsidTrafficShapingRules](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-traffic-shaping-rules)

        Args:
            network_id: Network ID.
            number: Number.
            traffic_shaping_enabled: Whether traffic shaping rules are applied to clients on your
                SSID.
            default_rules_enabled: Whether default traffic shaping rules are enabled (true) or
                disabled (false). There are 4 default rules, which can be seen on your
                network's traffic shaping page. Note that default rules count against
                the rule limit of 8.
            rules: An array of traffic shaping rules. Rules are applied in the order that they are
                specified in. An empty list (or null) means no rules. Note that you are
                allowed a maximum of 8 rules.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "trafficShapingEnabled": true,
              "defaultRulesEnabled": true,
              "rules": [
                {
                  "definitions": [
                    {
                      "type": "host",
                      "value": "google.com"
                    }
                  ],
                  "perClientBandwidthLimits": {
                    "settings": "custom",
                    "bandwidthLimits": {
                      "limitUp": 1000000,
                      "limitDown": 1000000
                    }
                  },
                  "dscpTagValue": 0,
                  "pcpTagValue": 0
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/trafficShaping/rules"

        payload: dict[str, Any] = {}
        if traffic_shaping_enabled is not None:
            payload["trafficShapingEnabled"] = traffic_shaping_enabled
        if default_rules_enabled is not None:
            payload["defaultRulesEnabled"] = default_rules_enabled
        if rules is not None:
            payload["rules"] = [item.model_dump(by_alias=True, exclude_none=True) for item in rules]

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidTrafficShapingRules",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessSsidTrafficShapingRulesResponse,
        )

    async def get_network_wireless_ssid_vpn(self, *, network_id: str, number: str) -> DictResponse:
        """List the VPN settings for the SSID.

        [API documentation: getNetworkWirelessSsidVpn](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-ssid-vpn)

        Args:
            network_id: Network ID.
            number: Number.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "concentrator": {
                "networkId": "N_123",
                "vlanId": 44,
                "name": "some concentrator name"
              },
              "failover": {
                "requestIp": "1.1.1.1",
                "heartbeatInterval": 10,
                "idleTimeout": 30
              },
              "splitTunnel": {
                "enabled": true,
                "rules": [
                  {
                    "protocol": "Any",
                    "destCidr": "1.1.1.1/32",
                    "destPort": "any",
                    "policy": "allow",
                    "comment": "split tunnel rule 1"
                  },
                  {
                    "destCidr": "foo.com",
                    "destPort": "any",
                    "policy": "deny",
                    "comment": "split tunnel rule 2"
                  }
                ]
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/vpn"

        return await self._session.get(
            scope="wireless",
            operation_id="getNetworkWirelessSsidVpn",
            path=path,
            response_schema=DictResponse,
        )

    async def update_network_wireless_ssid_vpn(
        self,
        *,
        network_id: str,
        number: str,
        concentrator: UpdateNetworkWirelessSsidVpnConcentrator | None = None,
        split_tunnel: UpdateNetworkWirelessSsidVpnSplitTunnel | None = None,
        failover: UpdateNetworkWirelessSsidVpnFailover | None = None,
    ) -> DictResponse:
        """Update the VPN settings for the SSID.

        [API documentation: updateNetworkWirelessSsidVpn](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid-vpn)

        Args:
            network_id: Network ID.
            number: Number.
            concentrator: The VPN concentrator settings for this SSID.
            split_tunnel: The VPN split tunnel settings for this SSID.
            failover: Secondary VPN concentrator settings. This is only used when two VPN
                concentrators are configured on the SSID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "concentrator": {
                "networkId": "N_123",
                "vlanId": 44,
                "name": "some concentrator name"
              },
              "failover": {
                "requestIp": "1.1.1.1",
                "heartbeatInterval": 10,
                "idleTimeout": 30
              },
              "splitTunnel": {
                "enabled": true,
                "rules": [
                  {
                    "protocol": "Any",
                    "destCidr": "1.1.1.1/32",
                    "destPort": "any",
                    "policy": "allow",
                    "comment": "split tunnel rule 1"
                  },
                  {
                    "destCidr": "foo.com",
                    "destPort": "any",
                    "policy": "deny",
                    "comment": "split tunnel rule 2"
                  }
                ]
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        number = urllib.parse.quote(str(number), safe="")
        path = f"/networks/{network_id}/wireless/ssids/{number}/vpn"

        payload: dict[str, Any] = {}
        if concentrator is not None:
            payload["concentrator"] = concentrator.model_dump(by_alias=True, exclude_none=True)
        if split_tunnel is not None:
            payload["splitTunnel"] = split_tunnel.model_dump(by_alias=True, exclude_none=True)
        if failover is not None:
            payload["failover"] = failover.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessSsidVpn",
            path=path,
            json=payload,
            response_schema=DictResponse,
        )

    def get_network_wireless_usage_history(
        self,
        network_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        resolution: int | None = None,
        auto_resolution: bool | None = None,
        client_id: str | None = None,
        device_serial: str | None = None,
        ap_tag: str | None = None,
        band: GetNetworkWirelessUsageHistoryBand | None = None,
        ssid: int | None = None,
    ) -> AsyncPaginatedResponse[GetNetworkWirelessUsageHistoryResponseItem]:
        """Return AP usage over time for a device or network client.

        [API documentation: getNetworkWirelessUsageHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-wireless-usage-history)

        Args:
            network_id: Network ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 7 days.
            resolution: The time resolution in seconds for returned data. The valid resolutions are:
                300, 600, 1200, 3600, 14400, 86400. The default is 86400.
            auto_resolution: Automatically select a data resolution based on the given timespan;
                this overrides the value specified by the 'resolution' parameter. The
                default setting is false.
            client_id: Filter results by network client to return per-device AP usage over time
                inner joined by the queried client's connection history.
            device_serial: Filter results by device. Requires :band.
            ap_tag: Filter results by AP tag; either :clientId or :deviceSerial must be jointly
                specified.
            band: Filter results by band (either '2.4', '5' or '6').
            ssid: Filter results by SSID number.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2020-01-01T00:00:00Z",
                "endTs": "2020-01-01T01:00:00Z",
                "totalKbps": 2590,
                "sentKbps": 159,
                "receivedKbps": 2431
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/usageHistory"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if resolution is not None:
            params["resolution"] = resolution
        if auto_resolution is not None:
            params["autoResolution"] = auto_resolution
        if client_id is not None:
            params["clientId"] = client_id
        if device_serial is not None:
            params["deviceSerial"] = device_serial
        if ap_tag is not None:
            params["apTag"] = ap_tag
        if band is not None:
            params["band"] = band
        if ssid is not None:
            params["ssid"] = ssid

        return self._session.get_pages(
            scope="wireless",
            operation_id="getNetworkWirelessUsageHistory",
            path=path,
            params=params,
            item_schema=GetNetworkWirelessUsageHistoryResponseItem,
        )

    async def update_network_wireless_zigbee(
        self,
        network_id: str,
        *,
        enabled: bool | None = None,
        iot_controller: UpdateNetworkWirelessZigbeeIotController | None = None,
        lock_management: UpdateNetworkWirelessZigbeeLockManagement | None = None,
        defaults: UpdateNetworkWirelessZigbeeDefaults | None = None,
    ) -> UpdateNetworkWirelessZigbeeResponse:
        """Update Zigbee Configs for specified network.

        [API documentation: updateNetworkWirelessZigbee](https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-zigbee)

        Args:
            network_id: Network ID.
            enabled: To enable/disable Zigbee on the network.
            iot_controller: Zigbee's IoT controller details.
            lock_management: Login Credentials of on-premises lock management.
            defaults: Default Settings for Zigbee Devices.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "network": {
                "id": "N_24329156"
              },
              "enabled": true,
              "iotController": {
                "name": "My AP",
                "mac": "e4:55:a8:38:f2:06",
                "serial": "Q234-ABCD-5678",
                "status": "online"
              },
              "lockManagement": {
                "address": "10.100.100.200",
                "username": "user",
                "status": "offline"
              },
              "defaults": {
                "transmitPowerLevel": 10,
                "channel": "25"
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/wireless/zigbee"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if iot_controller is not None:
            payload["iotController"] = iot_controller.model_dump(by_alias=True, exclude_none=True)
        if lock_management is not None:
            payload["lockManagement"] = lock_management.model_dump(by_alias=True, exclude_none=True)
        if defaults is not None:
            payload["defaults"] = defaults.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateNetworkWirelessZigbee",
            path=path,
            json=payload,
            response_schema=UpdateNetworkWirelessZigbeeResponse,
        )

    def get_organization_wireless_air_marshal_rules(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessAirMarshalRulesResponseItemsItem]:
        """Returns the current Air Marshal rules for this organization.

        [API documentation: getOrganizationWirelessAirMarshalRules](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-air-marshal-rules)

        Args:
            organization_id: Organization ID.
            network_ids: (optional) The set of network IDs to include.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "network": {
                    "id": "N_12345",
                    "name": "Network 1"
                  },
                  "ruleId": "5239",
                  "type": "allow",
                  "updatedAt": "2023-05-23 12:02:46.298",
                  "createdAt": "2023-05-23 12:02:46.298",
                  "match": {
                    "string": "ipsum",
                    "type": "contains"
                  }
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 1
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/airMarshal/rules"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessAirMarshalRules",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessAirMarshalRulesResponseItemsItem,
        )

    def get_organization_wireless_air_marshal_settings_by_network(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessAirMarshalSettingsByNetworkResponseItemsItem
    ]:
        """Returns the current Air Marshal settings for this network.

        [API documentation: getOrganizationWirelessAirMarshalSettingsByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-air-marshal-settings-by-network)

        Args:
            organization_id: Organization ID.
            network_ids: The network IDs to include in the result set.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "networkId": "N_12345",
                  "defaultPolicy": "allow"
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 1,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/airMarshal/settings/byNetwork"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessAirMarshalSettingsByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessAirMarshalSettingsByNetworkResponseItemsItem,
        )

    def get_organization_wireless_clients_overview_by_device(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        campus_gateway_cluster_ids: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessClientsOverviewByDeviceResponseItemsItem]:
        """List access point client count at the moment in an organization.

        [API documentation: getOrganizationWirelessClientsOverviewByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-clients-overview-by-device)

        Args:
            organization_id: Organization ID.
            network_ids: Optional parameter to filter access points client counts by network ID.
                This filter uses multiple exact matches.
            serials: Optional parameter to filter access points client counts by its serial numbers.
                This filter uses multiple exact matches.
            campus_gateway_cluster_ids: Optional parameter to filter access points client counts by
                MCG cluster IDs. This filter uses multiple exact matches.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "network": {
                    "id": "N_24329156"
                  },
                  "serial": "Q234-ABCD-5678",
                  "counts": {
                    "byStatus": {
                      "online": 1
                    }
                  }
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/clients/overview/byDevice"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if campus_gateway_cluster_ids is not None:
            params["campusGatewayClusterIds[]"] = campus_gateway_cluster_ids
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessClientsOverviewByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessClientsOverviewByDeviceResponseItemsItem,
        )

    def get_organization_wireless_devices_channel_utilization_by_device(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        interval: int | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesChannelUtilizationByDeviceResponseItem
    ]:
        """Get average channel utilization for all bands in a network, split by AP.

        [API documentation: getOrganizationWirelessDevicesChannelUtilizationByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-channel-utilization-by-device)

        Args:
            organization_id: Organization ID.
            network_ids: Filter results by network.
            serials: Filter results by device.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 90 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 90 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 90 days. The default is 7 days.
            interval: The time interval in seconds for returned data. The valid intervals are: 300,
                600, 3600, 7200, 14400, 21600. The default is 3600.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "serial": "Q234-ABCD-5678",
                "mac": "00:11:22:33:44:55",
                "network": {
                  "id": "N_24329156"
                },
                "byBand": [
                  {
                    "band": "5",
                    "wifi": {
                      "percentage": 33.12
                    },
                    "nonWifi": {
                      "percentage": 1.84
                    },
                    "total": {
                      "percentage": 34.96
                    }
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/channelUtilization/byDevice"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if interval is not None:
            params["interval"] = interval

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesChannelUtilizationByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesChannelUtilizationByDeviceResponseItem,
        )

    def get_organization_wireless_devices_channel_utilization_by_network(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        interval: int | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesChannelUtilizationByNetworkResponseItem
    ]:
        """Get average channel utilization across all bands for all networks in the organization.

        [API documentation: getOrganizationWirelessDevicesChannelUtilizationByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-channel-utilization-by-network)

        Args:
            organization_id: Organization ID.
            network_ids: Filter results by network.
            serials: Filter results by device.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 90 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 90 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 90 days. The default is 7 days.
            interval: The time interval in seconds for returned data. The valid intervals are: 300,
                600, 3600, 7200, 14400, 21600. The default is 3600.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "network": {
                  "id": "N_24329156"
                },
                "byBand": [
                  {
                    "band": "5",
                    "wifi": {
                      "percentage": 33.12
                    },
                    "nonWifi": {
                      "percentage": 1.84
                    },
                    "total": {
                      "percentage": 34.96
                    }
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/channelUtilization/byNetwork"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if interval is not None:
            params["interval"] = interval

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesChannelUtilizationByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesChannelUtilizationByNetworkResponseItem,
        )

    def get_organization_wireless_devices_channel_utilization_history_by_device_by_interval(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        interval: int | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesChannelUtilizationHistoryByDeviceByIntervalResponseItem
    ]:
        """Get a time-series of average channel utilization for all bands, segmented by device.

        [API documentation: getOrganizationWirelessDevicesChannelUtilizationHistoryByDeviceByInterval](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-channel-utilization-history-by-device-by-interval)

        Args:
            organization_id: Organization ID.
            network_ids: Filter results by network.
            serials: Filter results by device.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 7 days.
            interval: The time interval in seconds for returned data. The valid intervals are: 300,
                600, 3600, 7200, 14400, 21600. The default is 3600.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2018-02-11T00:00:00Z",
                "endTs": "2018-05-12T00:00:00Z",
                "serial": "Q234-ABCD-5678",
                "mac": "00:11:22:33:44:55",
                "network": {
                  "id": "N_24329156"
                },
                "byBand": [
                  {
                    "band": "5",
                    "wifi": {
                      "percentage": 33.12
                    },
                    "nonWifi": {
                      "percentage": 1.84
                    },
                    "total": {
                      "percentage": 34.96
                    }
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/channelUtilization/history/byDevice/byInterval"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if interval is not None:
            params["interval"] = interval

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesChannelUtilizationHistoryByDeviceByInterval",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesChannelUtilizationHistoryByDeviceByIntervalResponseItem,
        )

    def get_organization_wireless_devices_channel_utilization_history_by_network_by_interval(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        interval: int | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesChannelUtilizationHistoryByNetworkByIntervalResponseItem
    ]:
        """Get a time-series of average channel utilization for all bands.

        [API documentation: getOrganizationWirelessDevicesChannelUtilizationHistoryByNetworkByInterval](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-channel-utilization-history-by-network-by-interval)

        Args:
            organization_id: Organization ID.
            network_ids: Filter results by network.
            serials: Filter results by device.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 7 days.
            interval: The time interval in seconds for returned data. The valid intervals are: 300,
                600, 3600, 7200, 14400, 21600. The default is 3600.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2018-02-11T00:00:00Z",
                "endTs": "2018-05-12T00:00:00Z",
                "network": {
                  "id": "N_24329156"
                },
                "byBand": [
                  {
                    "band": "5",
                    "wifi": {
                      "percentage": 33.12
                    },
                    "nonWifi": {
                      "percentage": 1.84
                    },
                    "total": {
                      "percentage": 34.96
                    }
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/channelUtilization/history/byNetwork/byInterval"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if interval is not None:
            params["interval"] = interval

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesChannelUtilizationHistoryByNetworkByInterval",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesChannelUtilizationHistoryByNetworkByIntervalResponseItem,
        )

    def get_organization_wireless_devices_ethernet_statuses(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessDevicesEthernetStatusesResponseItem]:
        """List the most recent Ethernet link speed, duplex, aggregation and power mode and status information for wireless devices.

        [API documentation: getOrganizationWirelessDevicesEthernetStatuses](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-ethernet-statuses)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 100.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: A list of Meraki network IDs to filter results to contain only specified
                networks. E.g.: networkIds[]=N_12345678&networkIds[]=L_3456.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "serial": "Q234-ABCD-5678",
                "name": "My appliance",
                "network": {
                  "id": "N_24329156"
                },
                "power": {
                  "mode": "full",
                  "ac": {
                    "isConnected": false
                  },
                  "poe": {
                    "isConnected": true
                  }
                },
                "ports": [
                  {
                    "name": "Ethernet 0",
                    "poe": {
                      "standard": "802.3at"
                    },
                    "linkNegotiation": {
                      "duplex": "full",
                      "speed": 5000
                    }
                  }
                ],
                "aggregation": {
                  "enabled": true,
                  "speed": 10000
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/ethernet/statuses"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesEthernetStatuses",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesEthernetStatusesResponseItem,
        )

    def get_organization_wireless_devices_packet_loss_by_client(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        ssids: list[int] | None = None,
        bands: list[str] | None = None,
        macs: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessDevicesPacketLossByClientResponseItem]:
        """Get average packet loss for the given timespan for all clients in the organization.

        [API documentation: getOrganizationWirelessDevicesPacketLossByClient](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-packet-loss-by-client)

        Args:
            organization_id: Organization ID.
            network_ids: Filter results by network.
            ssids: Filter results by SSID number.
            bands: Filter results by band. Valid bands are: 2.4, 5, and 6.
            macs: Filter results by client mac address(es).
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 90 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 90 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 5 minutes and be less than or
                equal to 90 days. The default is 7 days.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "downstream": {
                  "total": 1000,
                  "lost": 10,
                  "lossPercentage": 1.0
                },
                "upstream": {
                  "total": 1200,
                  "lost": 15,
                  "lossPercentage": 1.3
                },
                "client": {
                  "id": "k74272e",
                  "mac": "22:33:44:55:66:77"
                },
                "network": {
                  "id": "N_24329156",
                  "name": "Main Office"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/packetLoss/byClient"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if ssids is not None:
            params["ssids[]"] = ssids
        if bands is not None:
            params["bands[]"] = bands
        if macs is not None:
            params["macs[]"] = macs
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesPacketLossByClient",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesPacketLossByClientResponseItem,
        )

    def get_organization_wireless_devices_packet_loss_by_device(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        ssids: list[int] | None = None,
        bands: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessDevicesPacketLossByDeviceResponseItem]:
        """Get average packet loss for the given timespan for all devices in the organization.

        [API documentation: getOrganizationWirelessDevicesPacketLossByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-packet-loss-by-device)

        Args:
            organization_id: Organization ID.
            network_ids: Filter results by network.
            serials: Filter results by device.
            ssids: Filter results by SSID number.
            bands: Filter results by band. Valid bands are: 2.4, 5, and 6.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 90 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 90 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 5 minutes and be less than or
                equal to 90 days. The default is 7 days.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "downstream": {
                  "total": 1000,
                  "lost": 10,
                  "lossPercentage": 1.0
                },
                "upstream": {
                  "total": 1200,
                  "lost": 15,
                  "lossPercentage": 1.3
                },
                "network": {
                  "id": "N_24329156",
                  "name": "Main Office"
                },
                "device": {
                  "name": "My AP",
                  "serial": "Q234-ABCD-5678",
                  "mac": "00:11:22:33:44:55"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/packetLoss/byDevice"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if ssids is not None:
            params["ssids[]"] = ssids
        if bands is not None:
            params["bands[]"] = bands
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesPacketLossByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesPacketLossByDeviceResponseItem,
        )

    def get_organization_wireless_devices_packet_loss_by_network(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        ssids: list[int] | None = None,
        bands: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessDevicesPacketLossByNetworkResponseItem]:
        """Get average packet loss for the given timespan for all networks in the organization.

        [API documentation: getOrganizationWirelessDevicesPacketLossByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-packet-loss-by-network)

        Args:
            organization_id: Organization ID.
            network_ids: Filter results by network.
            serials: Filter results by device.
            ssids: Filter results by SSID number.
            bands: Filter results by band. Valid bands are: 2.4, 5, and 6.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 90 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 90 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 5 minutes and be less than or
                equal to 90 days. The default is 7 days.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "downstream": {
                  "total": 1000,
                  "lost": 10,
                  "lossPercentage": 1.0
                },
                "upstream": {
                  "total": 1200,
                  "lost": 15,
                  "lossPercentage": 1.3
                },
                "network": {
                  "id": "N_24329156",
                  "name": "Main Office"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/packetLoss/byNetwork"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if ssids is not None:
            params["ssids[]"] = ssids
        if bands is not None:
            params["bands[]"] = bands
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesPacketLossByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesPacketLossByNetworkResponseItem,
        )

    def get_organization_wireless_devices_power_mode_history(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessDevicesPowerModeHistoryResponseItemsItem]:
        """Return a record of power mode changes for wireless devices in the organization.

        [API documentation: getOrganizationWirelessDevicesPowerModeHistory](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-power-mode-history)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 1 day
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 1 day after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 1 day. The default is 1 day.
            per_page: The number of entries per page returned. Acceptable range is 3 - 20. Default
                is 10.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter the result set by the included set of network
                IDs.
            serials: Optional parameter to filter device availabilities history by device serial
                numbers.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "serial": "Q234-ABCD-0001",
                  "model": "MR",
                  "name": "My AP",
                  "mac": "00:11:22:33:44:55",
                  "tags": [
                    "tag1",
                    "tag2"
                  ],
                  "network": {
                    "id": "N_24329156",
                    "name": "Main Office",
                    "tags": [
                      "tag1",
                      "tag2"
                    ]
                  },
                  "events": [
                    {
                      "ts": "2018-02-11T00:00:00.090210Z",
                      "powerMode": "full power"
                    }
                  ]
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/power/mode/history"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesPowerModeHistory",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesPowerModeHistoryResponseItemsItem,
        )

    def get_organization_wireless_devices_radsec_certificates_authorities(
        self, organization_id: str, *, certificate_authority_ids: list[str] | None = None
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesResponseItem
    ]:
        r"""Query for details on the organization's RADSEC device Certificate Authority certificates (CAs).

        [API documentation: getOrganizationWirelessDevicesRadsecCertificatesAuthorities](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities)

        Args:
            organization_id: Organization ID.
            certificate_authority_ids: Optional parameter to filter CAs by one or more CA IDs. All
                returned CAs will have an ID that is an exact match.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "items": [
                  {
                    "certificateAuthorityId": "1234",
                    "status": "trusted",
                    "contents": "-----BEGIN CERTIFICATE-----\nMIIDzDCCAragAwIBAgIUOd0ukLcjH43TfTHFG9qE0FtlMVgwCwYJKoZIhvcNAQEL\n...\numkqeYeO30g1uYvDuWLXVA==\n-----END CERTIFICATE-----\n"
                  }
                ],
                "meta": {
                  "counts": {
                    "items": {
                      "total": 2,
                      "remaining": 0
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/radsec/certificates/authorities"

        params: dict[str, Any] = {}
        if certificate_authority_ids is not None:
            params["certificateAuthorityIds[]"] = certificate_authority_ids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesRadsecCertificatesAuthorities",
            path=path,
            params=params,
            item_schema=GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesResponseItem,
        )

    async def update_organization_wireless_devices_radsec_certificates_authorities(
        self,
        organization_id: str,
        *,
        status: str | None = None,
        certificate_authority_id: str | None = None,
    ) -> UpdateOrganizationWirelessDevicesRadsecCertificatesAuthoritiesResponse:
        r"""Update an organization's RADSEC device Certificate Authority (CA) state.

        [API documentation: updateOrganizationWirelessDevicesRadsecCertificatesAuthorities](https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-devices-radsec-certificates-authorities)

        Args:
            organization_id: Organization ID.
            status: The "status" to update the Certificate Authority to. Only valid option is
                "trusted".
            certificate_authority_id: The ID of the Certificate Authority to update.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "certificateAuthorityId": "1234",
              "status": "trusted",
              "contents": "-----BEGIN CERTIFICATE-----\nMIIDzDCCAragAwIBAgIUOd0ukLcjH43TfTHFG9qE0FtlMVgwCwYJKoZIhvcNAQEL\n...\numkqeYeO30g1uYvDuWLXVA==\n-----END CERTIFICATE-----\n"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/radsec/certificates/authorities"

        payload: dict[str, Any] = {}
        if status is not None:
            payload["status"] = status
        if certificate_authority_id is not None:
            payload["certificateAuthorityId"] = certificate_authority_id

        return await self._session.put(
            scope="wireless",
            operation_id="updateOrganizationWirelessDevicesRadsecCertificatesAuthorities",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationWirelessDevicesRadsecCertificatesAuthoritiesResponse,
        )

    async def create_organization_wireless_devices_radsec_certificates_authority(
        self, organization_id: str
    ) -> CreateOrganizationWirelessDevicesRadsecCertificatesAuthorityResponse:
        r"""Create an organization's RADSEC device Certificate Authority (CA).

        [API documentation: createOrganizationWirelessDevicesRadsecCertificatesAuthority](https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-devices-radsec-certificates-authority)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "certificateAuthorityId": "1234",
              "status": "trusted",
              "contents": "-----BEGIN CERTIFICATE-----\nMIIDzDCCAragAwIBAgIUOd0ukLcjH43TfTHFG9qE0FtlMVgwCwYJKoZIhvcNAQEL\n...\numkqeYeO30g1uYvDuWLXVA==\n-----END CERTIFICATE-----\n"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/radsec/certificates/authorities"

        return await self._session.post(
            scope="wireless",
            operation_id="createOrganizationWirelessDevicesRadsecCertificatesAuthority",
            path=path,
            response_schema=CreateOrganizationWirelessDevicesRadsecCertificatesAuthorityResponse,
        )

    def get_organization_wireless_devices_radsec_certificates_authorities_crls(
        self, organization_id: str, *, certificate_authority_ids: list[str] | None = None
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsResponseItemsItem
    ]:
        r"""Query for certificate revocation list (CRL) for the organization's RADSEC device Certificate Authorities (CAs).

        [API documentation: getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrls](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities-crls)

        Args:
            organization_id: Organization ID.
            certificate_authority_ids: Optional parameter to filter CAs by one or more CA IDs. All
                returned CAs will have an ID that is an exact match.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "certificateAuthorityId": "1234",
                  "crl": "-----BEGIN X509 CRL-----\nMIICVjCCAj8CAQEwQQD\n...\n-----END X509 CRL-----\n"
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 2,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/radsec/certificates/authorities/crls"

        params: dict[str, Any] = {}
        if certificate_authority_ids is not None:
            params["certificateAuthorityIds[]"] = certificate_authority_ids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrls",
            path=path,
            params=params,
            item_schema=GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsResponseItemsItem,
        )

    def get_organization_wireless_devices_radsec_certificates_authorities_crls_deltas(
        self, organization_id: str, *, certificate_authority_ids: list[str] | None = None
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsDeltasResponseItemsItem
    ]:
        r"""Query for all delta certificate revocation list (CRL) for the organization's RADSEC device Certificate Authority (CA) with the given id.

        [API documentation: getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsDeltas](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities-crls-deltas)

        Args:
            organization_id: Organization ID.
            certificate_authority_ids: Parameter to filter CAs by one or more CA IDs. All returned
                CAs will have an ID that is an exact match.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "certificateAuthorityId": "1234",
                  "crl": "-----BEGIN X509 CRL-----\nMIICVjCCAj8CAQEwQQD\n...\n-----END X509 CRL-----\n"
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 2,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/radsec/certificates/authorities/crls/deltas"

        params: dict[str, Any] = {}
        if certificate_authority_ids is not None:
            params["certificateAuthorityIds[]"] = certificate_authority_ids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsDeltas",
            path=path,
            params=params,
            item_schema=GetOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsDeltasResponseItemsItem,
        )

    def get_organization_wireless_devices_system_cpu_load_history(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesSystemCpuLoadHistoryResponseItemsItem
    ]:
        """Return the CPU Load history for a list of wireless devices in the organization.

        [API documentation: getOrganizationWirelessDevicesSystemCpuLoadHistory](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-system-cpu-load-history)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 1 day
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 1 day after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 1 day. The default is 1 day.
            per_page: The number of entries per page returned. Acceptable range is 3 - 20. Default
                is 10.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter the result set by the included set of network
                IDs.
            serials: Optional parameter to filter device availabilities history by device serial
                numbers.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "serial": "Q234-ABCD-0001",
                  "model": "MR",
                  "name": "My AP",
                  "mac": "00:11:22:33:44:55",
                  "tags": [
                    "tag1",
                    "tag2"
                  ],
                  "network": {
                    "id": "N_24329156",
                    "name": "Main Office",
                    "tags": [
                      "tag1",
                      "tag2"
                    ]
                  },
                  "cpuCount": 4,
                  "series": [
                    {
                      "ts": "2018-02-11T00:00:00.090210Z",
                      "cpuLoad5": 1000
                    }
                  ]
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/system/cpu/load/history"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesSystemCpuLoadHistory",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesSystemCpuLoadHistoryResponseItemsItem,
        )

    def get_organization_wireless_devices_wireless_controllers_by_device(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        controller_serials: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessDevicesWirelessControllersByDeviceResponseItemsItem
    ]:
        """List of Catalyst access points information.

        [API documentation: getOrganizationWirelessDevicesWirelessControllersByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-wireless-controllers-by-device)

        Args:
            organization_id: Organization ID.
            network_ids: Optional parameter to filter access points by network ID. This filter uses
                multiple exact matches.
            serials: Optional parameter to filter access points by its cloud ID. This filter uses
                multiple exact matches.
            controller_serials: Optional parameter to filter access points by its wireless LAN
                controller cloud ID. This filter uses multiple exact matches.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 100.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "network": {
                    "id": "N_24329156"
                  },
                  "serial": "Q234-ABCD-5678",
                  "controller": {
                    "serial": "Q234-ABCD-5678"
                  },
                  "joinedAt": "2020-01-01T00:00:00Z",
                  "model": "C9115AXI-H",
                  "tags": [
                    {
                      "policy": "4F",
                      "site": "default-site-tag",
                      "rf": "default-rf-tag"
                    }
                  ],
                  "mode": "local",
                  "countryCode": "CA",
                  "details": [
                    {
                      "name": "catalyst serial",
                      "value": "FGL2446L7QQ"
                    }
                  ]
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/devices/wirelessControllers/byDevice"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if controller_serials is not None:
            params["controllerSerials[]"] = controller_serials
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessDevicesWirelessControllersByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessDevicesWirelessControllersByDeviceResponseItemsItem,
        )

    def get_organization_wireless_location_scanning_by_network(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessLocationScanningByNetworkResponseItemsItem]:
        """Return scanning API settings.

        [API documentation: getOrganizationWirelessLocationScanningByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-location-scanning-by-network)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 250. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter scanning settings by network ID.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "networkId": "L_1234",
                  "name": "My Network",
                  "enabled": true,
                  "api": {
                    "enabled": true,
                    "validator": {
                      "string": "sample_validator"
                    }
                  }
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/location/scanning/byNetwork"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessLocationScanningByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessLocationScanningByNetworkResponseItemsItem,
        )

    def get_organization_wireless_location_scanning_receivers(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessLocationScanningReceiversResponseItemsItem]:
        """Return scanning API receivers.

        [API documentation: getOrganizationWirelessLocationScanningReceivers](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-location-scanning-receivers)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 250. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter scanning API receivers by network ID.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "network": {
                    "id": "L_1234",
                    "name": "My Network"
                  },
                  "receiverId": "1234567",
                  "url": "https://www.myreceiver.com",
                  "version": "3",
                  "radio": {
                    "type": "Wi-Fi"
                  }
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/location/scanning/receivers"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessLocationScanningReceivers",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessLocationScanningReceiversResponseItemsItem,
        )

    async def create_organization_wireless_location_scanning_receiver(
        self,
        *,
        organization_id: str,
        network: CreateOrganizationWirelessLocationScanningReceiverNetwork,
        url: str,
        version: str,
        radio: CreateOrganizationWirelessLocationScanningReceiverRadio,
        shared_secret: str,
    ) -> CreateOrganizationWirelessLocationScanningReceiverResponse:
        """Add new receiver for scanning API.

        [API documentation: createOrganizationWirelessLocationScanningReceiver](https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-location-scanning-receiver)

        Args:
            organization_id: Organization ID.
            network: Add scanning API receiver for network.
            url: Receiver Url.
            version: Scanning API Version.
            radio: Add scanning API Radio.
            shared_secret: Secret Value for Receiver.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "network": {
                "id": "L_1234",
                "name": "My Network"
              },
              "receiverId": "1234567",
              "url": "https://www.myreceiver.com",
              "version": "3",
              "radio": {
                "type": "Wi-Fi"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/location/scanning/receivers"

        payload: dict[str, Any] = {}
        if network is not None:
            payload["network"] = network.model_dump(by_alias=True, exclude_none=True)
        if url is not None:
            payload["url"] = url
        if version is not None:
            payload["version"] = version
        if radio is not None:
            payload["radio"] = radio.model_dump(by_alias=True, exclude_none=True)
        if shared_secret is not None:
            payload["sharedSecret"] = shared_secret

        return await self._session.post(
            scope="wireless",
            operation_id="createOrganizationWirelessLocationScanningReceiver",
            path=path,
            json=payload,
            response_schema=CreateOrganizationWirelessLocationScanningReceiverResponse,
        )

    async def update_organization_wireless_location_scanning_receiver(
        self,
        *,
        organization_id: str,
        receiver_id: str,
        url: str | None = None,
        version: str | None = None,
        radio: UpdateOrganizationWirelessLocationScanningReceiverRadio | None = None,
    ) -> UpdateOrganizationWirelessLocationScanningReceiverResponse:
        """Change scanning API receiver settings.

        [API documentation: updateOrganizationWirelessLocationScanningReceiver](https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-location-scanning-receiver)

        Args:
            organization_id: Organization ID.
            receiver_id: Receiver ID.
            url: Receiver Url.
            version: Scanning API Version.
            radio: Add scanning API Radio.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "network": {
                "id": "L_1234",
                "name": "My Network"
              },
              "receiverId": "1234567",
              "url": "https://www.myreceiver.com",
              "version": "3",
              "radio": {
                "type": "Wi-Fi"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        receiver_id = urllib.parse.quote(str(receiver_id), safe="")
        path = (
            f"/organizations/{organization_id}/wireless/location/scanning/receivers/{receiver_id}"
        )

        payload: dict[str, Any] = {}
        if url is not None:
            payload["url"] = url
        if version is not None:
            payload["version"] = version
        if radio is not None:
            payload["radio"] = radio.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateOrganizationWirelessLocationScanningReceiver",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationWirelessLocationScanningReceiverResponse,
        )

    async def delete_organization_wireless_location_scanning_receiver(
        self, *, organization_id: str, receiver_id: str
    ) -> None:
        """Delete a scanning API receiver.

        [API documentation: deleteOrganizationWirelessLocationScanningReceiver](https://developer.cisco.com/meraki/api-v1/#!delete-organization-wireless-location-scanning-receiver)

        Args:
            organization_id: Organization ID.
            receiver_id: Receiver ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        receiver_id = urllib.parse.quote(str(receiver_id), safe="")
        path = (
            f"/organizations/{organization_id}/wireless/location/scanning/receivers/{receiver_id}"
        )

        return await self._session.delete(
            scope="wireless",
            operation_id="deleteOrganizationWirelessLocationScanningReceiver",
            path=path,
        )

    def get_organization_wireless_mqtt_settings(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessMqttSettingsResponseItemsItem]:
        """Return MQTT Settings for networks.

        [API documentation: getOrganizationWirelessMqttSettings](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-mqtt-settings)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 250. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter mqtt settings by network ID.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "network": {
                    "id": "L_1234",
                    "name": "My Network"
                  },
                  "mqtt": {
                    "settingsId": "1234567",
                    "enabled": true,
                    "topic": "Test Topic",
                    "messageFields": [
                      "RSSI",
                      "AP MAC address",
                      "Client MAC address",
                      "Timestamp",
                      "Radio",
                      "Network ID",
                      "Beacon type",
                      "Raw payload",
                      "Client UUID",
                      "Client major value",
                      "Client minor value",
                      "Signal power",
                      "Band",
                      "Slot ID"
                    ],
                    "publishing": {
                      "frequency": 1,
                      "qos": 1
                    },
                    "broker": {
                      "id": "1234",
                      "name": "My Broker"
                    }
                  },
                  "ble": {
                    "enabled": false,
                    "type": "ibeacon",
                    "flush": {
                      "frequency": 60
                    },
                    "allowLists": {
                      "uuids": [],
                      "macs": []
                    },
                    "hysteresis": {
                      "enabled": true,
                      "threshold": 1
                    }
                  },
                  "wifi": {
                    "enabled": false,
                    "type": "associated",
                    "flush": {
                      "frequency": 60
                    },
                    "allowLists": {
                      "macs": []
                    },
                    "hysteresis": {
                      "enabled": false,
                      "threshold": 1
                    }
                  }
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/mqtt/settings"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessMqttSettings",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessMqttSettingsResponseItemsItem,
        )

    async def update_organization_wireless_mqtt_settings(
        self,
        *,
        organization_id: str,
        network: UpdateOrganizationWirelessMqttSettingsNetwork,
        mqtt: UpdateOrganizationWirelessMqttSettingsMqtt,
        ble: UpdateOrganizationWirelessMqttSettingsBle | None = None,
        wifi: UpdateOrganizationWirelessMqttSettingsWifi | None = None,
    ) -> UpdateOrganizationWirelessMqttSettingsResponse:
        """Add new broker config for wireless MQTT.

        [API documentation: updateOrganizationWirelessMqttSettings](https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-mqtt-settings)

        Args:
            organization_id: Organization ID.
            network: Add MQTT Settings for network.
            mqtt: MQTT Settings for network.
            ble: MQTT BLE Settings for network.
            wifi: MQTT Wi-Fi Settings for network.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "network": {
                "id": "L_1234",
                "name": "My Network"
              },
              "mqtt": {
                "settingsId": "1234567",
                "enabled": true,
                "topic": "Test Topic",
                "messageFields": [
                  "RSSI",
                  "AP MAC address",
                  "Client MAC address",
                  "Timestamp",
                  "Radio",
                  "Network ID",
                  "Beacon type",
                  "Raw payload",
                  "Client UUID",
                  "Client major value",
                  "Client minor value",
                  "Signal power",
                  "Band",
                  "Slot ID"
                ],
                "publishing": {
                  "frequency": 1,
                  "qos": 1
                },
                "broker": {
                  "id": "1234",
                  "name": "My Broker"
                }
              },
              "ble": {
                "enabled": false,
                "type": "ibeacon",
                "flush": {
                  "frequency": 60
                },
                "allowLists": {
                  "uuids": [],
                  "macs": []
                },
                "hysteresis": {
                  "enabled": true,
                  "threshold": 1
                }
              },
              "wifi": {
                "enabled": false,
                "type": "associated",
                "flush": {
                  "frequency": 60
                },
                "allowLists": {
                  "macs": []
                },
                "hysteresis": {
                  "enabled": false,
                  "threshold": 1
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/mqtt/settings"

        payload: dict[str, Any] = {}
        if network is not None:
            payload["network"] = network.model_dump(by_alias=True, exclude_none=True)
        if mqtt is not None:
            payload["mqtt"] = mqtt.model_dump(by_alias=True, exclude_none=True)
        if ble is not None:
            payload["ble"] = ble.model_dump(by_alias=True, exclude_none=True)
        if wifi is not None:
            payload["wifi"] = wifi.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateOrganizationWirelessMqttSettings",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationWirelessMqttSettingsResponse,
        )

    async def recalculate_organization_wireless_radio_auto_rf_channels(
        self, *, organization_id: str, network_ids: list[str]
    ) -> RecalculateOrganizationWirelessRadioAutoRfChannelsResponse:
        """Recalculates automatically assigned channels for every AP within specified the specified network(s).

        [API documentation: recalculateOrganizationWirelessRadioAutoRfChannels](https://developer.cisco.com/meraki/api-v1/#!recalculate-organization-wireless-radio-auto-rf-channels)

        Args:
            organization_id: Organization ID.
            network_ids: A list of network ids (limit: 15).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "estimatedCompletedAt": "2019-01-01T00:00:00Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/radio/autoRf/channels/recalculate"

        payload: dict[str, Any] = {}
        if network_ids is not None:
            payload["networkIds"] = network_ids

        return await self._session.post(
            scope="wireless",
            operation_id="recalculateOrganizationWirelessRadioAutoRfChannels",
            path=path,
            json=payload,
            response_schema=RecalculateOrganizationWirelessRadioAutoRfChannelsResponse,
        )

    def get_organization_wireless_radio_rrm_by_network(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        per_page: int | None = None,
        sort_order: GetOrganizationWirelessRadioRrmByNetworkSortOrder | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessRadioRrmByNetworkResponseItemsItem]:
        """List the AutoRF settings of an organization by network.

        [API documentation: getOrganizationWirelessRadioRrmByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-radio-rrm-by-network)

        Args:
            organization_id: Organization ID.
            network_ids: Optional parameter to filter results by network.
            starting_after: Retrieving items after this network ID.
            ending_before: Retrieving items before this network ID.
            per_page: Number of items per page.
            sort_order: The sort order of items.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "networkId": "L_12345",
                  "name": "My Network",
                  "timeZone": "America/Los_Angeles",
                  "busyHour": {
                    "schedule": {
                      "mode": "automatic",
                      "automatic": {
                        "start": "08:00",
                        "end": "17:00"
                      },
                      "manual": {
                        "start": "10:00",
                        "end": "15:00"
                      }
                    },
                    "minimizeChanges": {
                      "enabled": true
                    }
                  },
                  "channel": {
                    "avoidance": {
                      "enabled": true
                    }
                  },
                  "fra": {
                    "enabled": false
                  },
                  "ai": {
                    "enabled": true,
                    "lastEnabledAt": "2026-01-04T09:07:45Z"
                  }
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 42,
                    "remaining": 5
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/radio/rrm/byNetwork"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if per_page is not None:
            params["perPage"] = per_page
        if sort_order is not None:
            params["sortOrder"] = sort_order

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessRadioRrmByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessRadioRrmByNetworkResponseItemsItem,
        )

    def get_organization_wireless_rf_profiles_assignments_by_device(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        product_types: GetOrganizationWirelessRfProfilesAssignmentsByDeviceProductTypes
        | None = None,
        name: str | None = None,
        mac: str | None = None,
        serial: str | None = None,
        model: str | None = None,
        macs: list[str] | None = None,
        serials: list[str] | None = None,
        models: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessRfProfilesAssignmentsByDeviceResponseItem]:
        """List the RF profiles of an organization by device.

        [API documentation: getOrganizationWirelessRfProfilesAssignmentsByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-rf-profiles-assignments-by-device)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter devices by network.
            product_types: Optional parameter to filter devices by product type. Valid types are
                wireless, appliance, switch, systemsManager, camera, cellularGateway,
                sensor, wirelessController, campusGateway, and secureConnect.
            name: Optional parameter to filter RF profiles by device name. All returned devices will
                have a name that contains the search term or is an exact match.
            mac: Optional parameter to filter RF profiles by device MAC address. All returned
                devices will have a MAC address that contains the search term or is an
                exact match.
            serial: Optional parameter to filter RF profiles by device serial number. All returned
                devices will have a serial number that contains the search term or is an
                exact match.
            model: Optional parameter to filter RF profiles by device model. All returned devices
                will have a model that contains the search term or is an exact match.
            macs: Optional parameter to filter RF profiles by one or more device MAC addresses. All
                returned devices will have a MAC address that is an exact match.
            serials: Optional parameter to filter RF profiles by one or more device serial numbers.
                All returned devices will have a serial number that is an exact match.
            models: Optional parameter to filter RF profiles by one or more device models. All
                returned devices will have a model that is an exact match.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "items": [
                  {
                    "network": {
                      "id": "1234"
                    },
                    "name": "Device_name",
                    "serial": "Q234-ABCD-0001",
                    "model": "MR34",
                    "rfProfile": {
                      "id": "123456",
                      "name": "Basic Outdoor Profile",
                      "isIndoorDefault": false,
                      "isOutdoorDefault": true
                    }
                  }
                ],
                "meta": {
                  "counts": {
                    "items": {
                      "total": 1200,
                      "remaining": 200
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/rfProfiles/assignments/byDevice"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if product_types is not None:
            params["productTypes[]"] = product_types
        if name is not None:
            params["name"] = name
        if mac is not None:
            params["mac"] = mac
        if serial is not None:
            params["serial"] = serial
        if model is not None:
            params["model"] = model
        if macs is not None:
            params["macs[]"] = macs
        if serials is not None:
            params["serials[]"] = serials
        if models is not None:
            params["models[]"] = models

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessRfProfilesAssignmentsByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessRfProfilesAssignmentsByDeviceResponseItem,
        )

    def get_organization_wireless_ssids_firewall_isolation_allowlist_entries(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        ssids: GetOrganizationWirelessSsidsFirewallIsolationAllowlistEntriesSsids | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[
        GetOrganizationWirelessSsidsFirewallIsolationAllowlistEntriesResponseItemsItem
    ]:
        """List the L2 isolation allow list MAC entry in an organization.

        [API documentation: getOrganizationWirelessSsidsFirewallIsolationAllowlistEntries](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-ssids-firewall-isolation-allowlist-entries)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: networkIds array to filter out results.
            ssids: ssids number array to filter out results.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "entryId": "1",
                  "createdAt": "2024-11-11T07:16:38Z",
                  "lastUpdatedAt": "2024-11-11T07:16:38Z",
                  "description": "Example mac address",
                  "client": {
                    "mac": "A1:B2:C3:D4:E5:F6"
                  },
                  "ssid": {
                    "id": "5",
                    "name": "Test SSID",
                    "number": 2
                  },
                  "network": {
                    "id": "N_123",
                    "name": "Test network"
                  }
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 1,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = (
            f"/organizations/{organization_id}/wireless/ssids/firewall/isolation/allowlist/entries"
        )

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if ssids is not None:
            params["ssids[]"] = ssids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessSsidsFirewallIsolationAllowlistEntries",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessSsidsFirewallIsolationAllowlistEntriesResponseItemsItem,
        )

    async def create_organization_wireless_ssids_firewall_isolation_allowlist_entry(
        self,
        *,
        organization_id: str,
        client: CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryClient,
        ssid: CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntrySsid,
        network: CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryNetwork,
        description: str | None = None,
    ) -> CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryResponse:
        """Create isolation allow list MAC entry for this organization.

        [API documentation: createOrganizationWirelessSsidsFirewallIsolationAllowlistEntry](https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-ssids-firewall-isolation-allowlist-entry)

        Args:
            organization_id: Organization ID.
            description: The description of mac address.
            client: The client of allowlist.
            ssid: The SSID that allowlist belongs to.
            network: The Network that allowlist belongs to.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "entryId": "1",
              "createdAt": "2024-11-11T07:16:38Z",
              "lastUpdatedAt": "2024-11-11T07:16:38Z",
              "description": "Example mac address",
              "client": {
                "mac": "A1:B2:C3:D4:E5:F6"
              },
              "ssid": {
                "id": "5",
                "name": "Test SSID",
                "number": 2
              },
              "network": {
                "id": "N_123",
                "name": "Test network"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = (
            f"/organizations/{organization_id}/wireless/ssids/firewall/isolation/allowlist/entries"
        )

        payload: dict[str, Any] = {}
        if description is not None:
            payload["description"] = description
        if client is not None:
            payload["client"] = client.model_dump(by_alias=True, exclude_none=True)
        if ssid is not None:
            payload["ssid"] = ssid.model_dump(by_alias=True, exclude_none=True)
        if network is not None:
            payload["network"] = network.model_dump(by_alias=True, exclude_none=True)

        return await self._session.post(
            scope="wireless",
            operation_id="createOrganizationWirelessSsidsFirewallIsolationAllowlistEntry",
            path=path,
            json=payload,
            response_schema=CreateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryResponse,
        )

    async def update_organization_wireless_ssids_firewall_isolation_allowlist_entry(
        self,
        *,
        organization_id: str,
        entry_id: str,
        description: str | None = None,
        client: UpdateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryClient | None = None,
    ) -> UpdateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryResponse:
        """Update isolation allow list MAC entry info.

        [API documentation: updateOrganizationWirelessSsidsFirewallIsolationAllowlistEntry](https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-ssids-firewall-isolation-allowlist-entry)

        Args:
            organization_id: Organization ID.
            entry_id: Entry ID.
            description: The description of mac address.
            client: The client of allowlist.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "entryId": "1",
              "createdAt": "2024-11-11T07:16:38Z",
              "lastUpdatedAt": "2024-11-11T07:16:38Z",
              "description": "Example mac address",
              "client": {
                "mac": "A1:B2:C3:D4:E5:F6"
              },
              "ssid": {
                "id": "5",
                "name": "Test SSID",
                "number": 2
              },
              "network": {
                "id": "N_123",
                "name": "Test network"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        entry_id = urllib.parse.quote(str(entry_id), safe="")
        path = f"/organizations/{organization_id}/wireless/ssids/firewall/isolation/allowlist/entries/{entry_id}"

        payload: dict[str, Any] = {}
        if description is not None:
            payload["description"] = description
        if client is not None:
            payload["client"] = client.model_dump(by_alias=True, exclude_none=True)

        return await self._session.put(
            scope="wireless",
            operation_id="updateOrganizationWirelessSsidsFirewallIsolationAllowlistEntry",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationWirelessSsidsFirewallIsolationAllowlistEntryResponse,
        )

    async def delete_organization_wireless_ssids_firewall_isolation_allowlist_entry(
        self, *, organization_id: str, entry_id: str
    ) -> None:
        """Destroy isolation allow list MAC entry for this organization.

        [API documentation: deleteOrganizationWirelessSsidsFirewallIsolationAllowlistEntry](https://developer.cisco.com/meraki/api-v1/#!delete-organization-wireless-ssids-firewall-isolation-allowlist-entry)

        Args:
            organization_id: Organization ID.
            entry_id: Entry ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        entry_id = urllib.parse.quote(str(entry_id), safe="")
        path = f"/organizations/{organization_id}/wireless/ssids/firewall/isolation/allowlist/entries/{entry_id}"

        return await self._session.delete(
            scope="wireless",
            operation_id="deleteOrganizationWirelessSsidsFirewallIsolationAllowlistEntry",
            path=path,
        )

    def get_organization_wireless_ssids_open_roaming_by_network(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        include_disabled_ssids: bool | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessSsidsOpenRoamingByNetworkResponseItemsItem]:
        """Returns an array of objects, each containing SSID OpenRoaming configs for the corresponding network.

        [API documentation: getOrganizationWirelessSsidsOpenRoamingByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-ssids-open-roaming-by-network)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter OpenRoaming configuration by Network Id.
            include_disabled_ssids: Optional parameter to include OpenRoaming configuration for
                disabled ssids.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "networkId": "N_1234",
                  "networkName": "MR wireless 1",
                  "ssid": [
                    {
                      "name": "SSID 0",
                      "number": 0,
                      "enabled": true,
                      "openRoaming": {
                        "enabled": true,
                        "tenantId": "12345"
                      }
                    }
                  ]
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 105,
                    "remaining": 25
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/ssids/openRoaming/byNetwork"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if include_disabled_ssids is not None:
            params["includeDisabledSsids"] = include_disabled_ssids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessSsidsOpenRoamingByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessSsidsOpenRoamingByNetworkResponseItemsItem,
        )

    def get_organization_wireless_ssids_statuses_by_device(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        bssids: list[str] | None = None,
        hide_disabled: bool | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessSsidsStatusesByDeviceResponseItemsItem]:
        """List status information of all BSSIDs in your organization.

        [API documentation: getOrganizationWirelessSsidsStatusesByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-ssids-statuses-by-device)

        Args:
            organization_id: Organization ID.
            network_ids: Optional parameter to filter the result set by the included set of network
                IDs.
            serials: A list of serial numbers. The returned devices will be filtered to only include
                these serials.
            bssids: A list of BSSIDs. The returned devices will be filtered to only include these
                BSSIDs.
            hide_disabled: If true, the returned devices will not include disabled SSIDs. (default:
                true).
            per_page: The number of entries per page returned. Acceptable range is 3 - 500. Default
                is 100.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "serial": "QQ3A-QHWY-DQ2Z",
                  "name": "My AP",
                  "network": {
                    "id": "N_24329156",
                    "name": "Main Office"
                  },
                  "basicServiceSets": [
                    {
                      "bssid": "8A:15:04:00:00:00",
                      "ssid": {
                        "name": "My SSID",
                        "number": 0,
                        "enabled": true,
                        "advertised": true
                      },
                      "radio": {
                        "band": "2.4",
                        "channel": 11,
                        "channelWidth": 20,
                        "power": 18,
                        "isBroadcasting": true,
                        "index": "0"
                      }
                    }
                  ]
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 1738,
                    "remaining": 1238
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/ssids/statuses/byDevice"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if bssids is not None:
            params["bssids[]"] = bssids
        if hide_disabled is not None:
            params["hideDisabled"] = hide_disabled
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessSsidsStatusesByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessSsidsStatusesByDeviceResponseItemsItem,
        )

    def get_organization_wireless_zigbee_by_network(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessZigbeeByNetworkResponseItem]:
        """Return list of Zigbee configs.

        [API documentation: getOrganizationWirelessZigbeeByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-zigbee-by-network)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Filter by specified Network IDs.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "network": {
                  "id": "N_24329156"
                },
                "enabled": true,
                "iotController": {
                  "name": "My AP",
                  "mac": "e4:55:a8:38:f2:06",
                  "serial": "Q234-ABCD-5678",
                  "status": "online"
                },
                "lockManagement": {
                  "address": "10.100.100.200",
                  "username": "user",
                  "status": "offline"
                },
                "defaults": {
                  "transmitPowerLevel": 10,
                  "channel": "25"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/zigbee/byNetwork"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessZigbeeByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessZigbeeByNetworkResponseItem,
        )

    def get_organization_wireless_zigbee_devices(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        is_enrolled: bool | None = None,
        search: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessZigbeeDevicesResponseItem]:
        """List the Zigbee wireless devices for an organization or the supplied network(s).

        [API documentation: getOrganizationWirelessZigbeeDevices](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-zigbee-devices)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 10.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Parameter of networks you want the zigbee devices for. E.g.:
                networkIds[]=N_12345678&networkIds[]=N_3456.
            is_enrolled: Filter devices based on if they are enrolled or not.
            search: Filter devices by their name, tag or serial.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "network": {
                  "id": "N_1234",
                  "name": "Main office"
                },
                "panId": "0x0100",
                "channel": "auto",
                "transmitPowerLevel": 12,
                "enrolled": true,
                "status": "online",
                "gateway": {
                  "name": "Wireless gateway",
                  "mac": "e4:55:a8:38:f2:06",
                  "serial": "1234-4567-5678",
                  "tags": [
                    "tag1",
                    "tag2"
                  ]
                },
                "counts": {
                  "doorLocks": {
                    "byStatus": {
                      "online": 5,
                      "offline": 2,
                      "dormant": 0
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/zigbee/devices"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if is_enrolled is not None:
            params["isEnrolled"] = is_enrolled
        if search is not None:
            params["search"] = search

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessZigbeeDevices",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessZigbeeDevicesResponseItem,
        )

    async def update_organization_wireless_zigbee_device(
        self, *, organization_id: str, id: str, enrolled: bool, channel: str | None = None
    ) -> UpdateOrganizationWirelessZigbeeDeviceResponse:
        """Endpoint to update zigbee gateways.

        [API documentation: updateOrganizationWirelessZigbeeDevice](https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-zigbee-device)

        Args:
            organization_id: Organization ID.
            id: ID.
            enrolled: Parameter to enroll or unenroll the zigbee devices.
            channel: The new channel for the zigbee device.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "network": {
                "id": "N_1234",
                "name": "Main office"
              },
              "panId": "0x0100",
              "channel": "auto",
              "transmitPowerLevel": 12,
              "enrolled": true,
              "status": "online",
              "gateway": {
                "name": "Wireless gateway",
                "mac": "e4:55:a8:38:f2:06",
                "serial": "1234-4567-5678",
                "tags": [
                  "tag1",
                  "tag2"
                ]
              },
              "counts": {
                "doorLocks": {
                  "byStatus": {
                    "online": 5,
                    "offline": 2,
                    "dormant": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/wireless/zigbee/devices/{id}"

        payload: dict[str, Any] = {}
        if enrolled is not None:
            payload["enrolled"] = enrolled
        if channel is not None:
            payload["channel"] = channel

        return await self._session.put(
            scope="wireless",
            operation_id="updateOrganizationWirelessZigbeeDevice",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationWirelessZigbeeDeviceResponse,
        )

    async def create_organization_wireless_zigbee_disenrollment(
        self, organization_id: str, *, door_lock_ids: list[str] | None = None
    ) -> CreateOrganizationWirelessZigbeeDisenrollmentResponse:
        """Enqueue a job to start disenrolling door locks on zigbee configured wireless devices.

        [API documentation: createOrganizationWirelessZigbeeDisenrollment](https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-zigbee-disenrollment)

        Args:
            organization_id: Organization ID.
            door_lock_ids: A list of Meraki door lock ids to disenroll from the device.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "disenrollmentId": "1234",
              "url": "/organization/{organizationId}/wireless/zigbee/disenrollments/1234",
              "request": {
                "doorLockIds": [
                  "1234"
                ]
              },
              "status": "complete"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/zigbee/disenrollments"

        payload: dict[str, Any] = {}
        if door_lock_ids is not None:
            payload["doorLockIds"] = door_lock_ids

        return await self._session.post(
            scope="wireless",
            operation_id="createOrganizationWirelessZigbeeDisenrollment",
            path=path,
            json=payload,
            response_schema=CreateOrganizationWirelessZigbeeDisenrollmentResponse,
        )

    async def get_organization_wireless_zigbee_disenrollment(
        self, *, organization_id: str, disenrollment_id: str
    ) -> GetOrganizationWirelessZigbeeDisenrollmentResponse:
        """Return a disenrollment.

        [API documentation: getOrganizationWirelessZigbeeDisenrollment](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-zigbee-disenrollment)

        Args:
            organization_id: Organization ID.
            disenrollment_id: Disenrollment ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "disenrollmentId": "1234",
              "url": "/organization/{organizationId}/wireless/zigbee/disenrollments/1234",
              "request": {
                "doorLockIds": [
                  "1234"
                ]
              },
              "status": "complete",
              "doorLocks": [
                {
                  "doorLockId": "1234",
                  "status": "success"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        disenrollment_id = urllib.parse.quote(str(disenrollment_id), safe="")
        path = f"/organizations/{organization_id}/wireless/zigbee/disenrollments/{disenrollment_id}"

        return await self._session.get(
            scope="wireless",
            operation_id="getOrganizationWirelessZigbeeDisenrollment",
            path=path,
            response_schema=GetOrganizationWirelessZigbeeDisenrollmentResponse,
        )

    def get_organization_wireless_zigbee_door_locks(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        serial: str | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> AsyncPaginatedResponse[GetOrganizationWirelessZigbeeDoorLocksResponseItem]:
        """Return the list of door locks for a network.

        [API documentation: getOrganizationWirelessZigbeeDoorLocks](https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-zigbee-door-locks)

        Args:
            organization_id: Organization ID.
            network_ids: Filter by specified Network IDs.
            serial: Filter by device serial.
            per_page: The number of entries per page returned. Acceptable range is 3 - 500. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy AsyncPaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "doorLockId": "1",
                "name": "Door Lock 123",
                "shortId": "ABE123",
                "lqi": "1",
                "rssi": "1",
                "status": "online",
                "eui64": "DL403",
                "enrolledAt": "2023-08-14T19:57:06Z",
                "lastSeenAt": "2023-08-14T19:59:01Z",
                "network": {
                  "id": "N_24329156",
                  "name": "Main Office"
                },
                "gateway": {
                  "name": "My AP",
                  "serial": "Q234-ABCD-5678"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/wireless/zigbee/doorLocks"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serial is not None:
            params["serial"] = serial
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="wireless",
            operation_id="getOrganizationWirelessZigbeeDoorLocks",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWirelessZigbeeDoorLocksResponseItem,
        )

    async def update_organization_wireless_zigbee_door_lock(
        self, *, organization_id: str, door_lock_id: str, name: str | None = None
    ) -> UpdateOrganizationWirelessZigbeeDoorLockResponse:
        """Endpoint to batch update door locks params.

        [API documentation: updateOrganizationWirelessZigbeeDoorLock](https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-zigbee-door-lock)

        Args:
            organization_id: Organization ID.
            door_lock_id: Door lock ID.
            name: Door lock name to update.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "doorLockId": "1",
              "name": "Door Lock 123",
              "shortId": "ABE123",
              "lqi": "1",
              "rssi": "1",
              "status": "online",
              "eui64": "DL403",
              "enrolledAt": "2023-08-14T19:57:06Z",
              "lastSeenAt": "2023-08-14T19:59:01Z",
              "network": {
                "id": "N_24329156",
                "name": "Main Office"
              },
              "gateway": {
                "name": "My AP",
                "serial": "Q234-ABCD-5678"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        door_lock_id = urllib.parse.quote(str(door_lock_id), safe="")
        path = f"/organizations/{organization_id}/wireless/zigbee/doorLocks/{door_lock_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name

        return await self._session.put(
            scope="wireless",
            operation_id="updateOrganizationWirelessZigbeeDoorLock",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationWirelessZigbeeDoorLockResponse,
        )
