Crate knx_pico

Crate knx_pico 

Source
Expand description

Β§knx-pico

Crates.io Documentation License

A no_std KNXnet/IP protocol implementation for embedded systems, designed for the Embassy async runtime.

Β§Features

  • πŸš€ no_std compatible - Runs on bare metal embedded systems
  • ⚑ Zero-copy parsing - Efficient memory usage for resource-constrained devices
  • πŸ”„ Async/await - Full Embassy async runtime integration
  • 🎯 Type-safe addressing - Strong types for Individual and Group addresses
  • πŸ”Œ KNXnet/IP tunneling - Reliable point-to-point communication
  • πŸ“Š Datapoint Types (DPT) - Support for DPT 1, 3, 5, 7, 9, 13
  • πŸ” Gateway auto-discovery - Automatic KNX gateway detection via multicast
  • πŸ›‘οΈ Production-ready - Thoroughly tested with hardware and simulator

Β§Quick Start

Β§Installation

Add to your Cargo.toml:

[dependencies]
knx-pico = "0.1"

Β§Basic Example

use knx_pico::{GroupAddress, protocol::cemi::CemiFrame, dpt::{Dpt1, DptEncode}};

// Create a group address
let light = GroupAddress::new(1, 2, 3)?;

// Encode a boolean value (DPT 1 - Switch)
let value = Dpt1::new(true);
let encoded = value.encode();

// Create a write request frame
let frame = CemiFrame::write_request(light.into(), &encoded)?;

// The frame can now be sent over KNXnet/IP tunnel
// (requires Embassy runtime and network stack - see examples on GitHub)

For complete examples with Embassy runtime and Raspberry Pi Pico 2 W, see the examples directory on GitHub:

  • pico_knx_async.rs - Complete working example for Pico 2 W
  • knx_sniffer.rs - Interactive testing tool with convenience macros

Β§Hardware Support

Β§Tested Platforms

  • βœ… Raspberry Pi Pico 2 W (RP2350) - Primary development platform
  • πŸ”œ ESP32-C3/C6 - Planned support via embassy-esp

Β§Required Hardware

For physical KNX testing:

  • Raspberry Pi Pico 2 W (or compatible RP2350 board)
  • KNX/IP Gateway (e.g., Gira X1, MDT SCN-IP000.03)
  • WiFi network

For testing without hardware: Use the included Python KNX simulator (see Testing).

Β§Architecture

Β§Layer Overview

KNX communication uses three nested protocol layers:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  KNXnet/IP FRAME (UDP transport)                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ CEMI (KNX command)                        β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚  β”‚
β”‚  β”‚  β”‚ DPT (encoded value)                 β”‚ β”‚  β”‚
β”‚  β”‚  β”‚ e.g., true β†’ [0x01]                 β”‚ β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
LayerPurposeExample
DPTEncode values21.5Β°C β†’ \[0x0C, 0x1A\]
CEMIKNX commandsβ€œWrite to 1/2/3: [0x01]”
KNXnet/IPIP transportUDP to 192.168.1.10:3671

Β§Module Structure

knx-pico/
β”œβ”€β”€ addressing/          # KNX addressing (Individual & Group)
β”œβ”€β”€ protocol/            # KNXnet/IP protocol implementation
β”‚   β”œβ”€β”€ frame.rs         # Layer 1: KNXnet/IP frames
β”‚   β”œβ”€β”€ cemi.rs          # Layer 2: CEMI messages
β”‚   β”œβ”€β”€ services.rs      # Tunneling service builders
β”‚   β”œβ”€β”€ tunnel.rs        # Typestate tunneling client
β”‚   └── async_tunnel.rs  # Async wrapper for Embassy
β”œβ”€β”€ dpt/                 # Layer 3: Datapoint Types (DPT)
β”‚   β”œβ”€β”€ dpt1.rs          # Boolean (switches, buttons)
β”‚   β”œβ”€β”€ dpt3.rs          # 3-bit control (dimming, blinds)
β”‚   β”œβ”€β”€ dpt5.rs          # 8-bit unsigned (percentage, angle)
β”‚   β”œβ”€β”€ dpt7.rs          # 16-bit unsigned (counter, brightness)
β”‚   β”œβ”€β”€ dpt9.rs          # 2-byte float (temperature, humidity)
β”‚   └── dpt13.rs         # 32-bit signed (energy, flow)
β”œβ”€β”€ knx_discovery.rs     # Gateway auto-discovery
β”œβ”€β”€ knx_client.rs        # High-level client API
β”œβ”€β”€ error.rs             # Comprehensive error types
└── lib.rs               # Public API

Β§Convenience Macros

The library provides macros to simplify common operations:

use knx_pico::{ga, knx_write, knx_read, KnxValue};

// Create group addresses with readable notation
let light = ga!(1/2/3);
let temp_sensor = ga!(1/2/10);

// Write values with inline address notation
knx_write!(client, 1/2/3, KnxValue::Bool(true)).await?;
knx_write!(client, 1/2/10, KnxValue::Temperature(21.5)).await?;

// Read values
knx_read!(client, 1/2/10).await?;

// Register multiple DPT types at once
register_dpts! {
    client,
    1/2/3  => Bool,
    1/2/5  => Percent,
    1/2/10 => Temperature,
}?;

Β§Building and Flashing

Β§For Raspberry Pi Pico 2 W

# Configure WiFi in src/configuration.rs
# Build and flash in one command
cargo flash-example-usb

# Monitor logs via USB serial
screen /dev/tty.usbmodem* 115200
Β§Option 2: defmt Logger (Requires debug probe)
# Build with defmt-rtt
cargo build --release --example pico_knx_async \
    --target thumbv8m.main-none-eabihf \
    --features embassy-rp

# Flash with probe-rs
probe-rs run --chip RP2350 \
    target/thumbv8m.main-none-eabihf/release/examples/pico_knx_async

Β§Available Commands

See .cargo/config.toml for all commands:

# Examples with USB logger
cargo flash-example-usb              # Flash pico_knx_async
cargo flash-sniffer-usb-release      # Flash knx_sniffer
cargo flash-main-app-usb-release     # Flash knx_main_application

# Library checks
cargo check-rp2040                   # Check for RP2040 target (defmt)
cargo check-rp2040-usb               # Check for RP2040 target (USB logger)
cargo test-host-release              # Run host tests (optimized)

# Full verification
./check-all.sh                       # Run all checks

Β§Testing

Β§Without Physical Hardware

Use the included Python KNX simulator for development and testing:

# Start simulator
python3 knx_simulator.py

# Run integration tests
python3 test_runner.py

# Or use Make
make test              # All tests
make test-unit         # Unit tests only

Β§With Physical Hardware

  1. Configure WiFi credentials in src/configuration.rs:

    pub const CONFIG: &str = r#"
    WIFI_NETWORK=Your_WiFi_SSID
    WIFI_PASSWORD=Your_WiFi_Password
    "#;
  2. Flash to hardware:

    cargo flash-example-usb
  3. Monitor logs:

    screen /dev/tty.usbmodem* 115200

See TESTING.md for detailed testing guide.

Β§Gateway Auto-Discovery

The library automatically discovers KNX gateways using multicast SEARCH_REQUEST:

use knx_pico::knx_discovery;
use embassy_time::Duration;

// Discover gateway (3 second timeout)
let gateway = knx_discovery::discover_gateway(&stack, Duration::from_secs(3))
    .await
    .expect("No KNX gateway found");

println!("Found gateway at {}:{}", gateway.ip, gateway.port);

No manual IP configuration needed! See KNX_DISCOVERY.md for details.

Β§Supported Datapoint Types (DPT)

DPTTypeDescriptionExample
1.xxxBooleanSwitches, buttons, binary sensorstrue/false
3.0073-bitDimming control (increase/decrease)+4 steps
3.0083-bitBlinds control (up/down)down 2 steps
5.0018-bitPercentage (0-100%)75%
5.0108-bitUnsigned value (0-255)192
7.00116-bitCounter, pulses (0-65535)5000 lux
9.0012-byte floatTemperature (Β°C)21.5Β°C
9.0042-byte floatIlluminance (lux)5000 lux
9.0072-byte floatHumidity (%)65%
13.xxx32-bitEnergy, flow rate, long counters500000 Wh

See src/dpt/ for implementation details.

Β§Documentation

Β§Project Status

βœ… Production Ready

All core features implemented and tested:

  • βœ… KNXnet/IP protocol (Frame, CEMI, Services)
  • βœ… Datapoint Types (DPT 1, 3, 5, 7, 9, 13)
  • βœ… Tunneling client with typestate pattern
  • βœ… Embassy + RP2040 integration (Pico 2 W)
  • βœ… Gateway auto-discovery via multicast
  • βœ… High-level client API with macros
  • βœ… Comprehensive testing (unit, integration, hardware)
  • βœ… CI/CD automation (GitHub Actions)

Β§Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Run ./check-all.sh to verify all checks pass
  5. Submit a pull request

Β§Performance

Optimized for embedded systems:

  • Zero-copy parsing - Minimal memory allocations
  • Inline hot paths - Critical functions marked #[inline]
  • Unsafe optimizations - Bounds checks eliminated where safe (documented with // SAFETY: comments)
  • ~10% performance gain on parsing hot paths
  • Fire-and-forget pattern - Optimized command sending for stability

Benchmarked on Raspberry Pi Pico 2 W (RP2350, 150 MHz).

Β§Troubleshooting

Β§Gateway not found during discovery

  1. Verify gateway is powered on and connected to network
  2. Check that multicast is enabled on your WiFi network
  3. Increase discovery timeout to 5 seconds
  4. Ensure your WiFi network allows multicast traffic (224.0.23.12)

Β§Connection timeouts

  1. Verify gateway IP and port (usually 3671)
  2. Check firewall settings (UDP port 3671 must be open)
  3. Ensure only one client connects to gateway at a time

Β§Compilation errors

  1. Update Rust toolchain: rustup update
  2. Install RP2040 target: rustup target add thumbv8m.main-none-eabihf
  3. For USB logger: ensure picotool is installed
  4. For defmt: ensure probe-rs is installed

See TESTING.md for detailed troubleshooting guide.

Β§License

Licensed under either of:

at your option.

Β§Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Β§knx-pico

KNXnet/IP protocol implementation for embedded systems.

This crate provides a no_std implementation of the KNXnet/IP protocol, designed for use with Embassy async runtime on embedded microcontrollers.

Β§Features

  • KNXnet/IP tunneling support
  • Common Datapoint Types (DPT)
  • Individual and Group addressing
  • Zero-copy parsing
  • Async/await with Embassy

Β§Example

use knx_pico::{KnxClient, GroupAddress};

// Connect to KNX gateway and send a command
let addr = GroupAddress::new(1, 2, 3).unwrap();
client.write_bool(addr, true).await?;

ModulesΒ§

addressing
KNX addressing system.
dpt
KNX Datapoint Types (DPT)
error
Error types for KNX operations following M-ERRORS-CANONICAL-STRUCTS guideline.
logging
Unified Logging Macros for KNX-RS
macros
Convenience macros for working with KNX addresses and types.
net
Network types for KNX communication.
protocol
KNXnet/IP protocol implementation.

MacrosΒ§

ga
Creates a GroupAddress from 3-level notation.
knx_read
Simplified read operation with inline address notation.
knx_respond
Simplified respond operation with inline address notation.
knx_write
Simplified write operation with inline address notation.
pico_log
Logging macro that automatically selects the right backend.
register_dpts
Registers multiple DPT type mappings in a single block.

StructsΒ§

GroupAddress
KNX Group Address
IndividualAddress
KNX Individual Address (Area.Line.Device)
IpEndpoint
IP endpoint (address + port) for network communication.
Ipv4Addr
IPv4 address representation.

EnumsΒ§

Dpt1
DPT 1.xxx Boolean types
Dpt5
DPT 5.xxx 8-bit unsigned types
Dpt9
DPT 9.xxx 2-byte float types
KnxError
KNX protocol error types.

TraitsΒ§

DptDecode
Trait for decoding KNX data to values
DptEncode
Trait for encoding values to KNX data format

Type AliasesΒ§

Result
Result type alias for KNX operations.