Skip to content

Commit 709b42d

Browse files
committed
clean up, better build & serial stuff
1 parent 29ac084 commit 709b42d

9 files changed

Lines changed: 323 additions & 166 deletions

.gitmodules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[submodule "esp-matter"]
22
path = esp-matter
33
url = https://github.com/espressif/esp-matter.git
4+
ignore = dirty

patches/0001-thread-connect-success-after-dnssd-ready.patch

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp
2-
--- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp
3-
+++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: Codex <codex@example.com>
3+
Date: Thu, 23 Apr 2026 17:40:00 +0200
4+
Subject: [PATCH 1/3] thread: wait for DNS-SD before reporting attach success
5+
6+
diff --git a/connectedhomeip/connectedhomeip/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/connectedhomeip/connectedhomeip/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp
7+
--- a/connectedhomeip/connectedhomeip/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp
8+
+++ b/connectedhomeip/connectedhomeip/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp
49
@@ -45,6 +45,7 @@
510
#include <openthread/srp_client.h>
611
#endif
@@ -51,3 +56,5 @@ diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hp
5156
}
5257

5358
template <class ImplClass>
59+
--
60+
2.39.5 (Apple Git-154)

patches/0002-waveshare-c6-zero-swap-red-green.patch

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
diff --git a/device_hal/device/esp32c6_devkit_c/device.c b/device_hal/device/esp32c6_devkit_c/device.c
2-
index 30f7d3c0..7fd283a6 100644
2+
index 30f7d3c..7fd283a 100644
33
--- a/device_hal/device/esp32c6_devkit_c/device.c
44
+++ b/device_hal/device/esp32c6_devkit_c/device.c
55
@@ -28,6 +28,7 @@ led_driver_config_t led_driver_get_config()
@@ -11,7 +11,7 @@ index 30f7d3c0..7fd283a6 100644
1111
return config;
1212
}
1313
diff --git a/device_hal/led_driver/include/led_driver.h b/device_hal/led_driver/include/led_driver.h
14-
index 278f1b35..aa021445 100644
14+
index 278f1b3..aa02144 100644
1515
--- a/device_hal/led_driver/include/led_driver.h
1616
+++ b/device_hal/led_driver/include/led_driver.h
1717
@@ -24,6 +24,7 @@ typedef struct {
@@ -23,7 +23,7 @@ index 278f1b35..aa021445 100644
2323

2424
typedef void *led_driver_handle_t;
2525
diff --git a/device_hal/led_driver/utils/color_format.c b/device_hal/led_driver/utils/color_format.c
26-
index 930daf3c..362058c3 100644
26+
index 930daf3..362058c 100644
2727
--- a/device_hal/led_driver/utils/color_format.c
2828
+++ b/device_hal/led_driver/utils/color_format.c
2929
@@ -12,8 +12,11 @@
@@ -57,7 +57,7 @@ index 930daf3c..362058c3 100644
5757
+ XY.x, XY.y, brightness, RGB->red, RGB->green, RGB->blue);
5858
}
5959
diff --git a/device_hal/led_driver/ws2812/led_driver.c b/device_hal/led_driver/ws2812/led_driver.c
60-
index 33879e89..9de0fb60 100644
60+
index 33879e8..9de0fb6 100644
6161
--- a/device_hal/led_driver/ws2812/led_driver.c
6262
+++ b/device_hal/led_driver/ws2812/led_driver.c
6363
@@ -22,11 +22,11 @@ static bool current_power = false;
@@ -106,7 +106,7 @@ index 33879e89..9de0fb60 100644
106106
if (err != ESP_OK) {
107107
ESP_LOGE(TAG, "strip_refresh failed");
108108
diff --git a/examples/light/main/app_driver.cpp b/examples/light/main/app_driver.cpp
109-
index 7ac765cd..72fcaa8c 100644
109+
index 7ac765c..72fcaa8 100644
110110
--- a/examples/light/main/app_driver.cpp
111111
+++ b/examples/light/main/app_driver.cpp
112112
@@ -7,6 +7,7 @@
@@ -153,7 +153,7 @@ index 7ac765cd..72fcaa8c 100644
153153
}
154154

155155
diff --git a/examples/light/main/app_main.cpp b/examples/light/main/app_main.cpp
156-
index 3223640d..0ca50c30 100644
156+
index 3223640..0ca50c3 100644
157157
--- a/examples/light/main/app_main.cpp
158158
+++ b/examples/light/main/app_main.cpp
159159
@@ -47,6 +47,56 @@ using namespace chip::app::Clusters;
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: Codex <codex@example.com>
3+
Date: Thu, 23 Apr 2026 17:45:00 +0200
4+
Subject: [PATCH 2/3] light: keep Thread node as FED until fabric commit
5+
6+
The esp-matter core brings every Thread FTD build up as router-eligible.
7+
For initial commissioning on a busy mesh, that allows the node to change
8+
parent and promote from child to router during the BLE-to-operational
9+
handoff. Keep uncommissioned nodes as FullEndDevice during onboarding,
10+
then restore router eligibility once the fabric is committed.
11+
---
12+
esp-matter/examples/light/main/app_main.cpp | 54 ++++++++++++++++++++
13+
1 file changed, 54 insertions(+)
14+
15+
diff --git a/examples/light/main/app_main.cpp b/examples/light/main/app_main.cpp
16+
--- a/examples/light/main/app_main.cpp
17+
+++ b/examples/light/main/app_main.cpp
18+
@@ -20,6 +20,7 @@
19+
#include <app_priv.h>
20+
#include <app_reset.h>
21+
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
22+
+#include <platform/CHIPDeviceLayer.h>
23+
#include <platform/ESP32/OpenthreadLauncher.h>
24+
#endif
25+
26+
@@ -46,7 +47,46 @@
27+
using namespace chip::app::Clusters;
28+
29+
constexpr auto k_timeout_seconds = 300;
30+
+
31+
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
32+
+static const char *thread_device_type_name(chip::DeviceLayer::ConnectivityManager::ThreadDeviceType device_type)
33+
+{
34+
+ switch (device_type) {
35+
+ case chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_Router:
36+
+ return "router";
37+
+ case chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_FullEndDevice:
38+
+ return "full end device";
39+
+ default:
40+
+ return "other";
41+
+ }
42+
+}
43+
+
44+
+static void ensure_thread_device_type(chip::DeviceLayer::ConnectivityManager::ThreadDeviceType device_type,
45+
+ const char *reason)
46+
+{
47+
+ auto &connectivity_mgr = chip::DeviceLayer::ConnectivityMgr();
48+
+
49+
+ if (connectivity_mgr.GetThreadDeviceType() == device_type) {
50+
+ ESP_LOGI(TAG, "Thread device type already %s for %s", thread_device_type_name(device_type), reason);
51+
+ return;
52+
+ }
53+
+
54+
+ CHIP_ERROR err = connectivity_mgr.SetThreadDeviceType(device_type);
55+
+ if (err != CHIP_NO_ERROR) {
56+
+ ESP_LOGE(TAG, "Failed to set Thread device type to %s for %s: %" CHIP_ERROR_FORMAT,
57+
+ thread_device_type_name(device_type), reason, err.Format());
58+
+ return;
59+
+ }
60+
+
61+
+ ESP_LOGI(TAG, "Set Thread device type to %s for %s", thread_device_type_name(device_type), reason);
62+
+}
63+
+
64+
+static bool is_uncommissioned()
65+
+{
66+
+ return chip::Server::GetInstance().GetFabricTable().FabricCount() == 0;
67+
+}
68+
+#endif
69+
70+
static const char *attribute_update_type_name(attribute::callback_type_t type)
71+
{
72+
switch (type) {
73+
@@ -130,6 +170,12 @@
74+
75+
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStarted:
76+
ESP_LOGI(TAG, "Commissioning session started");
77+
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
78+
+ if (is_uncommissioned()) {
79+
+ ensure_thread_device_type(chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_FullEndDevice,
80+
+ "commissioning session");
81+
+ }
82+
+#endif
83+
break;
84+
85+
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStopped:
86+
@@ -148,6 +194,10 @@
87+
case chip::DeviceLayer::DeviceEventType::kFabricRemoved: {
88+
ESP_LOGI(TAG, "Fabric removed successfully");
89+
if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) {
90+
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
91+
+ ensure_thread_device_type(chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_FullEndDevice,
92+
+ "fabric removal");
93+
+#endif
94+
chip::CommissioningWindowManager &commissionMgr = chip::Server::GetInstance().GetCommissioningWindowManager();
95+
constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds16(k_timeout_seconds);
96+
if (!commissionMgr.IsCommissioningWindowOpen()) {
97+
@@ -174,6 +224,9 @@
98+
99+
case chip::DeviceLayer::DeviceEventType::kFabricCommitted:
100+
ESP_LOGI(TAG, "Fabric is committed");
101+
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
102+
+ ensure_thread_device_type(chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_Router, "fabric commit");
103+
+#endif
104+
break;
105+
106+
case chip::DeviceLayer::DeviceEventType::kBLEDeinitialized:
107+
@@ -294,6 +347,13 @@
108+
err = esp_matter::start(app_event_cb);
109+
ABORT_APP_ON_FAILURE(err == ESP_OK, ESP_LOGE(TAG, "Failed to start Matter, err:%d", err));
110+
111+
+#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
112+
+ if (is_uncommissioned()) {
113+
+ ensure_thread_device_type(chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_FullEndDevice,
114+
+ "initial commissioning");
115+
+ }
116+
+#endif
117+
+
118+
MEMORY_PROFILER_DUMP_HEAP_STAT("matter started");
119+
120+
/* Starting driver with default values */
121+
--
122+
2.39.5 (Apple Git-154)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: Codex <codex@example.com>
3+
Date: Thu, 23 Apr 2026 22:40:00 +0200
4+
Subject: [PATCH 4/4] light: expose basic info serial number from factory data
5+
6+
diff --git a/components/esp_matter/data_model/legacy/esp_matter_cluster.cpp b/components/esp_matter/data_model/legacy/esp_matter_cluster.cpp
7+
--- a/components/esp_matter/data_model/legacy/esp_matter_cluster.cpp
8+
+++ b/components/esp_matter/data_model/legacy/esp_matter_cluster.cpp
9+
@@ -249,6 +249,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags)
10+
attribute::create_hardware_version(cluster, 0);
11+
attribute::create_hardware_version_string(cluster, NULL, 0);
12+
attribute::create_software_version(cluster, 0);
13+
attribute::create_software_version_string(cluster, NULL, 0);
14+
+ attribute::create_serial_number(cluster, NULL, 0);
15+
attribute::create_unique_id(cluster, NULL, 0);
16+
attribute::create_capability_minima(cluster, NULL, 0, 0);
17+
attribute::create_specification_version(cluster, 0);
18+
attribute::create_max_paths_per_invoke(cluster, 0);
19+
20+
diff --git a/components/esp_matter/data_model/generated/clusters/basic_information/basic_information.cpp b/components/esp_matter/data_model/generated/clusters/basic_information/basic_information.cpp
21+
--- a/components/esp_matter/data_model/generated/clusters/basic_information/basic_information.cpp
22+
+++ b/components/esp_matter/data_model/generated/clusters/basic_information/basic_information.cpp
23+
@@ -239,6 +239,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags)
24+
attribute::create_hardware_version(cluster, config->hardware_version);
25+
attribute::create_hardware_version_string(cluster, config->hardware_version_string, sizeof(config->hardware_version_string));
26+
attribute::create_software_version(cluster, config->software_version);
27+
attribute::create_software_version_string(cluster, config->software_version_string, sizeof(config->software_version_string));
28+
+ attribute::create_serial_number(cluster, NULL, 0);
29+
attribute::create_unique_id(cluster, config->unique_id, sizeof(config->unique_id));
30+
attribute::create_specification_version(cluster, config->specification_version);
31+
attribute::create_max_paths_per_invoke(cluster, config->max_paths_per_invoke);
32+
attribute::create_capability_minima(cluster, NULL, 0, 0);
33+
34+
--
35+
2.39.5 (Apple Git-154)

tools/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ User-facing entrypoint: `tools/light_pipeline.py`
55
The pipeline shells into ESP-IDF automatically after it finds `IDF_PATH`. No manual `source export.sh` step needed.
66
If Matter tooling such as `gn` is missing, the pipeline also runs CHIP bootstrap automatically before the firmware build step.
77
If nested git submodules under `esp-matter/connectedhomeip` are missing, the pipeline also runs `git submodule update --init --recursive` from repo root before the build step.
8-
If repo patch files exist under top-level `patches/`, the pipeline applies them to `esp-matter/connectedhomeip/connectedhomeip` before build/bootstrap commands.
8+
If repo patch files exist under top-level `patches/`, the pipeline reports them but does not apply them. `esp-matter/` stays untouched by `light_pipeline.py` execution.
99

1010
Target flow:
1111

tools/generate_label_html.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@
101101
transform-origin: center center;
102102
}}
103103
104+
.header-stack {{
105+
display: grid;
106+
justify-items: center;
107+
gap: 0.3mm;
108+
width: 100%;
109+
}}
110+
104111
.brand {{
105112
display: flex;
106113
justify-content: center;
@@ -124,6 +131,17 @@
124131
white-space: nowrap;
125132
}}
126133
134+
.serial-number {{
135+
width: 100%;
136+
text-align: center;
137+
font-size: 1.05mm;
138+
line-height: 1;
139+
font-weight: 600;
140+
letter-spacing: 0.05mm;
141+
white-space: nowrap;
142+
font-variant-numeric: tabular-nums;
143+
}}
144+
127145
.qr-wrap {{
128146
display: grid;
129147
align-content: center;
@@ -347,10 +365,12 @@
347365
paddingTop: mmToPixels(0.55 * contentScale),
348366
paddingBottom: mmToPixels(0.7 * contentScale),
349367
gap: mmToPixels(0.55 * contentScale),
368+
headerGap: mmToPixels(0.3 * contentScale),
350369
brandFontPx: mmToPixels(1.95 * contentScale),
351370
iconSizePx: mmToPixels(1.65 * contentScale),
352371
iconGapPx: mmToPixels(0.45 * contentScale),
353372
qrSizePx: mmToPixels(8.2 * contentScale),
373+
serialFontPx: mmToPixels(1.05 * contentScale),
354374
manualFontPx: mmToPixels(1.32 * contentScale),
355375
}};
356376
}}
@@ -429,6 +449,14 @@
429449
brandY
430450
);
431451
452+
const serialText = label.serial_num || "";
453+
ctx.font = `600 ${{metrics.serialFontPx}}px "Avenir Next", "Segoe UI", sans-serif`;
454+
const serialMetrics = ctx.measureText(serialText);
455+
const serialHeight = textHeight(serialMetrics, metrics.serialFontPx);
456+
const serialX = metrics.contentLeftPx + ((metrics.contentWidthPx - serialMetrics.width) / 2);
457+
const serialY = brandY + brandHeight + metrics.headerGap;
458+
ctx.fillText(serialText, serialX, serialY);
459+
432460
const manualText = formatManualCode(label.manualcode);
433461
ctx.font = `600 ${{metrics.manualFontPx}}px "Avenir Next", "Segoe UI", sans-serif`;
434462
const manualMetrics = ctx.measureText(manualText);
@@ -443,7 +471,7 @@
443471
ctx.fillText(manualText, manualX, manualY);
444472
445473
const qrCanvas = await qrToCanvas(label.qrcode, metrics.qrSizePx);
446-
const qrRegionTop = brandY + brandHeight + metrics.gap;
474+
const qrRegionTop = serialY + serialHeight + metrics.gap;
447475
const qrRegionBottom = manualY - metrics.gap;
448476
const qrY = qrRegionTop + Math.max(0, Math.floor((qrRegionBottom - qrRegionTop - metrics.qrSizePx) / 2));
449477
const qrX = metrics.contentLeftPx + Math.floor((metrics.contentWidthPx - metrics.qrSizePx) / 2);
@@ -488,7 +516,10 @@
488516
const item = make("section", "label-item");
489517
const card = make("div", "label");
490518
const content = make("div", "label-content");
519+
const header = make("div", "header-stack");
491520
const brand = makeBrand();
521+
const serialNumber = make("div", "serial-number", label.serial_num);
522+
header.append(brand, serialNumber);
492523
493524
const qrWrap = make("div", "qr-wrap");
494525
const qrBox = make("div", "qr-box");
@@ -504,7 +535,7 @@
504535
}});
505536
actions.append(downloadButton);
506537
507-
content.append(brand, qrWrap, manualCode);
538+
content.append(header, qrWrap, manualCode);
508539
card.append(content);
509540
item.append(card, actions);
510541
sheet.append(item);

0 commit comments

Comments
 (0)