diff --git a/esphome/components/canbus/__init__.py b/esphome/components/canbus/__init__.py index 5f614eb0a4..20f2642144 100644 --- a/esphome/components/canbus/__init__.py +++ b/esphome/components/canbus/__init__.py @@ -10,6 +10,7 @@ IS_PLATFORM_COMPONENT = True CONF_CAN_ID = "can_id" CONF_CAN_ID_MASK = "can_id_mask" CONF_USE_EXTENDED_ID = "use_extended_id" +CONF_REMOTE_TRANSMISSION_REQUEST = "remote_transmission_request" CONF_CANBUS_ID = "canbus_id" CONF_BIT_RATE = "bit_rate" CONF_ON_FRAME = "on_frame" @@ -122,6 +123,7 @@ async def register_canbus(var, config): cv.GenerateID(CONF_CANBUS_ID): cv.use_id(CanbusComponent), cv.Optional(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF), cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean, + cv.Optional(CONF_REMOTE_TRANSMISSION_REQUEST, default=False): cv.boolean, cv.Required(CONF_DATA): cv.templatable(validate_raw_data), }, validate_id, @@ -140,6 +142,11 @@ async def canbus_action_to_code(config, action_id, template_arg, args): ) cg.add(var.set_use_extended_id(use_extended_id)) + remote_transmission_request = await cg.templatable( + config[CONF_REMOTE_TRANSMISSION_REQUEST], args, bool + ) + cg.add(var.set_remote_transmission_request(remote_transmission_request)) + data = config[CONF_DATA] if isinstance(data, bytes): data = [int(x) for x in data] diff --git a/esphome/components/canbus/canbus.cpp b/esphome/components/canbus/canbus.cpp index 14dc1544cf..5d9084706b 100644 --- a/esphome/components/canbus/canbus.cpp +++ b/esphome/components/canbus/canbus.cpp @@ -22,20 +22,22 @@ void Canbus::dump_config() { } } -void Canbus::send_data(uint32_t can_id, bool use_extended_id, const std::vector &data) { +void Canbus::send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request, + const std::vector &data) { struct CanFrame can_message; uint8_t size = static_cast(data.size()); if (use_extended_id) { - ESP_LOGD(TAG, "send extended id=0x%08x size=%d", can_id, size); + ESP_LOGD(TAG, "send extended id=0x%08x rtr=%s size=%d", can_id, TRUEFALSE(remote_transmission_request), size); } else { - ESP_LOGD(TAG, "send extended id=0x%03x size=%d", can_id, size); + ESP_LOGD(TAG, "send extended id=0x%03x rtr=%s size=%d", can_id, TRUEFALSE(remote_transmission_request), size); } if (size > CAN_MAX_DATA_LENGTH) size = CAN_MAX_DATA_LENGTH; can_message.can_data_length_code = size; can_message.can_id = can_id; can_message.use_extended_id = use_extended_id; + can_message.remote_transmission_request = remote_transmission_request; for (int i = 0; i < size; i++) { can_message.data[i] = data[i]; diff --git a/esphome/components/canbus/canbus.h b/esphome/components/canbus/canbus.h index 0491e8d3c1..20c490c083 100644 --- a/esphome/components/canbus/canbus.h +++ b/esphome/components/canbus/canbus.h @@ -62,7 +62,12 @@ class Canbus : public Component { float get_setup_priority() const override { return setup_priority::HARDWARE; } void loop() override; - void send_data(uint32_t can_id, bool use_extended_id, const std::vector &data); + void send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request, + const std::vector &data); + void send_data(uint32_t can_id, bool use_extended_id, const std::vector &data) { + // for backwards compatibility only + this->send_data(can_id, use_extended_id, false, data); + } void set_can_id(uint32_t can_id) { this->can_id_ = can_id; } void set_use_extended_id(bool use_extended_id) { this->use_extended_id_ = use_extended_id; } void set_bitrate(CanSpeed bit_rate) { this->bit_rate_ = bit_rate; } @@ -96,21 +101,26 @@ template class CanbusSendAction : public Action, public P void set_use_extended_id(bool use_extended_id) { this->use_extended_id_ = use_extended_id; } + void set_remote_transmission_request(bool remote_transmission_request) { + this->remote_transmission_request_ = remote_transmission_request; + } + void play(Ts... x) override { auto can_id = this->can_id_.has_value() ? *this->can_id_ : this->parent_->can_id_; auto use_extended_id = this->use_extended_id_.has_value() ? *this->use_extended_id_ : this->parent_->use_extended_id_; if (this->static_) { - this->parent_->send_data(can_id, use_extended_id, this->data_static_); + this->parent_->send_data(can_id, use_extended_id, this->remote_transmission_request_, this->data_static_); } else { auto val = this->data_func_(x...); - this->parent_->send_data(can_id, use_extended_id, val); + this->parent_->send_data(can_id, use_extended_id, this->remote_transmission_request_, val); } } protected: optional can_id_{}; optional use_extended_id_{}; + bool remote_transmission_request_{false}; bool static_{false}; std::function(Ts...)> data_func_{}; std::vector data_static_{}; diff --git a/tests/test1.yaml b/tests/test1.yaml index 181f62d3f4..77c4a76bda 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -2616,6 +2616,16 @@ text_sensor: canbus_id: esp32_internal_can can_id: 23 data: [0x10, 0x20, 0x30] + - canbus.send: + canbus_id: mcp2515_can + can_id: 24 + remote_transmission_request: true + data: [] + - canbus.send: + canbus_id: esp32_internal_can + can_id: 24 + remote_transmission_request: true + data: [] - platform: template name: Template Text Sensor id: ${textname}_text