Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
22ff2a9
initial implementation knx connector for tokio
lxsaah Nov 16, 2025
5d77d2d
initial implementation embassy knx connector
lxsaah Nov 16, 2025
9b4faaa
format and rename demo
lxsaah Nov 16, 2025
befd7c8
update Makefile
lxsaah Nov 16, 2025
cc9160f
fix clippy errors and warnings
lxsaah Nov 16, 2025
7b8f658
update devcontainer CI workflow for improved efficiency
lxsaah Nov 17, 2025
069759e
persist watch receiver to avoid infinite subscription loop
lxsaah Nov 17, 2025
0916653
fix group adress parsing and refactor documentation for clarity
lxsaah Nov 17, 2025
3482253
remove conflicting memory.x from knx-pico to ensure correct STM32 mem…
lxsaah Nov 17, 2025
3bbfa22
implement outbound publishing for the tokio connector
lxsaah Nov 17, 2025
f7c3546
fix clippy
lxsaah Nov 17, 2025
65d468b
implement outbound publishers for embassy
lxsaah Nov 17, 2025
5829d25
update embassy
lxsaah Nov 17, 2025
16b5167
fix clippy
lxsaah Nov 17, 2025
ba457b1
feat: Enhance KNX connector with ACK handling and timeout detection
lxsaah Nov 18, 2025
6dcf30e
add knx-pico submodule
lxsaah Nov 19, 2025
87cbdb2
update submodules
lxsaah Nov 19, 2025
c939d02
Update Ethernet device type and configuration in KNX and MQTT demos
lxsaah Nov 19, 2025
cc60aa2
fix: Update knx-pico dependency path to avoid version conflicts
lxsaah Nov 19, 2025
3ba9b6c
update knx-pico
lxsaah Nov 19, 2025
b48f562
update knx pico
lxsaah Nov 20, 2025
6aa76a1
reexport dpt from knx-pico crate
lxsaah Nov 20, 2025
3917e65
use dpt en/decoding from knx-connector crate
lxsaah Nov 20, 2025
5d979ee
Refactor KNX connector to utilize knx-pico for type-safe group addres…
lxsaah Nov 20, 2025
b158b0f
update embassy
lxsaah Nov 20, 2025
6f79222
update README's
lxsaah Nov 20, 2025
4986ab5
Update examples/tokio-knx-connector-demo/README.md
lxsaah Nov 20, 2025
bb2239d
Update examples/tokio-knx-connector-demo/README.md
lxsaah Nov 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions .github/workflows/devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,13 @@ on:
push:
branches: [ main, develop ]
paths:
- '.devcontainer/Dockerfile'
- '.devcontainer/devcontainer.json'
- '.devcontainer/**'
- '.github/workflows/devcontainer.yml'
pull_request:
branches: [ main ]
branches: [ main, develop ]
paths:
- '.devcontainer/Dockerfile'
- '.devcontainer/devcontainer.json'
- '.devcontainer/**'
- '.github/workflows/devcontainer.yml'
schedule:
# Test weekly to catch upstream image changes
- cron: '0 6 * * 1' # Every Monday at 6 AM UTC
workflow_dispatch:

env:
Expand Down Expand Up @@ -168,6 +163,19 @@ jobs:
with:
submodules: recursive

- name: Free up disk space
run: |
echo "Disk space before cleanup:"
df -h
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo docker image prune -af
sudo apt-get clean
echo "Disk space after cleanup:"
df -h

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

Expand All @@ -186,6 +194,7 @@ jobs:
image-ref: aimdb-devcontainer:scan
format: 'sarif'
output: 'trivy-results.sarif'
skip-dirs: '/usr/share/dotnet,/usr/local/lib/android'

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "_external/mountain-mqtt"]
path = _external/mountain-mqtt
url = https://github.com/aimdb-dev/mountain-mqtt.git
[submodule "_external/knx-pico"]
path = _external/knx-pico
url = https://github.com/aimdb-dev/knx-pico.git
83 changes: 83 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ members = [
"aimdb-tokio-adapter",
"aimdb-sync",
"aimdb-mqtt-connector",
"aimdb-knx-connector",
"tools/aimdb-cli",
"tools/aimdb-mcp",
"examples/tokio-mqtt-connector-demo",
"examples/tokio-knx-connector-demo",
"examples/embassy-mqtt-connector-demo",
"examples/embassy-knx-connector-demo",
"examples/sync-api-demo",
"examples/remote-access-demo",
]
Expand Down
20 changes: 18 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ build:
cargo build --package aimdb-cli
@printf "$(YELLOW) → Building MCP server$(NC)\n"
cargo build --package aimdb-mcp
@printf "$(YELLOW) → Building KNX connector$(NC)\n"
cargo build --package aimdb-knx-connector --features "std,tokio-runtime"

test:
@printf "$(GREEN)Running all tests (valid combinations)...$(NC)\n"
Expand All @@ -73,10 +75,12 @@ test:
cargo test --package aimdb-cli
@printf "$(YELLOW) → Testing MCP server$(NC)\n"
cargo test --package aimdb-mcp
@printf "$(YELLOW) → Testing KNX connector$(NC)\n"
cargo test --package aimdb-knx-connector --features "std,tokio-runtime"

fmt:
@printf "$(GREEN)Formatting code (workspace members only)...$(NC)\n"
@for pkg in aimdb-executor aimdb-core aimdb-client aimdb-embassy-adapter aimdb-tokio-adapter aimdb-sync aimdb-mqtt-connector aimdb-cli aimdb-mcp sync-api-demo tokio-mqtt-connector-demo embassy-mqtt-connector-demo; do \
@for pkg in aimdb-executor aimdb-core aimdb-client aimdb-embassy-adapter aimdb-tokio-adapter aimdb-sync aimdb-mqtt-connector aimdb-knx-connector aimdb-cli aimdb-mcp sync-api-demo tokio-mqtt-connector-demo embassy-mqtt-connector-demo tokio-knx-connector-demo embassy-knx-connector-demo; do \
printf "$(YELLOW) → Formatting $$pkg$(NC)\n"; \
cargo fmt -p $$pkg 2>/dev/null || true; \
done
Expand All @@ -85,7 +89,7 @@ fmt:
fmt-check:
@printf "$(GREEN)Checking code formatting (workspace members only)...$(NC)\n"
@FAILED=0; \
for pkg in aimdb-executor aimdb-core aimdb-client aimdb-embassy-adapter aimdb-tokio-adapter aimdb-sync aimdb-mqtt-connector aimdb-cli aimdb-mcp sync-api-demo tokio-mqtt-connector-demo embassy-mqtt-connector-demo; do \
for pkg in aimdb-executor aimdb-core aimdb-client aimdb-embassy-adapter aimdb-tokio-adapter aimdb-sync aimdb-mqtt-connector aimdb-knx-connector aimdb-cli aimdb-mcp sync-api-demo tokio-mqtt-connector-demo embassy-mqtt-connector-demo tokio-knx-connector-demo embassy-knx-connector-demo; do \
printf "$(YELLOW) → Checking $$pkg$(NC)\n"; \
if ! cargo fmt -p $$pkg -- --check 2>&1; then \
printf "$(RED)❌ Formatting check failed for $$pkg$(NC)\n"; \
Expand Down Expand Up @@ -118,6 +122,10 @@ clippy:
cargo clippy --package aimdb-cli --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on MCP server$(NC)\n"
cargo clippy --package aimdb-mcp --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on KNX connector (std)$(NC)\n"
cargo clippy --package aimdb-knx-connector --features "std,tokio-runtime" --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on KNX connector (embassy)$(NC)\n"
cargo clippy --package aimdb-knx-connector --target thumbv7em-none-eabihf --no-default-features --features "embassy-runtime" -- -D warnings

doc:
@printf "$(GREEN)Generating dual-platform documentation...$(NC)\n"
Expand All @@ -129,13 +137,15 @@ doc:
cargo doc --package aimdb-tokio-adapter --features "tokio-runtime,tracing,metrics" --no-deps
cargo doc --package aimdb-sync --no-deps
cargo doc --package aimdb-mqtt-connector --features "std,tokio-runtime" --no-deps
cargo doc --package aimdb-knx-connector --features "std,tokio-runtime" --no-deps
cargo doc --package aimdb-cli --no-deps
cargo doc --package aimdb-mcp --no-deps
@cp -r target/doc/* target/doc-final/cloud/
@printf "$(YELLOW) → Building embedded documentation$(NC)\n"
cargo doc --package aimdb-core --no-default-features --no-deps
cargo doc --package aimdb-embassy-adapter --features "embassy-runtime" --no-deps
cargo doc --package aimdb-mqtt-connector --no-default-features --features "embassy-runtime" --no-deps
cargo doc --package aimdb-knx-connector --no-default-features --features "embassy-runtime" --no-deps
@cp -r target/doc/* target/doc-final/embedded/
@printf "$(YELLOW) → Creating main index page$(NC)\n"
@cp docs/index.html target/doc-final/index.html
Expand All @@ -158,6 +168,8 @@ test-embedded:
cargo check --package aimdb-embassy-adapter --target thumbv7em-none-eabihf --no-default-features --features "embassy-runtime,embassy-net-support"
@printf "$(YELLOW) → Checking aimdb-mqtt-connector (Embassy) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-mqtt-connector --target thumbv7em-none-eabihf --no-default-features --features "embassy-runtime"
@printf "$(YELLOW) → Checking aimdb-knx-connector (Embassy) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-knx-connector --target thumbv7em-none-eabihf --no-default-features --features "embassy-runtime"

## Example projects
examples:
Expand All @@ -168,6 +180,10 @@ examples:
cargo build --package tokio-mqtt-connector-demo
@printf "$(YELLOW) → Building embassy-mqtt-connector-demo (embedded, embassy runtime)$(NC)\n"
cargo build --package embassy-mqtt-connector-demo --target thumbv7em-none-eabihf
@printf "$(YELLOW) → Building tokio-knx-connector-demo (native, tokio runtime)$(NC)\n"
cargo build --package tokio-knx-connector-demo
@printf "$(YELLOW) → Building embassy-knx-connector-demo (embedded, embassy runtime)$(NC)\n"
cargo build --package embassy-knx-connector-demo --target thumbv7em-none-eabihf
@printf "$(GREEN)All examples built successfully!$(NC)\n"

## Security & Quality commands
Expand Down
2 changes: 1 addition & 1 deletion _external/embassy
Submodule embassy updated 67 files
+3 −3 docs/pages/bootloader.adoc
+3 −0 embassy-boot/CHANGELOG.md
+13 −1 embassy-boot/Cargo.toml
+7 −5 embassy-boot/src/boot_loader.rs
+4 −0 embassy-boot/src/lib.rs
+1 −0 embassy-nxp/CHANGELOG.md
+2 −2 embassy-nxp/Cargo.toml
+326 −27 embassy-nxp/build.rs
+8 −119 embassy-nxp/src/chips/lpc55.rs
+2 −102 embassy-nxp/src/chips/mimxrt1011.rs
+2 −271 embassy-nxp/src/chips/mimxrt1062.rs
+1 −0 embassy-nxp/src/dma.rs
+15 −32 embassy-nxp/src/dma/lpc55.rs
+16 −77 embassy-nxp/src/gpio/lpc55.rs
+13 −37 embassy-nxp/src/gpio/rt1xxx.rs
+29 −0 embassy-nxp/src/iomuxc.rs
+9 −7 embassy-nxp/src/lib.rs
+2 −0 embassy-nxp/src/pwm.rs
+18 −95 embassy-nxp/src/pwm/lpc55.rs
+56 −0 embassy-nxp/src/sct.rs
+2 −0 embassy-nxp/src/usart.rs
+44 −71 embassy-nxp/src/usart/lpc55.rs
+1 −0 embassy-stm32-wpan/CHANGELOG.md
+3 −1 embassy-stm32-wpan/Cargo.toml
+26 −0 embassy-stm32-wpan/src/mac/commands.rs
+147 −38 embassy-stm32-wpan/src/mac/control.rs
+118 −25 embassy-stm32-wpan/src/mac/driver.rs
+35 −0 embassy-stm32-wpan/src/mac/indications.rs
+1 −5 embassy-stm32-wpan/src/mac/mod.rs
+100 −58 embassy-stm32-wpan/src/mac/runner.rs
+54 −1 embassy-stm32-wpan/src/mac/typedefs.rs
+61 −22 embassy-stm32-wpan/src/sub/mac.rs
+1 −1 embassy-stm32-wpan/src/sub/mm.rs
+6 −0 embassy-stm32/CHANGELOG.md
+10 −0 embassy-stm32/build.rs
+1 −3 embassy-stm32/src/adc/ringbuffered.rs
+29 −21 embassy-stm32/src/eth/generic_phy.rs
+8 −21 embassy-stm32/src/eth/mod.rs
+42 −0 embassy-stm32/src/eth/sma/mod.rs
+102 −0 embassy-stm32/src/eth/sma/v1.rs
+94 −0 embassy-stm32/src/eth/sma/v2.rs
+116 −143 embassy-stm32/src/eth/v1/mod.rs
+94 −103 embassy-stm32/src/eth/v2/mod.rs
+36 −10 embassy-stm32/src/exti.rs
+155 −35 embassy-stm32/src/flash/h7.rs
+2 −2 embassy-stm32/src/flash/mod.rs
+223 −62 embassy-stm32/src/hsem/mod.rs
+3 −0 embassy-stm32/src/lib.rs
+80 −15 embassy-stm32/src/low_power.rs
+1 −1 embassy-stm32/src/usart/buffered.rs
+1 −1 examples/lpc55s69/src/bin/pwm.rs
+2 −2 examples/lpc55s69/src/bin/usart_async.rs
+59 −31 examples/rp/src/bin/wifi_webrequest.rs
+6 −6 examples/stm32f4/src/bin/eth.rs
+6 −6 examples/stm32f4/src/bin/eth_compliance_test.rs
+6 −6 examples/stm32f7/src/bin/eth.rs
+6 −6 examples/stm32h5/src/bin/eth.rs
+6 −6 examples/stm32h7/src/bin/eth.rs
+6 −6 examples/stm32h7/src/bin/eth_client.rs
+6 −6 examples/stm32h7/src/bin/eth_client_mii.rs
+84 −0 examples/stm32h7/src/bin/flash_async.rs
+6 −6 examples/stm32h7rs/src/bin/eth.rs
+1 −1 examples/stm32wb/Cargo.toml
+80 −105 examples/stm32wb/src/bin/mac_ffd_net.rs
+8 −2 tests/stm32/Cargo.toml
+7 −6 tests/stm32/src/bin/eth.rs
+50 −0 tests/stm32/src/bin/hsem.rs
1 change: 1 addition & 0 deletions _external/knx-pico
Submodule knx-pico added at e60ca5
40 changes: 32 additions & 8 deletions aimdb-embassy-adapter/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ impl<
// Clone the Arc for the reader
EmbassyBufferReader {
buffer: Arc::clone(&self.inner),
watch_receiver: None, // Will be initialized on first recv() for Watch buffers
}
}
}
Expand Down Expand Up @@ -264,8 +265,8 @@ impl<

/// Reader for Embassy buffers
///
/// Holds an Arc reference to the buffer. Each recv() call creates a temporary
/// subscription to read one value.
/// Holds persistent subscription state for each buffer type.
/// For Watch buffers, stores a persistent Receiver to track which value has been seen.
pub struct EmbassyBufferReader<
T: Clone + Send + 'static,
const CAP: usize,
Expand All @@ -274,6 +275,9 @@ pub struct EmbassyBufferReader<
const WATCH_N: usize,
> {
buffer: Arc<EmbassyBufferInner<T, CAP, SUBS, PUBS, WATCH_N>>,
/// Persistent Watch receiver. The 'static lifetime is safe because the Arc keeps the Watch alive.
watch_receiver:
Option<embassy_sync::watch::Receiver<'static, CriticalSectionRawMutex, T, WATCH_N>>,
}

impl<
Expand All @@ -289,8 +293,6 @@ impl<
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T, DbError>> + Send + '_>>
{
Box::pin(async move {
// Create a temporary subscription for this recv() call
// This works because the Arc keeps the buffer alive
match &*self.buffer {
EmbassyBufferInner::SpmcRing(channel) => match channel.subscriber() {
Ok(mut sub) => match sub.next_message().await {
Expand All @@ -302,10 +304,32 @@ impl<
},
Err(_) => Err(DbError::BufferClosed { _buffer_name: () }),
},
EmbassyBufferInner::Watch(watch) => match watch.receiver() {
Some(mut rx) => Ok(rx.changed().await),
None => Err(DbError::BufferClosed { _buffer_name: () }),
},
EmbassyBufferInner::Watch(watch) => {
// Watch requires a persistent receiver to track seen values.
// Creating a new receiver each time causes infinite loops (always returns current value).
if self.watch_receiver.is_none() {
// SAFETY: The Arc in self.buffer keeps the Watch alive for this reader's lifetime.
// We extend the lifetime to 'static to store the receiver, which is safe because
// the receiver is just (&Watch, u64 counter) and will be dropped with the reader.
let watch_static: &'static embassy_sync::watch::Watch<
CriticalSectionRawMutex,
T,
WATCH_N,
> = unsafe { &*(watch as *const _) };

self.watch_receiver = watch_static.receiver();
Comment thread
lxsaah marked this conversation as resolved.
if self.watch_receiver.is_none() {
return Err(DbError::BufferClosed { _buffer_name: () });
}
}

// Use the persistent receiver to detect changes
if let Some(ref mut rx) = self.watch_receiver {
Ok(rx.changed().await)
} else {
Err(DbError::BufferClosed { _buffer_name: () })
}
}
EmbassyBufferInner::Mailbox(channel) => {
let rx = channel.receiver();
Ok(rx.receive().await)
Expand Down
Loading