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:
parent
44767c32cf
commit
f7ed127182
@ -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
|
||||
|
0
esphome/components/wts01/__init__.py
Normal file
0
esphome/components/wts01/__init__.py
Normal file
41
esphome/components/wts01/sensor.py
Normal file
41
esphome/components/wts01/sensor.py
Normal 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)
|
91
esphome/components/wts01/wts01.cpp
Normal file
91
esphome/components/wts01/wts01.cpp
Normal 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
|
27
esphome/components/wts01/wts01.h
Normal file
27
esphome/components/wts01/wts01.h
Normal 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
|
7
tests/components/wts01/common.yaml
Normal file
7
tests/components/wts01/common.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
uart:
|
||||
rx_pin: ${rx_pin}
|
||||
baud_rate: 9600
|
||||
|
||||
sensor:
|
||||
- platform: wts01
|
||||
id: wts01_sensor
|
5
tests/components/wts01/test.esp32-ard.yaml
Normal file
5
tests/components/wts01/test.esp32-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
tx_pin: GPIO16
|
||||
rx_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/wts01/test.esp32-c3-ard.yaml
Normal file
5
tests/components/wts01/test.esp32-c3-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
tx_pin: GPIO6
|
||||
rx_pin: GPIO7
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/wts01/test.esp32-c3-idf.yaml
Normal file
5
tests/components/wts01/test.esp32-c3-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
tx_pin: GPIO6
|
||||
rx_pin: GPIO7
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/wts01/test.esp32-idf.yaml
Normal file
5
tests/components/wts01/test.esp32-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
tx_pin: GPIO16
|
||||
rx_pin: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/wts01/test.esp8266-ard.yaml
Normal file
5
tests/components/wts01/test.esp8266-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
|
||||
<<: !include common.yaml
|
5
tests/components/wts01/test.rp2040-ard.yaml
Normal file
5
tests/components/wts01/test.rp2040-ard.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
substitutions:
|
||||
tx_pin: GPIO0
|
||||
rx_pin: GPIO1
|
||||
|
||||
<<: !include common.yaml
|
Loading…
x
Reference in New Issue
Block a user