findmy.scanner.scanner
======================

.. py:module:: findmy.scanner.scanner

.. autoapi-nested-parse::

   Airtag scanner.



Attributes
----------

.. autoapisummary::

   findmy.scanner.scanner.logger
   findmy.scanner.scanner.APPLE_DEVICE_TYPE
   findmy.scanner.scanner.BATTERY_LEVEL


Classes
-------

.. autoapisummary::

   findmy.scanner.scanner.OfflineFindingDevice
   findmy.scanner.scanner.NearbyOfflineFindingDevice
   findmy.scanner.scanner.SeparatedOfflineFindingDevice
   findmy.scanner.scanner.OfflineFindingScanner


Module Contents
---------------

.. py:data:: logger

.. py:data:: APPLE_DEVICE_TYPE

.. py:data:: BATTERY_LEVEL

.. py:class:: OfflineFindingDevice(mac_bytes: bytes, status_byte: int, detected_at: datetime.datetime, rssi: int | None = None, additional_data: dict[Any, Any] | None = None)

   Bases: :py:obj:`abc.ABC`

   .. autoapi-inheritance-diagram:: findmy.scanner.scanner.OfflineFindingDevice
      :parts: 1


   Device discoverable through Apple's bluetooth-based Offline Finding protocol.


   .. py:attribute:: OF_HEADER_SIZE
      :value: 2



   .. py:attribute:: OF_TYPE
      :value: 18



   .. py:property:: mac_address
      :type: str


      MAC address of the device in AA:BB:CC:DD:EE:FF format.



   .. py:property:: status
      :type: int


      Status value as reported by the device.



   .. py:property:: detected_at
      :type: datetime.datetime


      Timezone-aware datetime of when the device was detected.



   .. py:property:: rssi
      :type: int | None


      Received Signal Strength Indicator (RSSI) value.



   .. py:property:: additional_data
      :type: dict[Any, Any]


      Any additional data. No guarantees about the contents of this dictionary.



   .. py:property:: device_type
      :type: str


      Get the device type from status byte.



   .. py:property:: battery_level
      :type: str


      Get the battery level from status byte.



   .. py:method:: is_from(other_device: findmy.keys.HasPublicKey | findmy.accessory.RollingKeyPairSource) -> bool
      :abstractmethod:


      Check whether the OF device's identity originates from a specific key source.



   .. py:method:: print(file: _typeshed.SupportsWrite[str] | None = None) -> None
      :abstractmethod:


      Print human-readable information about the device to stdout or file.



   .. py:method:: from_payload(mac_address: str, payload: bytes, detected_at: datetime.datetime, rssi: int | None = None, additional_data: dict[Any, Any] | None = None) -> OfflineFindingDevice | None
      :classmethod:

      :abstractmethod:


      Get a NearbyOfflineFindingDevice object from an OF message payload.



   .. py:method:: from_ble_payload(mac_address: str, ble_payload: bytes, detected_at: datetime.datetime | None = None, rssi: int | None = None, additional_data: dict[Any, Any] | None = None) -> OfflineFindingDevice | None
      :classmethod:


      Get a NearbyOfflineFindingDevice object from a BLE packet payload.



   .. py:method:: __eq__(other: object) -> bool


   .. py:method:: __hash__() -> int


.. py:class:: NearbyOfflineFindingDevice(mac_bytes: bytes, status_byte: int, first_adv_key_bytes: bytes, detected_at: datetime.datetime, rssi: int | None = None, additional_data: dict[Any, Any] | None = None)

   Bases: :py:obj:`OfflineFindingDevice`

   .. autoapi-inheritance-diagram:: findmy.scanner.scanner.NearbyOfflineFindingDevice
      :parts: 1


   Offline-Finding device in nearby state.


   .. py:attribute:: OF_PAYLOAD_LEN
      :value: 2



   .. py:property:: partial_adv_key
      :type: bytes


      Although not a full public key, still identifies device like one.



   .. py:method:: is_from(other_device: findmy.keys.HasPublicKey | findmy.accessory.RollingKeyPairSource) -> bool

      Check whether the OF device's identity originates from a specific key source.



   .. py:method:: from_payload(mac_address: str, payload: bytes, detected_at: datetime.datetime, rssi: int | None = None, additional_data: dict[Any, Any] | None = None) -> NearbyOfflineFindingDevice | None
      :classmethod:


      Get a NearbyOfflineFindingDevice object from an OF message payload.



   .. py:method:: print(file: _typeshed.SupportsWrite[str] | None = None) -> None

      Print human-readable information about the device to stdout or file.



.. py:class:: SeparatedOfflineFindingDevice(mac_bytes: bytes, status: int, public_key: bytes, hint: int, detected_at: datetime.datetime, rssi: int | None = None, additional_data: dict[Any, Any] | None = None)

   Bases: :py:obj:`OfflineFindingDevice`, :py:obj:`findmy.keys.HasPublicKey`

   .. autoapi-inheritance-diagram:: findmy.scanner.scanner.SeparatedOfflineFindingDevice
      :parts: 1


   Offline-Finding device in separated state.


   .. py:attribute:: OF_PAYLOAD_LEN
      :value: 25



   .. py:property:: hint
      :type: int


      Hint value as reported by the device.



   .. py:property:: adv_key_bytes
      :type: bytes


      See :meth:`HasPublicKey.adv_key_bytes`.



   .. py:method:: is_from(other_device: findmy.keys.HasPublicKey | findmy.accessory.RollingKeyPairSource) -> bool

      Check whether the OF device's identity originates from a specific key source.



   .. py:method:: from_payload(mac_address: str, payload: bytes, detected_at: datetime.datetime, rssi: int | None = None, additional_data: dict[Any, Any] | None = None) -> SeparatedOfflineFindingDevice | None
      :classmethod:


      Get a SeparatedOfflineFindingDevice object from an OF message payload.



   .. py:method:: print(file: _typeshed.SupportsWrite[str] | None = None) -> None

      Print human-readable information about the device to stdout or file.



   .. py:method:: __repr__() -> str

      Human-readable string representation of an OfflineFindingDevice.



.. py:class:: OfflineFindingScanner(loop: asyncio.AbstractEventLoop)

   BLE scanner that searches for :meth:`OfflineFindingDevice`s.


   .. py:attribute:: BLE_COMPANY_APPLE
      :value: 76



   .. py:method:: create() -> OfflineFindingScanner
      :classmethod:

      :async:


      Create an instance of the scanner.



   .. py:method:: scan_for(timeout: float = 10, *, extend_timeout: bool = False, print_summary: bool = False) -> collections.abc.AsyncGenerator[OfflineFindingDevice, None]
      :async:


      Scan for :meth:`OfflineFindingDevice`s for up to :meth:`timeout` seconds.

      If :meth:`extend_timeout` is set, the timer will be extended
      by :meth:`timeout` seconds every time a new device is discovered.



