Expand description
Β§knx-pico
A no_std KNXnet/IP protocol implementation for embedded systems, designed for the Embassy async runtime.
Β§Features
- π
no_stdcompatible - 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 Wknx_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] β β β
β β βββββββββββββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββ| Layer | Purpose | Example |
|---|---|---|
| DPT | Encode values | 21.5Β°C β \[0x0C, 0x1A\] |
| CEMI | KNX commands | βWrite to 1/2/3: [0x01]β |
| KNXnet/IP | IP transport | UDP 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
Β§Option 1: USB Logger (Recommended - No probe needed)
# 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
-
Configure WiFi credentials in
src/configuration.rs:pub const CONFIG: &str = r#" WIFI_NETWORK=Your_WiFi_SSID WIFI_PASSWORD=Your_WiFi_Password "#; -
Flash to hardware:
cargo flash-example-usb -
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)
| DPT | Type | Description | Example |
|---|---|---|---|
| 1.xxx | Boolean | Switches, buttons, binary sensors | true/false |
| 3.007 | 3-bit | Dimming control (increase/decrease) | +4 steps |
| 3.008 | 3-bit | Blinds control (up/down) | down 2 steps |
| 5.001 | 8-bit | Percentage (0-100%) | 75% |
| 5.010 | 8-bit | Unsigned value (0-255) | 192 |
| 7.001 | 16-bit | Counter, pulses (0-65535) | 5000 lux |
| 9.001 | 2-byte float | Temperature (Β°C) | 21.5Β°C |
| 9.004 | 2-byte float | Illuminance (lux) | 5000 lux |
| 9.007 | 2-byte float | Humidity (%) | 65% |
| 13.xxx | 32-bit | Energy, flow rate, long counters | 500000 Wh |
See src/dpt/ for implementation details.
Β§Documentation
- TESTING.md - Testing guide with simulator setup
- KNX_DISCOVERY.md - Gateway discovery details
- PRE_PUBLISH_GUIDE.md - Pre-publish checklist
- examples/README.md - Example documentation
- API Documentation - Full API reference
Β§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:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Run
./check-all.shto verify all checks pass - 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
- Verify gateway is powered on and connected to network
- Check that multicast is enabled on your WiFi network
- Increase discovery timeout to 5 seconds
- Ensure your WiFi network allows multicast traffic (224.0.23.12)
Β§Connection timeouts
- Verify gateway IP and port (usually 3671)
- Check firewall settings (UDP port 3671 must be open)
- Ensure only one client connects to gateway at a time
Β§Compilation errors
- Update Rust toolchain:
rustup update - Install RP2040 target:
rustup target add thumbv8m.main-none-eabihf - For USB logger: ensure
picotoolis installed - For defmt: ensure
probe-rsis installed
See TESTING.md for detailed troubleshooting guide.
Β§License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
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
GroupAddressfrom 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Β§
- Group
Address - KNX Group Address
- Individual
Address - KNX Individual Address (Area.Line.Device)
- IpEndpoint
- IP endpoint (address + port) for network communication.
- Ipv4
Addr - 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Β§
Type AliasesΒ§
- Result
- Result type alias for KNX operations.