1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-17 07:57:13 +02:00

Add WTS01 temperature sensor component (#8539)

Co-authored-by: Antoine Lépée <alepee@MacBook-Pro-de-Antoine.local>
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
Antoine Lépée 2025-09-25 15:38:31 +02:00 committed by GitHub
parent 44767c32cf
commit f7ed127182
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 197 additions and 0 deletions

View File

@ -533,6 +533,7 @@ esphome/components/wk2204_spi/* @DrCoolZic
esphome/components/wk2212_i2c/* @DrCoolZic
esphome/components/wk2212_spi/* @DrCoolZic
esphome/components/wl_134/* @hobbypunk90
esphome/components/wts01/* @alepee
esphome/components/x9c/* @EtienneMD
esphome/components/xgzp68xx/* @gcormier
esphome/components/xiaomi_hhccjcy10/* @fariouche

View File

View File

@ -0,0 +1,41 @@
import esphome.codegen as cg
from esphome.components import sensor, uart
import esphome.config_validation as cv
from esphome.const import (
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
)
CONF_WTS01_ID = "wts01_id"
CODEOWNERS = ["@alepee"]
DEPENDENCIES = ["uart"]
wts01_ns = cg.esphome_ns.namespace("wts01")
WTS01Sensor = wts01_ns.class_(
"WTS01Sensor", cg.Component, uart.UARTDevice, sensor.Sensor
)
CONFIG_SCHEMA = (
sensor.sensor_schema(
WTS01Sensor,
unit_of_measurement=UNIT_CELSIUS,
accuracy_decimals=1,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
)
.extend(cv.COMPONENT_SCHEMA)
.extend(uart.UART_DEVICE_SCHEMA)
)
FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
"wts01",
baud_rate=9600,
require_rx=True,
)
async def to_code(config):
var = await sensor.new_sensor(config)
await cg.register_component(var, config)
await uart.register_uart_device(var, config)

View File

@ -0,0 +1,91 @@
#include "wts01.h"
#include "esphome/core/log.h"
#include <cmath>
namespace esphome {
namespace wts01 {
constexpr uint8_t HEADER_1 = 0x55;
constexpr uint8_t HEADER_2 = 0x01;
constexpr uint8_t HEADER_3 = 0x01;
constexpr uint8_t HEADER_4 = 0x04;
static const char *const TAG = "wts01";
void WTS01Sensor::loop() {
// Process all available data at once
while (this->available()) {
uint8_t c;
if (this->read_byte(&c)) {
this->handle_char_(c);
}
}
}
void WTS01Sensor::dump_config() { LOG_SENSOR("", "WTS01 Sensor", this); }
void WTS01Sensor::handle_char_(uint8_t c) {
// State machine for processing the header. Reset if something doesn't match.
if (this->buffer_pos_ == 0 && c != HEADER_1) {
return;
}
if (this->buffer_pos_ == 1 && c != HEADER_2) {
this->buffer_pos_ = 0;
return;
}
if (this->buffer_pos_ == 2 && c != HEADER_3) {
this->buffer_pos_ = 0;
return;
}
if (this->buffer_pos_ == 3 && c != HEADER_4) {
this->buffer_pos_ = 0;
return;
}
// Add byte to buffer
this->buffer_[this->buffer_pos_++] = c;
// Process complete packet
if (this->buffer_pos_ >= PACKET_SIZE) {
this->process_packet_();
this->buffer_pos_ = 0;
}
}
void WTS01Sensor::process_packet_() {
// Based on Tasmota implementation
// Format: 55 01 01 04 01 11 16 12 95
// header T Td Ck - T = Temperature, Td = Temperature decimal, Ck = Checksum
uint8_t calculated_checksum = 0;
for (uint8_t i = 0; i < PACKET_SIZE - 1; i++) {
calculated_checksum += this->buffer_[i];
}
uint8_t received_checksum = this->buffer_[PACKET_SIZE - 1];
if (calculated_checksum != received_checksum) {
ESP_LOGW(TAG, "WTS01 Checksum doesn't match: 0x%02X != 0x%02X", received_checksum, calculated_checksum);
return;
}
// Extract temperature value
int8_t temp = this->buffer_[6];
int32_t sign = 1;
// Handle negative temperatures
if (temp < 0) {
sign = -1;
}
// Calculate temperature (temp + decimal/100)
float temperature = static_cast<float>(temp) + (sign * static_cast<float>(this->buffer_[7]) / 100.0f);
ESP_LOGV(TAG, "Received new temperature: %.2f°C", temperature);
this->publish_state(temperature);
}
} // namespace wts01
} // namespace esphome

View File

@ -0,0 +1,27 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
namespace esphome {
namespace wts01 {
constexpr uint8_t PACKET_SIZE = 9;
class WTS01Sensor : public sensor::Sensor, public uart::UARTDevice, public Component {
public:
void loop() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::DATA; }
protected:
uint8_t buffer_[PACKET_SIZE];
uint8_t buffer_pos_{0};
void handle_char_(uint8_t c);
void process_packet_();
};
} // namespace wts01
} // namespace esphome

View File

@ -0,0 +1,7 @@
uart:
rx_pin: ${rx_pin}
baud_rate: 9600
sensor:
- platform: wts01
id: wts01_sensor

View File

@ -0,0 +1,5 @@
substitutions:
tx_pin: GPIO16
rx_pin: GPIO17
<<: !include common.yaml

View File

@ -0,0 +1,5 @@
substitutions:
tx_pin: GPIO6
rx_pin: GPIO7
<<: !include common.yaml

View File

@ -0,0 +1,5 @@
substitutions:
tx_pin: GPIO6
rx_pin: GPIO7
<<: !include common.yaml

View File

@ -0,0 +1,5 @@
substitutions:
tx_pin: GPIO16
rx_pin: GPIO17
<<: !include common.yaml

View File

@ -0,0 +1,5 @@
substitutions:
tx_pin: GPIO1
rx_pin: GPIO3
<<: !include common.yaml

View File

@ -0,0 +1,5 @@
substitutions:
tx_pin: GPIO0
rx_pin: GPIO1
<<: !include common.yaml