BACpypes

repository·master·Indexed 43 days ago

https://github.com/joelbender/bacpypes

A Python-based implementation of the BACnet application and network layers. It enables developers to build BACnet-compliant daemons, automation scripts, and graphical user interfaces (GUIs). The library supports UDP communication, including unicast and broadcast messages, and provides tools for device discovery and network analysis.

Tokens
42.9K
Snippets
125
Records
246
Agent score
54%

What's inside BACpypes

  1. Overview of BACpypes

    master
    BACpypes is a Python implementation of the BACnet application layer and network layer. It is designed to be used for building BACnet daemons, automation scripts, and graphical user interfaces (GUIs). Note that this repository is the active project and is distinct from the legacy version hosted on SourceForge.
  2. What is an IO Control Block (IOCB)?

    master

    An IO Control Block (IOCB) is a data structure used to store parameters for a specific processing task and to retrieve the results once that task is complete.

    In the BACpypes model:

    • The IOCB holds the input arguments, keyword arguments, the resulting output, and any error values encountered during processing.
    • The IOController (IOController) acts as the executor that performs the processing defined by the IOCB.

    This pattern is modeled after the VAX/VMS IO subsystem API, allowing for asynchronous operations where an application can be notified of completion via event flags, semaphores, or callback functions rather than waiting synchronously for the operation to finish.

    # Conceptual model of IOCB usage:
    # result = some_function(arg1, arg2, kwarg1=1)
    # 
    # 1. IOCB stores: arg1, arg2, kwarg1
    # 2. IOController (some_function) executes the task
    # 3. IOCB stores: result (or error value if processing fails)
  3. What is a Protocol Data Unit (PDU) in BACpypes?

    master

    A Protocol Data Unit (PDU) is a collection of information passed between two entities. In the comm module, a PDU is composed of two main parts:

    1. Protocol Control Information (PCI): Contains addressing (source and destination) and processing instructions.
    2. PDUData: The actual payload or data being transmitted.

    The PDU class combines these two components into a single object. While the comm module provides these abstractions, the classes themselves are not strictly limited to the BACnet protocol.

  4. Understand PDU class hierarchies

    master

    BACpypes organizes PDUs into several functional hierarchies:

    Basic PDU Classes

    These classes represent the fundamental types of PDUs:

    • ConfirmedRequestPDU
    • UnconfirmedRequestPDU
    • SimpleAckPDU
    • ComplexAckPDU
    • SegmentAckPDU
    • ErrorPDU
    • RejectPDU

    Sequence Classes

    Sequence classes combine APCI with specific PDU types, often used for higher-level protocol implementations:

    • APCISequence(APCI, Sequence)
    • ConfirmedRequestSequence(APCISequence, ConfirmedRequestPDU)
    • ComplexAckSequence(APCISequence, ComplexAckPDU)
    • UnconfirmedRequestSequence(APCISequence, UnconfirmedRequestPDU)
    • ErrorSequence(APCISequence, ErrorPDU)
  5. Create client-only applications

    master

    In BACpypes v0.15.0+, the Application class no longer requires localDevice or localAddress parameters.

    Applications that omit these parameters function as client-only applications. These are useful for:

    • Network analysis applications.
    • Simple trend data gather applications.
    • Applications running in Docker containers or cloud environments.

    Note: Client-only applications can only initiate confirmed or unconfirmed services that do not require local device/address information. They cannot respond to incoming requests like Who-Is.

  6. Manage device information with DeviceInfo and DeviceInfoCache

    master

    BACpypes uses DeviceInfo objects to store metadata about remote devices, such as their device identifier, network address, maximum APDU length, and segmentation support. This information is critical for constructing confirmed services and performing device-address binding.

    To manage this data, use DeviceInfoCache. An Application uses a cache to store information gathered from the network (e.g., via IAmRequest) or from a database. You can extend DeviceInfoCache to implement custom persistence logic, such as updating a database when update_device_info is called or implementing custom expiration logic in release_device_info.

  7. Understand ConnectionState access states

    master

    The ConnectionState object tracks the lifecycle of a BSLL connection. The accessState attribute transitions through the following values:

    • NOT_AUTHENTICATED: No authentication has been attempted.
    • REQUESTED: An access request has been sent to the server (Client side).
    • CHALLENGED: An access challenge has been sent to the client (Server side).
    • AUTHENTICATED: Authentication was successful.
  8. How the capability module works for mixing functionality

    master

    The bacpypes.capability module provides a mechanism to mix together classes that offer separate or overlapping functionality. It uses a component-based architecture where functionality is added to a base class via multiple inheritance.

    Key classes include:

    • Capability: The base class for defining specific pieces of functionality (e.g., a specific data transformation).
    • Collector: A base class used to aggregate and execute functions provided by mixed-in Capability classes.

    By mixing a Collector with multiple Capability classes, you can create a pipeline where the Collector iterates through all registered functions of a specific type (retrieved via capability_functions()) and applies them to a value.

    from bacpypes.capability import Capability, Collector
  9. Use Network Layer Service Requests

    master

    The npdu module defines several service request classes used for routing and network management. Most of these classes implement encode(npdu) and decode(npdu) methods, accepting an NPDU buffer as a parameter.

    Router Discovery and Management

    • WhoIsRouterToNetwork(NPCI): Used to find the router for a specific network or to allow routers to update routing tables.
    • IAmRouterToNetwork(NPCI): Response to WhoIsRouterToNetwork; contains network numbers the router provides access to.
    • ICouldBeRouterToNetwork(NPCI): Response to WhoIsRouterToNetwork; contains network numbers a half-router could provide access to via a PTP connection (connection not yet established).

    Error and Traffic Control

    • RejectMessageToNetwork(NPCI): Sent when a network layer message is rejected due to an error.
    • RouterBusyToNetwork(NPCI): Sent by a router to temporarily stop messages to specific destination networks.
    • RouterAvailableToNetwork(NPCI): Sent by a router to enable or re-enable messages to specific destination networks.

    Routing Table and Connection Management

    • InitializeRoutingTable(NPCI): Used to initialize a router's routing table or retrieve the current table.
    • InitializeRoutingTableAck(NPCI): Indicates the routing table has changed or been initialized.
    • EstablishConnectionToNetwork(NPCI): Tells a half-router to establish a PTP connection to a network.
    • DisconnectConnectionToNetwork(NPCI): Tells a half-router to close a PTP connection to a network.
  10. How COV subscriptions and detection algorithms work together

    master

    BACpypes uses a layered approach for Change of Value (COV) services:

    1. ChangeOfValueServices: The central manager that handles the lifecycle of subscriptions and the dispatching of notifications.
    2. Subscription: Represents an active subscription with a specific lifetime. It acts as a OneShotTask that automatically cancels itself when its lifetime expires.
    3. COVDetection: A DetectionAlgorithm that monitors object properties. When a change is detected, it calls send_cov_notifications() to alert all associated Subscription objects.
    4. ActiveCOVSubscriptions: A Property added to a local device object. When read, it returns a list of COVSubscription objects, allowing the device to report its current COV state.