From 38259c96c9c5e49154be9f25a89e68741034071a Mon Sep 17 00:00:00 2001 From: Felix Storm Date: Thu, 17 Feb 2022 05:00:31 +0100 Subject: [PATCH] CAN bus: support bit mask for on_frame can_id (#3196) --- esphome/components/canbus/__init__.py | 16 ++++++++--- esphome/components/canbus/canbus.cpp | 5 ++-- esphome/components/canbus/canbus.h | 8 +++--- tests/test1.yaml | 38 +++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/esphome/components/canbus/__init__.py b/esphome/components/canbus/__init__.py index 808b31d1d2..5f614eb0a4 100644 --- a/esphome/components/canbus/__init__.py +++ b/esphome/components/canbus/__init__.py @@ -8,6 +8,7 @@ CODEOWNERS = ["@mvturnho", "@danielschramm"] IS_PLATFORM_COMPONENT = True CONF_CAN_ID = "can_id" +CONF_CAN_ID_MASK = "can_id_mask" CONF_USE_EXTENDED_ID = "use_extended_id" CONF_CANBUS_ID = "canbus_id" CONF_BIT_RATE = "bit_rate" @@ -38,7 +39,7 @@ canbus_ns = cg.esphome_ns.namespace("canbus") CanbusComponent = canbus_ns.class_("CanbusComponent", cg.Component) CanbusTrigger = canbus_ns.class_( "CanbusTrigger", - automation.Trigger.template(cg.std_vector.template(cg.uint8)), + automation.Trigger.template(cg.std_vector.template(cg.uint8), cg.uint32), cg.Component, ) CanSpeed = canbus_ns.enum("CAN_SPEED") @@ -72,6 +73,9 @@ CANBUS_SCHEMA = cv.Schema( { cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger), cv.Required(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF), + cv.Optional(CONF_CAN_ID_MASK, default=0x1FFFFFFF): cv.int_range( + min=0, max=0x1FFFFFFF + ), cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean, }, validate_id, @@ -90,11 +94,16 @@ async def setup_canbus_core_(var, config): for conf in config.get(CONF_ON_FRAME, []): can_id = conf[CONF_CAN_ID] + can_id_mask = conf[CONF_CAN_ID_MASK] ext_id = conf[CONF_USE_EXTENDED_ID] - trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var, can_id, ext_id) + trigger = cg.new_Pvariable( + conf[CONF_TRIGGER_ID], var, can_id, can_id_mask, ext_id + ) await cg.register_component(trigger, conf) await automation.build_automation( - trigger, [(cg.std_vector.template(cg.uint8), "x")], conf + trigger, + [(cg.std_vector.template(cg.uint8), "x"), (cg.uint32, "can_id")], + conf, ) @@ -126,7 +135,6 @@ async def canbus_action_to_code(config, action_id, template_arg, args): if CONF_CAN_ID in config: can_id = await cg.templatable(config[CONF_CAN_ID], args, cg.uint32) cg.add(var.set_can_id(can_id)) - use_extended_id = await cg.templatable( config[CONF_USE_EXTENDED_ID], args, cg.uint32 ) diff --git a/esphome/components/canbus/canbus.cpp b/esphome/components/canbus/canbus.cpp index d9f6ded85d..14dc1544cf 100644 --- a/esphome/components/canbus/canbus.cpp +++ b/esphome/components/canbus/canbus.cpp @@ -78,8 +78,9 @@ void Canbus::loop() { // fire all triggers for (auto *trigger : this->triggers_) { - if ((trigger->can_id_ == can_message.can_id) && (trigger->use_extended_id_ == can_message.use_extended_id)) { - trigger->trigger(data); + if ((trigger->can_id_ == (can_message.can_id & trigger->can_id_mask_)) && + (trigger->use_extended_id_ == can_message.use_extended_id)) { + trigger->trigger(data, can_message.can_id); } } } diff --git a/esphome/components/canbus/canbus.h b/esphome/components/canbus/canbus.h index 37adf0bc9c..0491e8d3c1 100644 --- a/esphome/components/canbus/canbus.h +++ b/esphome/components/canbus/canbus.h @@ -116,17 +116,19 @@ template class CanbusSendAction : public Action, public P std::vector data_static_{}; }; -class CanbusTrigger : public Trigger>, public Component { +class CanbusTrigger : public Trigger, uint32_t>, public Component { friend class Canbus; public: - explicit CanbusTrigger(Canbus *parent, const std::uint32_t can_id, const bool use_extended_id) - : parent_(parent), can_id_(can_id), use_extended_id_(use_extended_id){}; + explicit CanbusTrigger(Canbus *parent, const std::uint32_t can_id, const std::uint32_t can_id_mask, + const bool use_extended_id) + : parent_(parent), can_id_(can_id), can_id_mask_(can_id_mask), use_extended_id_(use_extended_id){}; void setup() override { this->parent_->add_trigger(this); } protected: Canbus *parent_; uint32_t can_id_; + uint32_t can_id_mask_; bool use_extended_id_; }; diff --git a/tests/test1.yaml b/tests/test1.yaml index d8fea223dc..54343f59c7 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -2551,6 +2551,25 @@ canbus: lambda: "return x[0] == 0x11;" then: light.toggle: ${roomname}_lights + - can_id: 0b00000000000000000000001000000 + can_id_mask: 0b11111000000000011111111000000 + use_extended_id: true + then: + - lambda: |- + auto pdo_id = can_id >> 14; + switch (pdo_id) + { + case 117: + ESP_LOGD("canbus", "exhaust_fan_duty"); + break; + case 118: + ESP_LOGD("canbus", "supply_fan_duty"); + break; + case 119: + ESP_LOGD("canbus", "supply_fan_flow"); + break; + // to be continued... + } - platform: esp32_can id: esp32_internal_can rx_pin: GPIO04 @@ -2570,6 +2589,25 @@ canbus: lambda: "return x[0] == 0x11;" then: light.toggle: ${roomname}_lights + - can_id: 0b00000000000000000000001000000 + can_id_mask: 0b11111000000000011111111000000 + use_extended_id: true + then: + - lambda: |- + auto pdo_id = can_id >> 14; + switch (pdo_id) + { + case 117: + ESP_LOGD("canbus", "exhaust_fan_duty"); + break; + case 118: + ESP_LOGD("canbus", "supply_fan_duty"); + break; + case 119: + ESP_LOGD("canbus", "supply_fan_flow"); + break; + // to be continued... + } teleinfo: id: myteleinfo