mirror of
https://github.com/esphome/esphome.git
synced 2026-01-26 06:22:08 -07:00
Compare commits
14 Commits
copilot/ad
...
mqtt_stack
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d95ef154aa | ||
|
|
1c9a9c7536 | ||
|
|
e006216ad3 | ||
|
|
d66d05dbfc | ||
|
|
bba447e656 | ||
|
|
77b6720a25 | ||
|
|
2f8f052f43 | ||
|
|
86e70c7e76 | ||
|
|
40025bb277 | ||
|
|
438bb96687 | ||
|
|
c1e1325af2 | ||
|
|
944194e04e | ||
|
|
d27d6d64da | ||
|
|
2182d1e9f0 |
112
.github/workflows/auto-label-pr.yml
vendored
112
.github/workflows/auto-label-pr.yml
vendored
@@ -46,7 +46,6 @@ jobs:
|
||||
const BOT_COMMENT_MARKER = '<!-- auto-label-pr-bot -->';
|
||||
const CODEOWNERS_MARKER = '<!-- codeowners-request -->';
|
||||
const TOO_BIG_MARKER = '<!-- too-big-request -->';
|
||||
const DEPRECATED_COMPONENT_MARKER = '<!-- deprecated-component-request -->';
|
||||
|
||||
const MANAGED_LABELS = [
|
||||
'new-component',
|
||||
@@ -70,8 +69,7 @@ jobs:
|
||||
'new-feature',
|
||||
'breaking-change',
|
||||
'developer-breaking-change',
|
||||
'code-quality',
|
||||
'deprecated_component'
|
||||
'code-quality'
|
||||
];
|
||||
|
||||
const DOCS_PR_PATTERNS = [
|
||||
@@ -384,75 +382,6 @@ jobs:
|
||||
return labels;
|
||||
}
|
||||
|
||||
// Strategy: Deprecated component detection
|
||||
async function detectDeprecatedComponents() {
|
||||
const labels = new Set();
|
||||
const deprecatedInfo = [];
|
||||
|
||||
// Compile regex once for better performance
|
||||
const componentFileRegex = /^esphome\/components\/([^\/]+)\/[^/]*\.py$/;
|
||||
|
||||
// Get files that are modified or added in components directory
|
||||
const componentFiles = changedFiles.filter(file => componentFileRegex.test(file));
|
||||
|
||||
if (componentFiles.length === 0) {
|
||||
return { labels, deprecatedInfo };
|
||||
}
|
||||
|
||||
// Extract unique component names using the same regex
|
||||
const components = new Set();
|
||||
for (const file of componentFiles) {
|
||||
const match = file.match(componentFileRegex);
|
||||
if (match) {
|
||||
components.add(match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Get PR head SHA to fetch files from the PR branch
|
||||
const prHeadSha = context.payload.pull_request.head.sha;
|
||||
|
||||
// Check each component's __init__.py for DEPRECATED_COMPONENT constant
|
||||
for (const component of components) {
|
||||
const initFile = `esphome/components/${component}/__init__.py`;
|
||||
try {
|
||||
// Fetch file content from PR head using GitHub API
|
||||
const { data: fileData } = await github.rest.repos.getContent({
|
||||
owner,
|
||||
repo,
|
||||
path: initFile,
|
||||
ref: prHeadSha
|
||||
});
|
||||
|
||||
// Decode base64 content
|
||||
const content = Buffer.from(fileData.content, 'base64').toString('utf8');
|
||||
|
||||
// Look for DEPRECATED_COMPONENT = "message" or DEPRECATED_COMPONENT = 'message'
|
||||
// Support single quotes, double quotes, and triple quotes (for multiline)
|
||||
const doubleQuoteMatch = content.match(/DEPRECATED_COMPONENT\s*=\s*"""([\s\S]*?)"""/s) ||
|
||||
content.match(/DEPRECATED_COMPONENT\s*=\s*"((?:[^"\\]|\\.)*)"/);
|
||||
const singleQuoteMatch = content.match(/DEPRECATED_COMPONENT\s*=\s*'''([\s\S]*?)'''/s) ||
|
||||
content.match(/DEPRECATED_COMPONENT\s*=\s*'((?:[^'\\]|\\.)*)'/);
|
||||
const deprecatedMatch = doubleQuoteMatch || singleQuoteMatch;
|
||||
|
||||
if (deprecatedMatch) {
|
||||
labels.add('deprecated_component');
|
||||
deprecatedInfo.push({
|
||||
component: component,
|
||||
message: deprecatedMatch[1]
|
||||
});
|
||||
console.log(`Found deprecated component: ${component}`);
|
||||
}
|
||||
} catch (error) {
|
||||
// Only log if it's not a simple "file not found" error (404)
|
||||
if (error.status !== 404) {
|
||||
console.log(`Error reading ${initFile}:`, error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { labels, deprecatedInfo };
|
||||
}
|
||||
|
||||
// Strategy: Requirements detection
|
||||
async function detectRequirements(allLabels) {
|
||||
const labels = new Set();
|
||||
@@ -489,26 +418,10 @@ jobs:
|
||||
}
|
||||
|
||||
// Generate review messages
|
||||
function generateReviewMessages(finalLabels, originalLabelCount, deprecatedInfo) {
|
||||
function generateReviewMessages(finalLabels, originalLabelCount) {
|
||||
const messages = [];
|
||||
const prAuthor = context.payload.pull_request.user.login;
|
||||
|
||||
// Deprecated component message
|
||||
if (finalLabels.includes('deprecated_component') && deprecatedInfo && deprecatedInfo.length > 0) {
|
||||
let message = `${DEPRECATED_COMPONENT_MARKER}\n### ⚠️ Deprecated Component\n\n`;
|
||||
message += `Hey there @${prAuthor},\n`;
|
||||
message += `This PR modifies one or more deprecated components. Please be aware:\n\n`;
|
||||
|
||||
for (const info of deprecatedInfo) {
|
||||
message += `#### Component: \`${info.component}\`\n`;
|
||||
message += `${info.message}\n\n`;
|
||||
}
|
||||
|
||||
message += `Consider migrating to the recommended alternative if applicable.`;
|
||||
|
||||
messages.push(message);
|
||||
}
|
||||
|
||||
// Too big message
|
||||
if (finalLabels.includes('too-big')) {
|
||||
const testAdditions = prFiles
|
||||
@@ -555,10 +468,10 @@ jobs:
|
||||
}
|
||||
|
||||
// Handle reviews
|
||||
async function handleReviews(finalLabels, originalLabelCount, deprecatedInfo) {
|
||||
const reviewMessages = generateReviewMessages(finalLabels, originalLabelCount, deprecatedInfo);
|
||||
async function handleReviews(finalLabels, originalLabelCount) {
|
||||
const reviewMessages = generateReviewMessages(finalLabels, originalLabelCount);
|
||||
const hasReviewableLabels = finalLabels.some(label =>
|
||||
['too-big', 'needs-codeowners', 'deprecated_component'].includes(label)
|
||||
['too-big', 'needs-codeowners'].includes(label)
|
||||
);
|
||||
|
||||
const { data: reviews } = await github.rest.pulls.listReviews({
|
||||
@@ -667,8 +580,7 @@ jobs:
|
||||
actionsLabels,
|
||||
codeOwnerLabels,
|
||||
testLabels,
|
||||
checkboxLabels,
|
||||
deprecatedResult
|
||||
checkboxLabels
|
||||
] = await Promise.all([
|
||||
detectMergeBranch(),
|
||||
detectComponentPlatforms(apiData),
|
||||
@@ -680,14 +592,9 @@ jobs:
|
||||
detectGitHubActionsChanges(),
|
||||
detectCodeOwner(),
|
||||
detectTests(),
|
||||
detectPRTemplateCheckboxes(),
|
||||
detectDeprecatedComponents()
|
||||
detectPRTemplateCheckboxes()
|
||||
]);
|
||||
|
||||
// Extract deprecated component info
|
||||
const deprecatedLabels = deprecatedResult.labels;
|
||||
const deprecatedInfo = deprecatedResult.deprecatedInfo;
|
||||
|
||||
// Combine all labels
|
||||
const allLabels = new Set([
|
||||
...branchLabels,
|
||||
@@ -700,8 +607,7 @@ jobs:
|
||||
...actionsLabels,
|
||||
...codeOwnerLabels,
|
||||
...testLabels,
|
||||
...checkboxLabels,
|
||||
...deprecatedLabels
|
||||
...checkboxLabels
|
||||
]);
|
||||
|
||||
// Detect requirements based on all other labels
|
||||
@@ -732,7 +638,7 @@ jobs:
|
||||
console.log('Computed labels:', finalLabels.join(', '));
|
||||
|
||||
// Handle reviews
|
||||
await handleReviews(finalLabels, originalLabelCount, deprecatedInfo);
|
||||
await handleReviews(finalLabels, originalLabelCount);
|
||||
|
||||
// Apply labels
|
||||
if (finalLabels.length > 0) {
|
||||
|
||||
@@ -155,6 +155,9 @@ void MHZ19Component::dump_config() {
|
||||
case MHZ19_DETECTION_RANGE_0_10000PPM:
|
||||
range_str = "0 to 10000ppm";
|
||||
break;
|
||||
default:
|
||||
range_str = "default";
|
||||
break;
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " Detection range: %s", range_str);
|
||||
}
|
||||
|
||||
@@ -119,7 +119,8 @@ bool MQTTAlarmControlPanelComponent::publish_state() {
|
||||
default:
|
||||
state_s = "unknown";
|
||||
}
|
||||
return this->publish(this->get_state_topic_(), state_s);
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), state_s);
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -52,8 +52,9 @@ bool MQTTBinarySensorComponent::publish_state(bool state) {
|
||||
if (this->binary_sensor_->is_status_binary_sensor())
|
||||
return true;
|
||||
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
const char *state_s = state ? "ON" : "OFF";
|
||||
return this->publish(this->get_state_topic_(), state_s);
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), state_s);
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -132,17 +132,29 @@ std::string MQTTComponent::get_command_topic_() const {
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish(const std::string &topic, const std::string &payload) {
|
||||
return this->publish(topic, payload.data(), payload.size());
|
||||
return this->publish(topic.c_str(), payload.data(), payload.size());
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish(const std::string &topic, const char *payload, size_t payload_length) {
|
||||
if (topic.empty())
|
||||
return this->publish(topic.c_str(), payload, payload_length);
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish(const char *topic, const char *payload, size_t payload_length) {
|
||||
if (topic[0] == '\0')
|
||||
return false;
|
||||
return global_mqtt_client->publish(topic, payload, payload_length, this->qos_, this->retain_);
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish(const char *topic, const char *payload) {
|
||||
return this->publish(topic, payload, strlen(payload));
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish_json(const std::string &topic, const json::json_build_t &f) {
|
||||
if (topic.empty())
|
||||
return this->publish_json(topic.c_str(), f);
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish_json(const char *topic, const json::json_build_t &f) {
|
||||
if (topic[0] == '\0')
|
||||
return false;
|
||||
return global_mqtt_client->publish_json(topic, f, this->qos_, this->retain_);
|
||||
}
|
||||
|
||||
@@ -157,6 +157,38 @@ class MQTTComponent : public Component {
|
||||
*/
|
||||
bool publish(const std::string &topic, const char *payload, size_t payload_length);
|
||||
|
||||
/** Send a MQTT message (no heap allocation for topic).
|
||||
*
|
||||
* @param topic The topic as C string.
|
||||
* @param payload The payload buffer.
|
||||
* @param payload_length The length of the payload.
|
||||
*/
|
||||
bool publish(const char *topic, const char *payload, size_t payload_length);
|
||||
|
||||
/** Send a MQTT message (no heap allocation for topic).
|
||||
*
|
||||
* @param topic The topic as StringRef (for use with get_state_topic_to_()).
|
||||
* @param payload The payload buffer.
|
||||
* @param payload_length The length of the payload.
|
||||
*/
|
||||
bool publish(StringRef topic, const char *payload, size_t payload_length) {
|
||||
return this->publish(topic.c_str(), payload, payload_length);
|
||||
}
|
||||
|
||||
/** Send a MQTT message (no heap allocation for topic).
|
||||
*
|
||||
* @param topic The topic as C string.
|
||||
* @param payload The null-terminated payload.
|
||||
*/
|
||||
bool publish(const char *topic, const char *payload);
|
||||
|
||||
/** Send a MQTT message (no heap allocation for topic).
|
||||
*
|
||||
* @param topic The topic as StringRef (for use with get_state_topic_to_()).
|
||||
* @param payload The null-terminated payload.
|
||||
*/
|
||||
bool publish(StringRef topic, const char *payload) { return this->publish(topic.c_str(), payload); }
|
||||
|
||||
/** Construct and send a JSON MQTT message.
|
||||
*
|
||||
* @param topic The topic.
|
||||
@@ -164,6 +196,20 @@ class MQTTComponent : public Component {
|
||||
*/
|
||||
bool publish_json(const std::string &topic, const json::json_build_t &f);
|
||||
|
||||
/** Construct and send a JSON MQTT message (no heap allocation for topic).
|
||||
*
|
||||
* @param topic The topic as C string.
|
||||
* @param f The Json Message builder.
|
||||
*/
|
||||
bool publish_json(const char *topic, const json::json_build_t &f);
|
||||
|
||||
/** Construct and send a JSON MQTT message (no heap allocation for topic).
|
||||
*
|
||||
* @param topic The topic as StringRef (for use with get_state_topic_to_()).
|
||||
* @param f The Json Message builder.
|
||||
*/
|
||||
bool publish_json(StringRef topic, const json::json_build_t &f) { return this->publish_json(topic.c_str(), f); }
|
||||
|
||||
/** Subscribe to a MQTT topic.
|
||||
*
|
||||
* @param topic The topic. Wildcards are currently not supported.
|
||||
|
||||
@@ -115,7 +115,8 @@ bool MQTTCoverComponent::publish_state() {
|
||||
: this->cover_->position == COVER_OPEN ? "open"
|
||||
: traits.get_supports_position() ? "open"
|
||||
: "unknown";
|
||||
if (!this->publish(this->get_state_topic_(), state_s))
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
if (!this->publish(this->get_state_topic_to_(topic_buf), state_s))
|
||||
success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,8 @@ bool MQTTDateComponent::send_initial_state() {
|
||||
}
|
||||
}
|
||||
bool MQTTDateComponent::publish_state(uint16_t year, uint8_t month, uint8_t day) {
|
||||
return this->publish_json(this->get_state_topic_(), [year, month, day](JsonObject root) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish_json(this->get_state_topic_to_(topic_buf), [year, month, day](JsonObject root) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
root[ESPHOME_F("year")] = year;
|
||||
root[ESPHOME_F("month")] = month;
|
||||
|
||||
@@ -66,15 +66,17 @@ bool MQTTDateTimeComponent::send_initial_state() {
|
||||
}
|
||||
bool MQTTDateTimeComponent::publish_state(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute,
|
||||
uint8_t second) {
|
||||
return this->publish_json(this->get_state_topic_(), [year, month, day, hour, minute, second](JsonObject root) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
root[ESPHOME_F("year")] = year;
|
||||
root[ESPHOME_F("month")] = month;
|
||||
root[ESPHOME_F("day")] = day;
|
||||
root[ESPHOME_F("hour")] = hour;
|
||||
root[ESPHOME_F("minute")] = minute;
|
||||
root[ESPHOME_F("second")] = second;
|
||||
});
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish_json(this->get_state_topic_to_(topic_buf),
|
||||
[year, month, day, hour, minute, second](JsonObject root) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
root[ESPHOME_F("year")] = year;
|
||||
root[ESPHOME_F("month")] = month;
|
||||
root[ESPHOME_F("day")] = day;
|
||||
root[ESPHOME_F("hour")] = hour;
|
||||
root[ESPHOME_F("minute")] = minute;
|
||||
root[ESPHOME_F("second")] = second;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -44,7 +44,8 @@ void MQTTEventComponent::dump_config() {
|
||||
}
|
||||
|
||||
bool MQTTEventComponent::publish_event_(const std::string &event_type) {
|
||||
return this->publish_json(this->get_state_topic_(), [event_type](JsonObject root) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish_json(this->get_state_topic_to_(topic_buf), [event_type](JsonObject root) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
root[MQTT_EVENT_TYPE] = event_type;
|
||||
});
|
||||
|
||||
@@ -158,9 +158,10 @@ void MQTTFanComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig
|
||||
}
|
||||
}
|
||||
bool MQTTFanComponent::publish_state() {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
const char *state_s = this->state_->state ? "ON" : "OFF";
|
||||
ESP_LOGD(TAG, "'%s' Sending state %s.", this->state_->get_name().c_str(), state_s);
|
||||
this->publish(this->get_state_topic_(), state_s);
|
||||
this->publish(this->get_state_topic_to_(topic_buf), state_s);
|
||||
bool failed = false;
|
||||
if (this->state_->get_traits().supports_direction()) {
|
||||
bool success = this->publish(this->get_direction_state_topic(),
|
||||
|
||||
@@ -34,7 +34,8 @@ void MQTTJSONLightComponent::on_light_remote_values_update() {
|
||||
MQTTJSONLightComponent::MQTTJSONLightComponent(LightState *state) : state_(state) {}
|
||||
|
||||
bool MQTTJSONLightComponent::publish_state_() {
|
||||
return this->publish_json(this->get_state_topic_(), [this](JsonObject root) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish_json(this->get_state_topic_to_(topic_buf), [this](JsonObject root) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
LightJSONSchema::dump_json(*this->state_, root);
|
||||
});
|
||||
|
||||
@@ -47,13 +47,14 @@ void MQTTLockComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfi
|
||||
bool MQTTLockComponent::send_initial_state() { return this->publish_state(); }
|
||||
|
||||
bool MQTTLockComponent::publish_state() {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
#ifdef USE_STORE_LOG_STR_IN_FLASH
|
||||
char buf[LOCK_STATE_STR_SIZE];
|
||||
strncpy_P(buf, (PGM_P) lock_state_to_string(this->lock_->state), sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
return this->publish(this->get_state_topic_(), buf);
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), buf);
|
||||
#else
|
||||
return this->publish(this->get_state_topic_(), LOG_STR_ARG(lock_state_to_string(this->lock_->state)));
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), LOG_STR_ARG(lock_state_to_string(this->lock_->state)));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -74,9 +74,10 @@ bool MQTTNumberComponent::send_initial_state() {
|
||||
}
|
||||
}
|
||||
bool MQTTNumberComponent::publish_state(float value) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
char buffer[64];
|
||||
buf_append_printf(buffer, sizeof(buffer), 0, "%f", value);
|
||||
return this->publish(this->get_state_topic_(), buffer);
|
||||
size_t len = buf_append_printf(buffer, sizeof(buffer), 0, "%f", value);
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), buffer, len);
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -50,7 +50,8 @@ bool MQTTSelectComponent::send_initial_state() {
|
||||
}
|
||||
}
|
||||
bool MQTTSelectComponent::publish_state(const std::string &value) {
|
||||
return this->publish(this->get_state_topic_(), value);
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), value.data(), value.size());
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -79,12 +79,13 @@ bool MQTTSensorComponent::send_initial_state() {
|
||||
}
|
||||
}
|
||||
bool MQTTSensorComponent::publish_state(float value) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
if (mqtt::global_mqtt_client->is_publish_nan_as_none() && std::isnan(value))
|
||||
return this->publish(this->get_state_topic_(), "None", 4);
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), "None", 4);
|
||||
int8_t accuracy = this->sensor_->get_accuracy_decimals();
|
||||
char buf[VALUE_ACCURACY_MAX_LEN];
|
||||
size_t len = value_accuracy_to_buf(buf, value, accuracy);
|
||||
return this->publish(this->get_state_topic_(), buf, len);
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), buf, len);
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -52,8 +52,9 @@ void MQTTSwitchComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCon
|
||||
bool MQTTSwitchComponent::send_initial_state() { return this->publish_state(this->switch_->state); }
|
||||
|
||||
bool MQTTSwitchComponent::publish_state(bool state) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
const char *state_s = state ? "ON" : "OFF";
|
||||
return this->publish(this->get_state_topic_(), state_s);
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), state_s);
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -53,7 +53,8 @@ bool MQTTTextComponent::send_initial_state() {
|
||||
}
|
||||
}
|
||||
bool MQTTTextComponent::publish_state(const std::string &value) {
|
||||
return this->publish(this->get_state_topic_(), value);
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), value.data(), value.size());
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -31,7 +31,10 @@ void MQTTTextSensor::dump_config() {
|
||||
LOG_MQTT_COMPONENT(true, false);
|
||||
}
|
||||
|
||||
bool MQTTTextSensor::publish_state(const std::string &value) { return this->publish(this->get_state_topic_(), value); }
|
||||
bool MQTTTextSensor::publish_state(const std::string &value) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish(this->get_state_topic_to_(topic_buf), value.data(), value.size());
|
||||
}
|
||||
bool MQTTTextSensor::send_initial_state() {
|
||||
if (this->sensor_->has_state()) {
|
||||
return this->publish_state(this->sensor_->state);
|
||||
|
||||
@@ -53,7 +53,8 @@ bool MQTTTimeComponent::send_initial_state() {
|
||||
}
|
||||
}
|
||||
bool MQTTTimeComponent::publish_state(uint8_t hour, uint8_t minute, uint8_t second) {
|
||||
return this->publish_json(this->get_state_topic_(), [hour, minute, second](JsonObject root) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish_json(this->get_state_topic_to_(topic_buf), [hour, minute, second](JsonObject root) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
root[ESPHOME_F("hour")] = hour;
|
||||
root[ESPHOME_F("minute")] = minute;
|
||||
|
||||
@@ -28,7 +28,8 @@ void MQTTUpdateComponent::setup() {
|
||||
}
|
||||
|
||||
bool MQTTUpdateComponent::publish_state() {
|
||||
return this->publish_json(this->get_state_topic_(), [this](JsonObject root) {
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
return this->publish_json(this->get_state_topic_to_(topic_buf), [this](JsonObject root) {
|
||||
root[ESPHOME_F("installed_version")] = this->update_->update_info.current_version;
|
||||
root[ESPHOME_F("latest_version")] = this->update_->update_info.latest_version;
|
||||
root[ESPHOME_F("title")] = this->update_->update_info.title;
|
||||
|
||||
@@ -84,7 +84,8 @@ bool MQTTValveComponent::publish_state() {
|
||||
: this->valve_->position == VALVE_OPEN ? "open"
|
||||
: traits.get_supports_position() ? "open"
|
||||
: "unknown";
|
||||
if (!this->publish(this->get_state_topic_(), state_s))
|
||||
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
|
||||
if (!this->publish(this->get_state_topic_to_(topic_buf), state_s))
|
||||
success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# Test Deprecated Component
|
||||
|
||||
This is a test component to validate the `deprecated_component` label functionality in the auto-label workflow.
|
||||
|
||||
## Purpose
|
||||
|
||||
This component demonstrates how the `DEPRECATED_COMPONENT` constant should be used:
|
||||
|
||||
1. The component is still functional and usable
|
||||
2. It's deprecated and not actively maintained
|
||||
3. Users should migrate to an alternative when possible
|
||||
|
||||
## Usage
|
||||
|
||||
This is different from components that use `cv.invalid()`, which are completely unusable.
|
||||
|
||||
Components with `DEPRECATED_COMPONENT` are still functional but discouraged for new projects.
|
||||
@@ -1,6 +0,0 @@
|
||||
"""Test deprecated component for validation."""
|
||||
|
||||
CODEOWNERS = ["@test"]
|
||||
DEPRECATED_COMPONENT = "This component is deprecated and will be removed in a future release. Please use the newer_component instead."
|
||||
|
||||
# Component is still functional but deprecated
|
||||
@@ -1,5 +0,0 @@
|
||||
"""Test sensor platform for deprecated component."""
|
||||
import esphome.config_validation as cv
|
||||
|
||||
# This is a simple placeholder - component still works
|
||||
CONFIG_SCHEMA = cv.Schema({})
|
||||
@@ -1,2 +1 @@
|
||||
CODEOWNERS = ["@clydebarrow"]
|
||||
DEPRECATED_COMPONENT = "The waveshare_epaper component is deprecated and no new models will be added. For new epaper displays use the epaper_spi component"
|
||||
|
||||
Reference in New Issue
Block a user