ZigBeeNet

repository·develop·Indexed 41 days ago

https://github.com/mr-markus/zigbeenet

A .NET Standard 2.0 and .NET Core 3.0 implementation of the Zigbee 3.0 Cluster Library (ZCL). It enables the development of smart home solutions to control Zigbee devices from manufacturers like Philips Hue and IKEA Tradfri using various hardware dongles, including Texas Instruments CC2531, Digi XBee, ConBee, and Silicon Labs Ember.

Tokens
84.4K
Snippets
268
Records
410
Agent score
50%

What's inside ZigBeeNet

  1. Configure NuGet package versioning via GitHub Releases

    develop

    The Continuous Delivery (CD) process automatically determines the version of the published NuGet packages based on the tag_name used in the GitHub Release.

    For example, if you create a release with the tag v1.5.0, the resulting NuGet packages will be versioned as 1.5.0.

  2. Install ZigBeeNet packages via NuGet

    develop

    ZigBeeNet is modular. Depending on your hardware and requirements, you will need to install the core library along with specific transport and hardware implementation packages.

    Core and Transport:

    • ZigBeeNet: The core Zigbee 3.0 Cluster Library implementation.
    • ZigBeeNet.Transport.SerialPort: Platform-independent SerialPort implementation.

    Hardware Implementations:

    • ZigBeeNet.Hardware.TI.CC2531: For Texas Instruments CC25XX dongles.
    • ZigBeeNet.Hardware.Digi.XBee: For Digi XBee dongles.
    • ZigbeeNet.Hardware.ConBee: For Dresden Elektronik ConBee dongles.
    • ZigbeeNet.Hardware.Ember: For Silicon Labs Ember dongles.

    Data Storage:

    • ZigbeeNet.DataStore.JSON: JSON-based data storage.
    • ZigbeeNet.DataStore.MongoDb: MongoDB-based data storage.
    ZigBeeNet
    ZigBeeNet.Transport.SerialPort
    ZigBeeNet.Hardware.TI.CC2531
    ZigBeeNet.Hardware.Digi.XBee
    ZigbeeNet.Hardware.ConBee
    ZigbeeNet.Hardware.Ember
    ZigbeeNet.DataStore.JSON
    ZigbeeNet.DataStore.MongoDb
  3. Understand the CI/CD workflow for ZigBeeNet

    develop

    ZigBeeNet uses GitHub Actions for Continuous Integration (CI) and Continuous Delivery (CD).

    • CI (Continuous Integration): Triggered by a push to a branch or a pull request to the develop or master branches. It uses dotnet command-line tooling to perform build steps.
    • CD (Continuous Delivery): Triggered by creating a GitHub Release in the repository. It also utilizes dotnet tooling for deployment tasks.
  4. Set up NuGet publishing secrets

    develop
    To enable the CD process to publish NuGet packages to nuget.org, you must store a GitHub Secret named NUGET_API_KEY in the repository settings. This secret is required for the automated publishing steps to authenticate with the NuGet registry.
  5. Follow C# coding style guidelines

    develop

    When contributing to ZigBeeNet, follow these C# coding standards to maintain consistency. The general rule is to use Visual Studio defaults and follow the Allman style for braces (each brace begins on a new line).

    Key Rules:

    • Indentation: Use four spaces (no tabs).
    • Field Naming:
      • Internal/Private instance fields: _camelCase (e.g., _myField).
      • Static fields: s_camelCase (e.g., s_myField).
      • Thread static fields: t_camelCase (e.g., t_myField).
      • Public fields: PascalCase (use sparingly).
      • Use readonly where possible. For static fields, use static readonly.
    • Visibility: Always explicitly specify visibility (e.g., private string _foo) and place it as the first modifier (e.g., public abstract).
    • Namespaces: Place imports at the top of the file, outside of namespace declarations. Sort alphabetically, but place System.* namespaces at the very top.
    • Types: Use language keywords instead of BCL types (e.g., int, string, float instead of Int32, String, Single).
    • Variables: Use var only when the type is obvious (e.g., var stream = new FileStream(...)).
    • Constants: Use PascalCase for constant local variables and fields (except in interop code).
    • Strings: Use nameof(...) instead of hardcoded strings whenever possible.
    • File Structure: Create a separate file for each class. Place fields at the top of the type declaration.
    • Non-ASCII: Use Unicode escape sequences (\uXXXX) instead of literal non-ASCII characters.

    Note: If an existing file uses a different style (e.g., m_member instead of _member), the existing style in that file takes precedence.

  6. EmberConcentratorType

    develop

    The EmberConcentratorType enumeration defines how a concentrator manages source routes based on its available memory:

    • EMBER_HIGH_RAM_CONCENTRATOR: Used when the device has sufficient memory to store source routes for the entire network. Remote nodes stop sending route records once the concentrator has successfully received one.
    • EMBER_LOW_RAM_CONCENTRATOR: Used when the device has insufficient RAM to store all outbound source routes. In this mode, remote nodes send route records to the concentrator prior to every inbound APS unicast.
  7. Initialize a ZigBee network with a TI CC2531 dongle

    develop

    To start a ZigBee network, you need to create a serial port connection, wrap it in a hardware-specific dongle implementation, and then initialize the ZigBeeNetworkManager.

    This example demonstrates setting up a ZigBeeSerialPort on COM4 using a ZigBeeDongleTiCc2531 and starting the network manager.

    using System;
    
    namespace ZigBeeNet.PlayGround
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    ZigBeeSerialPort zigbeePort = new ZigBeeSerialPort("COM4");
    
                    IZigBeeTransportTransmit dongle = new ZigBeeDongleTiCc2531(zigbeePort);
    
                    ZigBeeNetworkManager networkManager = new ZigBeeNetworkManager(dongle);
    
                    // Initialise the network
                    networkManager.Initialize();
    
                    networkManager.AddSupportedCluster(0x06);
    
                    ZigBeeStatus startupSucceded = networkManager.Startup(false);
    
                    if (startupSucceded == ZigBeeStatus.SUCCESS)
                    {
                        Log.Logger.Information("ZigBee console starting up ... [OK]");
                    }
                    else
                    {
                        Log.Logger.Information("ZigBee console starting up ... [FAIL]");
                        return;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
    
                Console.ReadLine();
            }
        }
    }
  8. Supported Zigbee hardware stacks and dongles

    develop

    ZigBeeNet separates the Zigbee Cluster Library (ZCL) from manufacturer-specific stacks, allowing support for various hardware via different implementations:

    • Texas Instruments (Z-Stack): Supports Z-Stack 3.0.x for CC2530, CC2531, and CC2538. It uses the Unified Network Processor Interface (UNPI) for serial communication. The CC2531 USB Stick with a ZNP image is a common choice.
    • Digi XBee: Tested with the XBee ZigBee S2C chip.
    • ConBee: Tested with Dresden Elektronik ConBee 2.
    • Silicon Labs Ember (EM35x / EFR32): Supports the Silicon Labs EZSP protocol using the ASH protocol over a serial interface.
      • For EM3588 devices with embedded USB, baud rates are flexible.
      • For dongles with external USB interfaces (e.g., CP2102), specific baud rates are required.
      • Two NCP images are supported: one with hardware flow control (115200 baud) and one with software flow control (57600 baud).
  9. Use EzspGetBindingRemoteNodeIdRequest to retrieve a binding's destination node ID

    develop

    The EzspGetBindingRemoteNodeIdRequest class implements the Ember EZSP command getBindingRemoteNodeId. It is used to retrieve the node ID for a binding's destination, provided the ID is already known by the stack.

    Behavioral Notes:

    • If a message is sent using a binding but the destination's ID is unknown, the stack will attempt to discover the ID by broadcasting a ZDO address request.
    • To avoid discovery overhead, you can use setBindingRemoteNodeId if the ID is already known through other means.
    • The destination's node ID is cleared when:
      • The binding is changed.
      • The local node reboots.
      • The destination node changes its ID due to an ID conflict (rare).
    var request = new EzspGetBindingRemoteNodeIdRequest();
    request.SetIndex(0); // Set the index of the binding table entry
    int[] payload = request.Serialize();
  10. Handle EzspGetCertificateResponse in Ember EZSP

    develop

    The EzspGetCertificateResponse class is used to process the response from the Ember EZSP getCertificate command. This command is used to retrieve the certificate installed on the Network Co-Processor (NCP).

    When a response is received, the class deserializes the EmberStatus (the result of the CBKE operation) and the EmberCertificateData (the locally installed certificate).

    // Example of accessing the response data
    // Assuming 'inputBuffer' is the raw byte array received from the hardware
    var response = new EzspGetCertificateResponse(inputBuffer);
    
    EmberStatus status = response.GetStatus();
    EmberCertificateData localCert = response.GetLocalCert();
    
    Console.WriteLine($"Status: {status}");
    Console.WriteLine($"Certificate: {localCert}");
  11. Use EzspFindKeyTableEntryRequest to search the Key Table

    develop

    The EzspFindKeyTableEntryRequest class implements the Ember EZSP command findKeyTableEntry. This command searches the Key Table for an entry that matches specific criteria.

    Search Criteria:

    • Address: The IeeeAddress to search for. Passing an address of all zeros allows searching for the first available empty entry.
    • Link Key Flag: A boolean indicating the type of key to search for. Setting this to true searches for an entry containing a Link Key; otherwise, it searches for a Master Key.
    var request = new EzspFindKeyTableEntryRequest();
    request.SetAddress(someIeeeAddress);
    request.SetLinkKey(true); // true for Link Key, false for Master Key
    
    // To retrieve the configured values:
    IeeeAddress address = request.GetAddress();
    bool isLinkKey = request.GetLinkKey();
  12. Handle EzspSendTrustCenterLinkKeyResponse in Ember EZSP

    develop

    The EzspSendTrustCenterLinkKeyResponse class is used to process the response from an Ember EZSP sendTrustCenterLinkKey command. This command sends an APS TransportKey command containing the current trust center link key to a specific node identified by its short and long addresses.

    When receiving this response, you should check the EmberStatus to determine if the operation succeeded or failed.

    // Example of checking the status of a response
    // Assuming 'response' is an instance of EzspSendTrustCenterLinkKeyResponse
    EmberStatus status = response.GetStatus();
    
    if (status == EmberStatus.Success) // Note: EmberStatus.Success is an assumed value from the EmberStatus enum
    {
        // Handle success
    }
    else
    {
        // Handle failure
    }