mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 02:02:51 +00:00
Merge remote-tracking branch 'origin/dev' into light-effect-color-tables
This commit is contained in:
@@ -53,7 +53,7 @@ module.exports = async ({ github, context }) => {
|
||||
});
|
||||
const currentLabels = currentLabelsData.map(label => label.name);
|
||||
const managedLabels = currentLabels.filter(label =>
|
||||
label.startsWith('component: ') || MANAGED_LABELS.includes(label)
|
||||
label.startsWith('component: ') || label.startsWith('platform: ') || MANAGED_LABELS.includes(label)
|
||||
);
|
||||
|
||||
// Check for mega-PR early - if present, skip most automatic labeling
|
||||
|
||||
@@ -15,6 +15,8 @@ on:
|
||||
# base branch checkout, so fork code never runs with the token.
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- dev
|
||||
paths:
|
||||
- requirements_dev.txt
|
||||
- requirements_test.txt
|
||||
|
||||
@@ -48,7 +48,7 @@ PROJECT_NAME = ESPHome
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 2026.10.0-dev
|
||||
PROJECT_NUMBER = 2026.11.0-dev
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -3074,6 +3074,10 @@ async def to_code(config):
|
||||
# Increase freertos tick speed from 100Hz to 1kHz so that delay() resolution is 1ms
|
||||
add_idf_sdkconfig_option("CONFIG_FREERTOS_HZ", 1000)
|
||||
|
||||
# Main loop wakes use notification index 1; index 0 stays free for ESP-IDF waits
|
||||
# such as pthread_join(), which a stray main-loop wake would otherwise end early.
|
||||
add_idf_sdkconfig_option("CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES", 2)
|
||||
|
||||
# Place non-ISR FreeRTOS functions into flash instead of IRAM
|
||||
# This saves up to 8KB of IRAM. ISR-safe functions (FromISR variants) stay in IRAM.
|
||||
# In ESP-IDF 6.0 this becomes the default and CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
|
||||
@@ -15,9 +15,12 @@ static const uint8_t STARTUP_SEQUENCE[][2] PROGMEM = {
|
||||
{0x60, 0x01}, // ADR_PIN_CTRL: output
|
||||
{0x7D, 0x11},
|
||||
{0x7E, 0xFF},
|
||||
{0x00, 0x01},
|
||||
{0x00, 0x01}, // Page 1
|
||||
{0x51, 0x05},
|
||||
{0x00, 0x00},
|
||||
{0x00, 0x00}, // Page 0
|
||||
|
||||
// Additional register configuration
|
||||
{0x53, 0x60}, // ANA_CTRL: for high audio performance use 175kHz bandwidth with Fsw=768kHz
|
||||
};
|
||||
|
||||
static const LogString *model_name() { return LOG_STR("TAS5805M"); }
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
|
||||
namespace esphome::tas58xx {
|
||||
|
||||
// Remainder of the startup sequence, run after the reset. Register 0x00 selects the page.
|
||||
// All writes except starting and last three register writes are exactly the startup sequence from TI PurePath Console.
|
||||
// Registers 0x46, 0x7D, 0x7E, page 1 register 0x51 and Page 2 registers 0x1D, 0x19 are not documented in the datasheet.
|
||||
|
||||
// clang-format off
|
||||
// Remainder of the startup sequence, run after the reset in TAS58xx::init_(). Register 0x00 selects the page.
|
||||
// Based on the TI PurePath Console (PPC) export for "TAS5825M 2-Band DRC&AGL 2.0 96k".
|
||||
// Registers 0x46, 0x7D, 0x7E, page 1 register 0x51 and page 2 registers 0x1D, 0x19 are not documented in datasheet.
|
||||
static const uint8_t STARTUP_SEQUENCE[][2] PROGMEM = {
|
||||
{0x03, 0x00}, // Deep Sleep
|
||||
{0x03, 0x00}, // DEVICE_CTRL_2: deep sleep, the state the PPC sequence starts from
|
||||
{0x7D, 0x11},
|
||||
{0x7E, 0xFF},
|
||||
{0x00, 0x01}, // Page 1
|
||||
@@ -20,15 +18,16 @@ static const uint8_t STARTUP_SEQUENCE[][2] PROGMEM = {
|
||||
{0x19, 0x80},
|
||||
{0x00, 0x00}, // Page 0
|
||||
{0x46, 0x11},
|
||||
{0x02, 0x00}, // DEVICE_CTRL_1 - BD MODE, Damp to PBL MODE
|
||||
{0x53, 0x01}, // ANA_CTRL PWM Phase Control - in phase
|
||||
{0x54, 0x00}, // AGAIN 0dB
|
||||
{0x03, 0x02}, // Hi-Z
|
||||
{0x61, 0x0B}, // GPIO0_SEL - GPIO0 as FAULTZ output
|
||||
{0x60, 0x01}, // GPIO0_OE - Enable GPIO0 as output
|
||||
{0x77, 0x07}, // CBC_CONTROL enabling CBC function for warnings and faults
|
||||
// PPC also writes 0x02 (DEVICE_CTRL_1) and 0x54 (AGAIN) here; init_() writes both from YAML
|
||||
{0x53, 0x01}, // ANA_CTRL: in phase, 100kHz bandwidth for high audio performance with Fsw=384kHz
|
||||
{0x03, 0x02}, // DEVICE_CTRL_2: Hi-Z
|
||||
|
||||
// Additional register configuration
|
||||
// GPIO1 is a dedicated pin on TAS5825M (separate from ADR), used as FAULTZ
|
||||
{0x62, 0x0B}, // GPIO1_SEL: GPIO1 as FAULTZ
|
||||
{0x60, 0x02}, // GPIO_CTRL: GPIO1 is output
|
||||
{0x77, 0x07}, // CBC_CONTROL: enable cycle-by-cycle current limit for warnings and faults
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static const LogString *model_name() { return LOG_STR("TAS5825M"); }
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ from enum import Enum
|
||||
|
||||
from esphome.enum import StrEnum
|
||||
|
||||
__version__ = "2026.10.0-dev"
|
||||
__version__ = "2026.11.0-dev"
|
||||
|
||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||
|
||||
@@ -673,8 +673,8 @@ inline void ESPHOME_ALWAYS_INLINE Application::loop() {
|
||||
#if defined(USE_LWIP_FAST_SELECT) && defined(ESPHOME_THREAD_MULTI_ATOMICS)
|
||||
// Pairs with the TCP/IP thread's SYS_ARCH_UNPROTECT release on rcvevent so
|
||||
// subsequent Socket::ready() checks in this iter observe the published state
|
||||
// without a per-call memw. Wake is independent (xTaskNotifyGive/
|
||||
// ulTaskNotifyTake), so non-losing. Skipped on MULTI_NO_ATOMICS (e.g.
|
||||
// without a per-call memw. Wake is independent (esphome_main_task_notify/
|
||||
// esphome_main_task_wait), so non-losing. Skipped on MULTI_NO_ATOMICS (e.g.
|
||||
// BK72xx) — that path keeps `volatile` in esphome_lwip_socket_has_data()
|
||||
// instead.
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
|
||||
@@ -99,10 +99,10 @@
|
||||
// ESP32-C3/C6/H2) cross-core visibility is not an issue.
|
||||
//
|
||||
// FreeRTOS task notification value:
|
||||
// Written by TCP/IP thread (xTaskNotifyGive in callback) and background tasks
|
||||
// (xTaskNotifyGive in wake_main_loop). Read by main loop (ulTaskNotifyTake).
|
||||
// Written by TCP/IP thread (esphome_main_task_notify in callback) and background tasks
|
||||
// (esphome_main_task_notify in wake_main_loop). Read by main loop (esphome_main_task_wait).
|
||||
// Safe: FreeRTOS notification APIs are thread-safe by design (use internal
|
||||
// critical sections). Multiple concurrent xTaskNotifyGive calls are safe —
|
||||
// critical sections). Multiple concurrent notify calls are safe —
|
||||
// the notification count simply increments.
|
||||
|
||||
// USE_LWIP_FAST_SELECT is set via -D build flag (not cg.add_define) so it is
|
||||
@@ -178,7 +178,7 @@ static void esphome_socket_event_callback(struct netconn *conn, enum netconn_evt
|
||||
// s_original_callback is always valid here: hook_socket() sets it before swapping
|
||||
// the callback pointer, so this wrapper cannot run until it's initialized.
|
||||
s_original_callback(conn, evt, len);
|
||||
// Wake the main loop task if sleeping in ulTaskNotifyTake().
|
||||
// Wake the main loop task if sleeping in esphome_main_task_wait().
|
||||
// Only notify on receive events to avoid spurious wakeups from send-ready events.
|
||||
// NETCONN_EVT_ERROR is deliberately omitted: LwIP signals errors via RCVPLUS
|
||||
// (rcvevent++ with a NULL pbuf or error in recvmbox), so error conditions
|
||||
@@ -186,7 +186,7 @@ static void esphome_socket_event_callback(struct netconn *conn, enum netconn_evt
|
||||
if (evt == NETCONN_EVT_RCVPLUS) {
|
||||
#ifdef USE_OTA_PLATFORM_ESPHOME
|
||||
// Mark OTA pending-enable only for events on its listen socket. MUST happen
|
||||
// before xTaskNotifyGive so the flags are visible when the main task wakes.
|
||||
// before the main task is notified so the flags are visible when it wakes.
|
||||
if (conn == s_ota_listener_conn) {
|
||||
esphome_wake_ota_component_any_context();
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ struct lwip_sock *esphome_lwip_get_sock(int fd);
|
||||
/// per-call `memw` that volatile would emit on Xtensa under default
|
||||
/// -mserialize-volatile. Without atomics (e.g. BK72xx), the fence is skipped
|
||||
/// and the volatile load provides ordering on its own.
|
||||
/// Stale reads are harmless either way: the hooked event_callback
|
||||
/// xTaskNotifyGives on RCVPLUS, so the next iteration re-snapshots and
|
||||
/// ulTaskNotifyTake never loses a wake.
|
||||
/// Stale reads are harmless either way: the hooked event_callback calls
|
||||
/// esphome_main_task_notify() on RCVPLUS, so the next iteration re-snapshots and
|
||||
/// esphome_main_task_wait() never loses a wake.
|
||||
/// The offset and size are verified at compile time in lwip_fast_select.c.
|
||||
static inline bool esphome_lwip_socket_has_data(struct lwip_sock *sock) {
|
||||
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
||||
@@ -46,7 +46,7 @@ static inline bool esphome_lwip_socket_has_data(struct lwip_sock *sock) {
|
||||
}
|
||||
|
||||
/// Hook a socket's netconn callback to notify the main loop task on receive events.
|
||||
/// Wraps the original event_callback with one that also calls xTaskNotifyGive().
|
||||
/// Wraps the original event_callback with one that also calls esphome_main_task_notify().
|
||||
/// Must be called from the main loop after socket creation.
|
||||
/// The sock pointer must have been obtained from esphome_lwip_get_sock().
|
||||
void esphome_lwip_hook_socket(struct lwip_sock *sock);
|
||||
|
||||
@@ -19,12 +19,25 @@ extern "C" {
|
||||
|
||||
extern TaskHandle_t esphome_main_task_handle;
|
||||
|
||||
#ifdef USE_ESP32
|
||||
/// ESP-IDF waits on index 0 from the main task (e.g. pthread_join() uses an unfiltered
|
||||
/// xTaskNotifyWait), so main-loop wakes on index 0 would end those waits early.
|
||||
enum { ESPHOME_MAIN_TASK_NOTIFY_INDEX = 1 };
|
||||
#if configTASK_NOTIFICATION_ARRAY_ENTRIES < 2
|
||||
#error "CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES must be at least 2"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// Wake the main loop task from another FreeRTOS task. NOT ISR-safe.
|
||||
/// always_inline so callers placed in IRAM do not reference a flash-resident copy.
|
||||
__attribute__((always_inline)) static inline void esphome_main_task_notify() {
|
||||
TaskHandle_t task = esphome_main_task_handle;
|
||||
if (task != NULL) {
|
||||
#ifdef USE_ESP32
|
||||
xTaskNotifyGiveIndexed(task, ESPHOME_MAIN_TASK_NOTIFY_INDEX);
|
||||
#else
|
||||
xTaskNotifyGive(task);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +46,23 @@ __attribute__((always_inline)) static inline void esphome_main_task_notify_from_
|
||||
BaseType_t *px_higher_priority_task_woken) {
|
||||
TaskHandle_t task = esphome_main_task_handle;
|
||||
if (task != NULL) {
|
||||
#ifdef USE_ESP32
|
||||
vTaskNotifyGiveIndexedFromISR(task, ESPHOME_MAIN_TASK_NOTIFY_INDEX, px_higher_priority_task_woken);
|
||||
#else
|
||||
vTaskNotifyGiveFromISR(task, px_higher_priority_task_woken);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// Block the main loop task until it is woken or the timeout expires.
|
||||
__attribute__((always_inline)) static inline void esphome_main_task_wait(TickType_t ticks) {
|
||||
#ifdef USE_ESP32
|
||||
ulTaskNotifyTakeIndexed(ESPHOME_MAIN_TASK_NOTIFY_INDEX, pdTRUE, ticks);
|
||||
#else
|
||||
ulTaskNotifyTake(pdTRUE, ticks);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -43,15 +43,15 @@ namespace internal {
|
||||
inline void ESPHOME_ALWAYS_INLINE wakeable_delay(uint32_t ms) {
|
||||
// Fast path (with USE_LWIP_FAST_SELECT): FreeRTOS task notifications posted by the lwip
|
||||
// event_callback wrapper (see lwip_fast_select.c) are the single source of truth for
|
||||
// socket wake-ups. Every NETCONN_EVT_RCVPLUS posts an xTaskNotifyGive, so any notification
|
||||
// that lands between wakes keeps the counter non-zero (next ulTaskNotifyTake returns
|
||||
// immediately) or wakes a blocked Take directly. Additional wake sources:
|
||||
// socket wake-ups. Every NETCONN_EVT_RCVPLUS calls esphome_main_task_notify(), so any notification
|
||||
// that lands between wakes keeps the counter non-zero (next esphome_main_task_wait() returns
|
||||
// immediately) or wakes a blocked wait directly. Additional wake sources:
|
||||
// wake_loop_threadsafe() from background tasks, and the ms timeout.
|
||||
if (ms == 0) [[unlikely]] {
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(ms));
|
||||
esphome_main_task_wait(pdMS_TO_TICKS(ms));
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ pyserial==3.5
|
||||
platformio==6.2.0
|
||||
esptool==5.4.0
|
||||
click==8.5.0
|
||||
aioesphomeapi==46.6.0
|
||||
aioesphomeapi==46.8.0
|
||||
aiohappyeyeballs==2.7.1 # Happy Eyeballs for requests downloads; already pulled in by aioesphomeapi
|
||||
zeroconf==0.151.5
|
||||
puremagic==2.2.0
|
||||
|
||||
@@ -13,6 +13,7 @@ CONFIG_LIBC_NEWLIB=y
|
||||
# esp32
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
||||
CONFIG_ESP_TASK_WDT_INIT=y
|
||||
CONFIG_ESP_TASK_WDT_PANIC=y
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
||||
|
||||
@@ -18,6 +18,7 @@ canbus:
|
||||
lambda: "return x[0] == 0x11;"
|
||||
then:
|
||||
logger.log: Truth
|
||||
- canbus.send: !lambda return x;
|
||||
- can_id: 0b00000000000000000000001000000
|
||||
can_id_mask: 0b11111000000000011111111000000
|
||||
use_extended_id: true
|
||||
@@ -59,6 +60,9 @@ button:
|
||||
data: [0, 1, 2]
|
||||
- canbus.send: "abc"
|
||||
- canbus.send: [0, 1, 2]
|
||||
# Identical on purpose: both sends share one constant payload
|
||||
- canbus.send: [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]
|
||||
- canbus.send: [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]
|
||||
- canbus.send: !lambda return {0, 1, 2};
|
||||
# Test canbus.send with lambda that references a component (function pointer)
|
||||
- canbus.send: !lambda |-
|
||||
|
||||
@@ -10,6 +10,11 @@ canbus:
|
||||
- lambda: |-
|
||||
std::string b(x.begin(), x.end());
|
||||
ESP_LOGD("can_id 500", "%s", b.c_str());
|
||||
- canbus.send:
|
||||
canbus_id: mcp2515_can
|
||||
can_id: 501
|
||||
data: !lambda |-
|
||||
return {static_cast<uint8_t>(can_id), x.empty() ? uint8_t(0) : x[0]};
|
||||
- can_id: 23
|
||||
then:
|
||||
- if:
|
||||
@@ -36,3 +41,22 @@ canbus:
|
||||
break;
|
||||
// to be continued...
|
||||
}
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: MCP2515 Send
|
||||
on_press:
|
||||
# Identical on purpose: both sends share one constant payload
|
||||
- canbus.send:
|
||||
canbus_id: mcp2515_can
|
||||
data: [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]
|
||||
- canbus.send:
|
||||
canbus_id: mcp2515_can
|
||||
data: [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]
|
||||
- canbus.send:
|
||||
canbus_id: mcp2515_can
|
||||
can_id: 0x123
|
||||
data: "abc"
|
||||
- canbus.send:
|
||||
canbus_id: mcp2515_can
|
||||
data: !lambda return {0x01, 0x02};
|
||||
|
||||
@@ -5,6 +5,13 @@ number:
|
||||
min_value: 0
|
||||
max_value: 255
|
||||
step: 1
|
||||
on_value:
|
||||
- remote_transmitter.transmit_abbwelcome:
|
||||
source_address: 0x1234
|
||||
destination_address: 0x5678
|
||||
message_type: 0x01
|
||||
data: !lambda |-
|
||||
return {(uint8_t) x, 0x20};
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
@@ -260,6 +267,22 @@ button:
|
||||
destination_address: 0x5678
|
||||
message_type: 0x01
|
||||
data: [0x10, 0x20, 0x30]
|
||||
- platform: template
|
||||
name: ABBWelcome static same data
|
||||
on_press:
|
||||
remote_transmitter.transmit_abbwelcome:
|
||||
source_address: 0x1234
|
||||
destination_address: 0x5678
|
||||
message_type: 0x02
|
||||
data: [0x10, 0x20, 0x30]
|
||||
- platform: template
|
||||
name: ABBWelcome static empty data
|
||||
on_press:
|
||||
remote_transmitter.transmit_abbwelcome:
|
||||
source_address: 0x1234
|
||||
destination_address: 0x5678
|
||||
message_type: 0x03
|
||||
data: []
|
||||
- platform: template
|
||||
name: ABBWelcome lambda
|
||||
on_press:
|
||||
|
||||
Reference in New Issue
Block a user