diff --git a/components/truma_inetbox/TriggerDiscoveryButton.cpp b/components/truma_inetbox/TriggerDiscoveryButton.cpp new file mode 100644 index 0000000..537eae3 --- /dev/null +++ b/components/truma_inetbox/TriggerDiscoveryButton.cpp @@ -0,0 +1,19 @@ +#include "TriggerDiscoveryButton.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace truma_inetbox { + +static const char *const TAG = "truma_inetbox.TriggerDiscoveryButton"; + +void TriggerDiscoveryButton::press_action() { + ESP_LOGI(TAG, "Discovery button pressed"); + if (this->parent_ != nullptr) { + this->parent_->trigger_discovery(); + } else { + ESP_LOGW(TAG, "No parent TrumaiNetBoxApp found"); + } +} + +} // namespace truma_inetbox +} // namespace esphome \ No newline at end of file diff --git a/components/truma_inetbox/TriggerDiscoveryButton.h b/components/truma_inetbox/TriggerDiscoveryButton.h new file mode 100644 index 0000000..18e4407 --- /dev/null +++ b/components/truma_inetbox/TriggerDiscoveryButton.h @@ -0,0 +1,21 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/button/button.h" +#include "TrumaiNetBoxApp.h" + +namespace esphome { +namespace truma_inetbox { + +class TriggerDiscoveryButton : public button::Button, public Component { + public: + void set_parent(TrumaiNetBoxApp *parent) { this->parent_ = parent; } + + protected: + void press_action() override; + + TrumaiNetBoxApp *parent_; +}; + +} // namespace truma_inetbox +} // namespace esphome \ No newline at end of file diff --git a/components/truma_inetbox/TrumaiNetBoxApp.cpp b/components/truma_inetbox/TrumaiNetBoxApp.cpp index 2a4126f..82fbdb7 100644 --- a/components/truma_inetbox/TrumaiNetBoxApp.cpp +++ b/components/truma_inetbox/TrumaiNetBoxApp.cpp @@ -474,4 +474,28 @@ bool TrumaiNetBoxApp::master_scan_b2(uint8_t nad, uint8_t ident_start, uint8_t i return true; } +void TrumaiNetBoxApp::trigger_discovery() { + if (!this->master_mode_) { + ESP_LOGW(TAG, "Discovery can only be triggered in master mode"); + return; + } + + // Start targeted device discovery like CP Plus does + // Query known Truma device identifiers instead of full scan + + // Query identifier 0x23 - typical for Truma heaters + std::vector heater_query = {0xB2, 0x23, 0x17, 0x46, 0x01, 0x03}; + this->master_send_diag_single(0x7F, heater_query); + + // Query identifier 0x00 - LIN Product Identification + std::vector prod_id_query = {0xB2, 0x00, 0x17, 0x46, 0x00, 0x1F}; + this->master_send_diag_single(0x7F, prod_id_query); + + // Query identifier 0x00 with different device signatures + std::vector heater_prod_query = {0xB2, 0x00, 0x17, 0x46, 0x40, 0x03}; // Heater signature + this->master_send_diag_single(0x7F, heater_prod_query); + + ESP_LOGI(TAG, "Manual discovery triggered - sending CP Plus style discovery commands"); +} + } } diff --git a/components/truma_inetbox/TrumaiNetBoxApp.h b/components/truma_inetbox/TrumaiNetBoxApp.h index 3bd0e60..fdd21e1 100644 --- a/components/truma_inetbox/TrumaiNetBoxApp.h +++ b/components/truma_inetbox/TrumaiNetBoxApp.h @@ -31,6 +31,7 @@ class TrumaiNetBoxApp : public LinBusProtocol { // Master scanner API bool master_send_diag_single(uint8_t nad, const std::vector &payload); bool master_scan_b2(uint8_t nad, uint8_t ident_start, uint8_t ident_end ); + void trigger_discovery(); TRUMA_DEVICE get_heater_device() const { return this->heater_device_; } TRUMA_DEVICE get_aircon_device() const { return this->aircon_device_; } diff --git a/components/truma_inetbox/button.py b/components/truma_inetbox/button.py new file mode 100644 index 0000000..bb83989 --- /dev/null +++ b/components/truma_inetbox/button.py @@ -0,0 +1,27 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import button +from esphome.const import CONF_ID + +from . import TrumaINetBoxApp, truma_inetbox_ns, CONF_TRUMA_INETBOX_ID + +DEPENDENCIES = ["truma_inetbox"] + +TriggerDiscoveryButton = truma_inetbox_ns.class_( + "TriggerDiscoveryButton", button.Button, cg.Component +) + +CONFIG_SCHEMA = { + cv.GenerateID(): cv.declare_id(TriggerDiscoveryButton), + cv.GenerateID(CONF_TRUMA_INETBOX_ID): cv.use_id(TrumaINetBoxApp), +} + +CONFIG_SCHEMA = button.button_schema(TriggerDiscoveryButton).extend(CONFIG_SCHEMA) + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await button.register_button(var, config) + await cg.register_component(var, config) + + parent = await cg.get_variable(config[CONF_TRUMA_INETBOX_ID]) + cg.add(var.set_parent(parent)) \ No newline at end of file