Repository: esphome/esphome (2026-04-12T14:05:05Z)

Issue:
Canbus compilation error with recent dev (2026.5.0)
### The problem

Compilation error linked with can_id. Used to work fine with 2026.4.0

### Which version of ESPHome has the issue?

2026.5.0

### What type of installation are you using?

pip

### What platform are you using?

ESP32

### Component causing the issue

canbus

### YAML Config

```yaml
substitutions:
  device_name: 'test_canbus'
  module_address: "1"

esphome:
  name: ${device_name}
  friendly_name: ${friendly_name}
  platformio_options:
    board_build.flash_mode: dio
  on_boot:
    priority: -100
    then:
      - delay: 2s
      # Query program version at startup
      - canbus.send:
          canbus_id: pcm_can
          use_extended_id: true
          can_id: 0x03000A07
          data: [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

esp32:
  board: esp32dev
  framework:
    type: esp-idf
    version: 'dev'

# Enable logging
logger:
  level: DEBUG


# Enable Home Assistant API
api:
  # encryption:
    # key: !secret api_encryption_key

ota:
  - platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  
  # Enable fallback hotspot
  ap:
    ssid: "${device_name} Fallback"
    password: !secret ap_password

captive_portal:

# Web server for debugging
# web_server:
  # port: 80

# CAN Bus Configuration
canbus:
  - platform: esp32_can
    id: pcm_can
    tx_pin: GPIO5
    rx_pin: GPIO4
    can_id: 0x0A  # Upper computer address
    bit_rate: 250kbps
    use_extended_id: true
    
    on_frame:
      # Feedback Parameter 1 - 0x010A0051
      - can_id: 0x010A0051
        use_extended_id: true
        then:
          - lambda: |-
              uint8_t module_addr = x[0];
              uint8_t running_mode = x[1];
              uint16_t grid_voltage = (x[3] << 8) | x[2];
              uint16_t inverter_voltage = (x[5] << 8) | x[4];
              uint16_t inverting_current = (x[7] << 8) | x[6];
              
              id(grid_voltage_sensor).publish_state(grid_voltage / 10.0);
              id(inverter_voltage_sensor).publish_state(inverter_voltage / 10.0);
              id(inverting_current_sensor).publish_state(inverting_current / 10.0);
              id(running_mode_sensor).publish_state(running_mode);
              
              ESP_LOGD("canbus", "Feedback 1 - Module: %d, Mode: %d, Grid: %.1fV, Inv: %.1fV, Current: %.1fA", 
                       module_addr, running_mode, grid_voltage/10.0, inverter_voltage/10.0, inverting_current/10.0);
      
 

# Sensors
sensor:
  # Grid and Inverter
  - platform: template
    id: grid_voltage_sensor
    name: "${friendly_name} Grid Voltage"
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    id: inverter_voltage_sensor
    name: "${friendly_name} Inverter Voltage"
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    id: inverting_current_sensor
    name: "${friendly_name} Inverting Current"
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 1
  
  # DC Side
  - platform: template
    id: dc_voltage_sensor
    name: "${friendly_name} DC Voltage"
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    id: dc_current_sensor
    name: "${friendly_name} DC Current"
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    id: load_current_sensor
    name: "${friendly_name} Load Current"
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 1
  
  # Power
  - platform: template
    id: power_sensor
    name: "${friendly_name} Power"
    unit_of_measurement: "W"
    device_class: power
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    id: dc_power_sensor
    name: "${friendly_name} DC Power"
    unit_of_measurement: "W"
    device_class: power
    state_class: measurement
    accuracy_decimals: 1
  
  # Temperature
  - platform: template
    id: temperature1_sensor
    name: "${friendly_name} Temperature 1"
    unit_of_measurement: "°C"
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 0
    
  - platform: template
    id: temperature2_sensor
    name: "${friendly_name} Temperature 2"
    unit_of_measurement: "°C"
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 0
  
  # Running Mode as Number
  - platform: template
    id: running_mode_sensor
    name: "${friendly_name} Running Mode Value"
    accuracy_decimals: 0
    internal: true
  
  # Inverter Frequency
  - platform: template
    id: inverter_frequency_sensor
    name: "${friendly_name} Inverter Frequency Value"
    accuracy_decimals: 0
    internal: true

# Text Sensors
text_sensor:
  - platform: template
    id: running_mode_text
    name: "${friendly_name} Running Mode"
    icon: mdi:state-machine
    update_interval: 1s
    lambda: |-
      int mode = id(running_mode_sensor).state;
      switch(mode) {
        case 0: return {"Initialize"};
        case 1: return {"Standby"};
        case 2: return {"Grid-connected Charging"};
        case 3: return {"Grid-connected Discharge"};
        case 4: return {"Off-grid Inverter"};
        case 5: return {"Fault"};
        default: return {"Unknown"};
      }
  

# Switches and Controls
switch:
  # Power ON/OFF
  - platform: template
    name: "${friendly_name} Power"
    id: power_switch
    icon: mdi:power
    optimistic: false
    turn_on_action:
      - canbus.send:
          canbus_id: pcm_can
          can_id: 0x02000A01
          use_extended_id: true
          data: !lambda |-
            return {${module_address}, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
      - delay: 100ms
    turn_off_action:
      - canbus.send:
          canbus_id: pcm_can
          can_id: 0x02000A01
          use_extended_id: true
          data: !lambda |-
            return {${module_address}, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
      - delay: 100ms

# Buttons
button:
  # Reset
  - platform: template
    name: "${friendly_name} Reset"
    icon: mdi:restart
    on_press:
      - canbus.send:
          canbus_id: pcm_can
          can_id: 0x02000A01
          use_extended_id: true
          data: !lambda |-
            return {${module_address}, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
  
 
# Select Controls
select:
  # Grid Mode
  - platform: template
    name: "${friendly_name} Grid Mode"
    id: grid_mode_select
    icon: mdi:transmission-tower
    optimistic: true
    options:
      - "Grid-connected Charging"
      - "Grid-connected Discharge"
    on_value:
      - canbus.send:
          canbus_id: pcm_can
          can_id: 0x02000A02
          use_extended_id: true
          data: !lambda |-
            uint8_t mode = 0;
            if (x == "Grid-connected Discharge") mode = 1;
            return {${module_address}, 0x00, mode, 0x00, 0x00, 0x00, 0x00, 0x00};
```

### Anything in the logs that might be useful for us?

```
Compiling .pioenvs\test_canbus\console\argtable3\arg_rem.c.o
test_canbus.yaml: In function 'Compiling .pioenvs\test_canbus\console\argtable3\arg_rex.c.o
void setup()':
Compiling .pioenvs\test_canbus\console\argtable3\arg_str.c.o
test_canbus.yaml:252:44: error: invalid user-defined conversion from 'setup()::<lambda()>' to 'uint32_t' {aka 'long unsigned intCompiling .pioenvs\test_canbus\console\argtable3\arg_utils.c.o
'} [-fpermissive]
test_canbus.yaml:252:44: Compiling .pioenvs\test_canbus\console\argtable3\argtable3.c.o
note: candidate is: 'constexpr setup()::<lambda()>::operator uint32_t (*)()() const' (near match)
test_canbus.yaml:252:44: note:   no known conversion from 'Compiling .pioenvs\test_canbus\cxx\cxx_exception_stubs.cpp.o
uint32_t (*)()' {aka 'long unsigned int (*)()'} to 'uint32_t' {aka 'long unsigned int'}
In file included from src/esphome.h:23,
                 from src/main.cpp:3:
src/esphome\components\canbus\canbus.h:124:28: note:   initializing argument 1 of 'void esphome::canbus::CanbusSendAction<Ts>::set_can_id(uint32_t) [with Ts = {}; uint32_t = long unsigned int]'
  124 |   void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
      |                   ~~~~~~~~~^~~~~~
test_canbus.yaml:241:44: error: invalid user-defined conversion from 'setup()::<lambda()>' to 'uint32_t' {aka 'long unsigned int'} [-fpermissive]
test_canbus.yaml:241:44: note: candidate is: 'constexpr setup()::<lambda()>::operator uint32_t (*)()() const' (near match)
test_canbus.yaml:241:44: note:   no known conversion from 'uint32_t (*)()' {aka 'long unsigned int (*)()'} to 'uint32_t' {aka 'long unsigned int'}
src/esphome\components\canbus\canbus.h:124:28: note:   initializing argument 1 of 'void esphome::canbus::CanbusSendAction<Ts>::set_can_id(uint32_t) [with Ts = {}; uint32_t = long unsigned int]'
  124 |   void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
      |                   ~~~~~~~~~^~~~~~
Compiling .pioenvs\test_canbus\cxx\cxx_guards.cpp.o
test_canbus.yaml:255:44: error: invalid user-defined conversion from 'setup()::<lambda()>' to 'uint32_t' {aka 'long unsigned int'} [-fpermissive]
Compiling .pioenvs\test_canbus\cxx\cxx_init.cpp.o
test_canbus.yaml:255:44: note: candidate is: 'constexpr setup()::<lambda()>::operator uint32_t (*)()() const' (near match)
test_canbus.yaml:255:44: note:   no known conversion from 'uint32_t (*)()' {aka 'long unsigned int (*)()'} to 'uint32_t' {aka 'long unsigned int'}
src/esphome\components\canbus\canbus.h:124:28: note:   initializing argument 1 of 'void esphome::canbus::CanbusSendAction<Ts>::set_can_id(uint32_t) [with Ts = {}; uint32_t = long unsigned int]'
  124 |   void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
      |                   ~~~~~~~~~^~~~~~
test_canbus.yaml:285:44: error: invalid user-defined conversion from 'setup()::<lambda(esphome::StringRef, size_t)>' to 'uint32_t' {aka 'long unsigned int'} [-fpermissive]
test_canbus.yaml:285:44: note: candidate is: 'constexpr setup()::<lambda(esphome::StringRef, size_t)>::operator uint32_t (*)(esphome::StringRef, size_t)() const' (near match)
test_canbus.yaml:285:44: note:   no known conversion from 'uint32_t (*)(esphome::StringRef, size_t)' {aka 'long unsigned int (*)(esphome::StringRef, unsigned int)'} to 'uint32_t' {aka 'long unsigned int'}
src/esphome\components\canbus\canbus.h:124:28: note:   initializing argument 1 of 'void esphome::canbus::CanbusSendAction<Ts>::set_can_id(uint32_t) [with Ts = {esphome::StringRef, unsigned int}; uint32_t = long unsigned int]'
  124 |   void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
      |                   ~~~~~~~~~^~~~~~
test_canbus.yaml:278:42: error: invalid user-defined conversion from 'setup()::<lambda()>' to 'uint32_t' {aka 'long unsigned int'} [-fpermissive]
test_canbus.yaml:278:42: note: candidate is: 'constexpr setup()::<lambda()>::operator uint32_t (*)()() const' (near match)
test_canbus.yaml:278:42: note:   no known conversion from 'uint32_t (*)()' {aka 'long unsigned int (*)()'} to 'uint32_t' {aka 'long unsigned int'}
src/esphome\components\canbus\canbus.h:124:28: note:   initializing argument 1 of 'void esphome::canbus::CanbusSendAction<Ts>::set_can_id(uint32_t) [with Ts = {}; uint32_t = long unsigned int]'
  124 |   void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
      |                   ~~~~~~~~~^~~~~~
Compiling .pioenvs\test_canbus\driver\deprecated\adc_legacy.c.o
*** [.pioenvs\test_canbus\src\main.cpp.o] Error 1

```

### Additional information

_No response_


Discussion:

Patch:
diff --git a/esphome/components/canbus/__init__.py b/esphome/components/canbus/__init__.py
index 7d3bf78f4925..fcd342ad3891 100644
--- a/esphome/components/canbus/__init__.py
+++ b/esphome/components/canbus/__init__.py
@@ -162,7 +162,6 @@ async def canbus_action_to_code(config, action_id, template_arg, args):
     await cg.register_parented(var, config[CONF_CANBUS_ID])
 
     if (can_id := config.get(CONF_CAN_ID)) is not None:
-        can_id = await cg.templatable(can_id, args, cg.uint32)
         cg.add(var.set_can_id(can_id))
         cg.add(var.set_use_extended_id(config[CONF_USE_EXTENDED_ID]))
 


Test patch:
diff --git a/tests/components/canbus/common.yaml b/tests/components/canbus/common.yaml
index 8bddeb740948..e779f7f078b1 100644
--- a/tests/components/canbus/common.yaml
+++ b/tests/components/canbus/common.yaml
@@ -50,6 +50,13 @@ button:
   - platform: template
     name: Canbus Actions
     on_press:
+      - canbus.send:
+          can_id: 0x601
+          data: [0, 1, 2]
+      - canbus.send:
+          can_id: 0x1FFFFFFF
+          use_extended_id: true
+          data: [0, 1, 2]
       - canbus.send: "abc"
       - canbus.send: [0, 1, 2]
       - canbus.send: !lambda return {0, 1, 2};