Skip to content

Enumeration


# coding=utf-8
# =============================================================================
# Copyright (c) 2026 FLIR Integrated Imaging Solutions, Inc. All Rights Reserved.
#
# This software is the confidential and proprietary information of FLIR
# Integrated Imaging Solutions, Inc. ("Confidential Information"). You
# shall not disclose such Confidential Information and shall use it only in
# accordance with the terms of the license agreement you entered into
# with FLIR Integrated Imaging Solutions, Inc. (FLIR).
#
# FLIR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
# SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE, OR NON-INFRINGEMENT. FLIR SHALL NOT BE LIABLE FOR ANY DAMAGES
# SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
# THIS SOFTWARE OR ITS DERIVATIVES.
# =============================================================================
#
# Enumeration.py shows how to enumerate interfaces and cameras.
# Knowing this is mandatory for doing anything with the Spinnaker SDK, and is 
# therefore the best place to start learning how to use the SDK.
#  
# This example introduces the preparation, use, and cleanup of the system
# object, interface and camera lists, interfaces, and cameras. It also touches
# upon retrieving both nodes from nodemaps and information from nodes.
#  
# Once comfortable with enumeration, we suggest checking out the Acquisition and/or
# NodeMapInfo examples. Acquisition demonstrates using a camera to acquire images,
# and NodeMapInfo demonstrates retrieving information from various node types.
#
# Please leave us feedback at: https://www.surveymonkey.com/r/TDYMVAPI
# More source code examples at: https://github.com/Teledyne-MV/Spinnaker-Examples
# Need help? Check out our forum at: https://teledynevisionsolutions.zendesk.com/hc/en-us/community/topics

import PySpin
import sys


def query_interface(interface):
    """
    Queries an interface for its cameras and prints out device information.

    :param interface: InterfacePtr
    :return: True if successful, False otherwise.
    :rtype: bool
    """

    try:
        result = True

        # Retrieve TL nodemap from interface
        #
        # *** NOTES ***
        # Each interface has a nodemap that can be retrieved in order to
        # access information about the interface itself, any devices
        # connected, or addressing information if applicable.
        nodemap_interface = interface.GetTLNodeMap()

        # Print interface display name
        #
        # *** NOTES ***
        # Grabbing node information requires first retrieving the node and
        # then retrieving its information. There are two things to keep in
        # mind. First, a node is distinguished by type, which is related
        # to its value's data type. Second, nodes should be checked for
        # availability and readability/writability prior to making an
        # attempt to read from or write to the node.
        #
        # Note that for Python, the node retrieved then has to be 'cast'
        # to the proper type (CStringPtr in this case) before it can be used.
        node_interface_display_name = PySpin.CStringPtr(nodemap_interface.GetNode('InterfaceDisplayName'))

        if PySpin.IsReadable(node_interface_display_name):
            interface_display_name = node_interface_display_name.GetValue()

            print(interface_display_name)

        else:
            print('Interface display name not readable')

        # Update list of cameras on the interface
        #
        # *** NOTES ***
        # Updating the cameras on each interface is especially important if
        # there has been any device arrivals or removals since the last time
        # that UpdateCameras() was called.
        interface.UpdateCameras()

        # Retrieve list of cameras from the interface
        #
        # *** NOTES ***
        # Camera lists can be retrieved from an interface or the system object.
        # Camera lists retrieved from an interface, such as this one, only
        # return cameras attached on that specific interface whereas camera
        # lists retrieved from the system will return all cameras on all
        # interfaces.
        #
        # *** LATER ***
        # Camera lists must be cleared manually. This must be done prior to
        # releasing the system and while the camera list is still in scope.
        cam_list = interface.GetCameras()

        # Retrieve number of cameras
        num_cams = cam_list.GetSize()

        # Return if no cameras detected
        if num_cams == 0:
            print('\tNo devices detected.\n')
            return result

        # Print device vendor and model name for each camera on the interface
        for i, cam in enumerate(cam_list):

            # Retrieve TL device nodemap; please see NodeMapInfo example for
            # additional comments on transport layer nodemaps
            nodemap_tldevice = cam.GetTLDeviceNodeMap()

            # Print device vendor name and device model name
            #
            # *** NOTES ***
            # Grabbing node information requires first retrieving the node and
            # then retrieving its information. There are two things to keep in
            # mind. First, a node is distinguished by type, which is related
            # to its value's data type. Second, nodes should be checked for
            # availability and readability/writability prior to making an
            # attempt to read from or write to the node.
            node_device_vendor_name = PySpin.CStringPtr(nodemap_tldevice.GetNode('DeviceVendorName'))

            if PySpin.IsReadable(node_device_vendor_name):
                device_vendor_name = node_device_vendor_name.ToString()

            node_device_model_name = PySpin.CStringPtr(nodemap_tldevice.GetNode('DeviceModelName'))

            if PySpin.IsReadable(node_device_model_name):
                device_model_name = node_device_model_name.ToString()

            print('\tDevice %i %s %s \n' % (i, device_vendor_name, device_model_name))

        # Release reference to camera
        # NOTE: Unlike the C++ examples, we cannot rely on pointer objects being automatically
        # cleaned up when going out of scope.
        # The usage of del is preferred to assigning the variable to None.
        del cam

        # Clear camera list before losing scope
        #
        # *** NOTES ***
        # Camera lists (and interface lists) must be cleared manually while in
        # the same scope that the system is released. However, in cases like this
        # where scope is lost, camera lists (and interface lists) will be cleared
        # automatically.
        cam_list.Clear()

    except PySpin.SpinnakerException as ex:
        print('Error: %s' % ex)
        result = False

    return result


def main():
    """
    Example entry point.

    :return: True if successful, False otherwise.
    :rtype: bool
    """
    result = True

    # Retrieve singleton reference to system object
    #
    # *** NOTES ***
    # Everything originates with the system object. It is important to notice
    # that it has a singleton implementation, so it is impossible to have
    # multiple system objects at the same time. Users can only get a smart
    # pointer (SystemPtr) to the system instance.
    # 
    # *** LATER ***
    # The system object should be cleared prior to program completion. If not
    # released explicitly, it will be released automatically when all SystemPtr
    # objects that point to the system go out of scope.
    system = PySpin.System.GetInstance()

    # Get current library version
    version = system.GetLibraryVersion()
    print('Library version: %d.%d.%d.%d' % (version.major, version.minor, version.type, version.build))

    # Retrieve list of interfaces from the system
    #
    # *** NOTES ***
    # Interface lists are retrieved from the system object.
    #
    # *** LATER ***
    # Interface lists must be cleared manually. This must be done prior to
    # releasing the system and while the interface list is still in scope.
    iface_list = system.GetInterfaces()

    # Get number of interfaces
    num_interfaces = iface_list.GetSize()

    print('Number of interfaces detected: %i' % num_interfaces)

    # Retrieve list of cameras from the system
    #
    # *** NOTES ***
    # Camera lists can be retrieved from an interface or the system object.
    # Camera lists retrieved from the system, such as this one, return all
    # cameras available on the system.
    #
    # *** LATER ***
    # Camera lists must be cleared manually. This must be done prior to
    # releasing the system and while the camera list is still in scope.
    cam_list = system.GetCameras()

    num_cams = cam_list.GetSize()

    print('Number of cameras detected: %i' % num_cams)

    # Finish if there are no cameras
    if num_cams == 0 or num_interfaces == 0:

        # Clear camera list before releasing system
        cam_list.Clear()

        # Clear interface list before releasing system
        iface_list.Clear()

        # Release system instance
        system.ReleaseInstance()

        print('Not enough cameras!')
        input('Done! Press Enter to exit...')
        return False

    print('\n*** QUERYING INTERFACES ***\n')

    for iface in iface_list:

        # Query interface
        result &= query_interface(iface)

    # Release reference to interface
    # NOTE: Unlike the C++ examples, we cannot rely on pointer objects being automatically
    # cleaned up when going out of scope.
    # The usage of del is preferred to assigning the variable to None.
    del iface

    # Clear camera list before releasing system
    #
    # *** NOTES ***
    # Camera lists must be cleared manually prior to a system release call.
    cam_list.Clear()

    # Clear interface list before releasing system
    #
    # *** NOTES ***
    # Interface lists must be cleared manually prior to a system release call.
    iface_list.Clear()

    # Release system instance
    #
    # *** NOTES ***
    # The system should be released, but if it is not, it will do so itself.
    # It is often at the release of the system (whether manual or automatic)
    # that unreleased resources and still-registered events will throw an
    # exception.
    system.ReleaseInstance()

    input('Done! Press Enter to exit...')
    return result

if __name__ == '__main__':
    if main():
        sys.exit(0)
    else:
        sys.exit(1)