Rearranging directories to make them work with github URLs

This commit is contained in:
John Dillenburg
2025-03-01 14:24:56 -06:00
parent 177179d8a4
commit 398094cbed
7 changed files with 1 additions and 1 deletions

21
components/tfmini/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Your Name
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,58 @@
# TFMini-S Time of Flight Distance Sensor for ESPHome
This is an external component for ESPHome that supports the TFMini-S time of flight distance sensor.
## Installation
You can install this component in two ways:
### 1. Using ESPHome external components
```yaml
external_components:
- source: github://your-username/esphome-tfmini@main
components: [ tfmini ]
```
### 2. Manual installation
Clone this repository into your ESPHome `custom_components` directory:
```bash
cd <your config directory>/custom_components
git clone https://github.com/your-username/esphome-tfmini.git
```
## Configuration
Add the following to your ESPHome configuration file:
```yaml
# Example configuration
uart:
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 115200
sensor:
- platform: tfmini
name: "Distance Sensor"
update_interval: 1s
```
## Features
- Measures distance in meters
- Automatic configuration of the TFMini-S sensor
- Signal strength validation
- Temperature monitoring (internal, not exposed yet)
## Notes
- The sensor is configured to use the standard 9-byte output format
- Refresh rate is set to 100Hz
- Data is provided in meters with 2 decimal precision
## License
This component is licensed under the MIT License.

View File

@@ -0,0 +1,17 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import CONF_ID
DEPENDENCIES = ['uart']
AUTO_LOAD = ['sensor']
tfmini_ns = cg.esphome_ns.namespace('tfmini')
TFMiniComponent = tfmini_ns.class_('TFMiniComponent', cg.Component)
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(TFMiniComponent)
}).extend(cv.COMPONENT_SCHEMA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)

View File

@@ -0,0 +1,76 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, uart
from esphome.const import (
CONF_ID,
DEVICE_CLASS_DISTANCE,
DEVICE_CLASS_SIGNAL_STRENGTH,
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
UNIT_METER,
UNIT_CENTIMETER,
UNIT_CELSIUS,
ICON_RULER,
ENTITY_CATEGORY_DIAGNOSTIC,
)
DEPENDENCIES = ['uart']
tfmini_ns = cg.esphome_ns.namespace('tfmini')
TFMiniSensor = tfmini_ns.class_('TFMiniSensor', sensor.Sensor, cg.Component,
uart.UARTDevice)
CONF_STRENGTH = "strength"
CONF_TEMPERATURE = "temperature"
CONF_DISTANCE_UNIT = "distance_unit"
CONFIG_SCHEMA = (
sensor.sensor_schema(
TFMiniSensor,
unit_of_measurement=UNIT_CENTIMETER, # Default to cm instead of meters
accuracy_decimals=0, # Integer precision for cm
device_class=DEVICE_CLASS_DISTANCE,
state_class=STATE_CLASS_MEASUREMENT,
icon=ICON_RULER,
)
.extend({
cv.Optional(CONF_DISTANCE_UNIT, default="cm"): cv.enum({
"cm": "CENTIMETERS",
"m": "METERS",
}),
cv.Optional(CONF_STRENGTH): sensor.sensor_schema(
unit_of_measurement="",
accuracy_decimals=0,
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
state_class=STATE_CLASS_MEASUREMENT,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
accuracy_decimals=1,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
})
.extend(uart.UART_DEVICE_SCHEMA)
)
async def to_code(config):
var = await sensor.new_sensor(config)
await cg.register_component(var, config)
await uart.register_uart_device(var, config)
cg.add(var.set_distance_unit(config[CONF_DISTANCE_UNIT]))
if config[CONF_DISTANCE_UNIT] == "m":
cg.add(var.set_unit_of_measurement(UNIT_METER))
cg.add(var.set_accuracy_decimals(2))
if CONF_STRENGTH in config:
sens = await sensor.new_sensor(config[CONF_STRENGTH])
cg.add(var.set_strength_sensor(sens))
if CONF_TEMPERATURE in config:
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
cg.add(var.set_temperature_sensor(sens))

View File

@@ -0,0 +1,112 @@
#include "tfmini.h"
#include <esphome/core/log.h>
namespace esphome {
namespace tfmini {
static const char *const TAG = "tfmini";
static const uint8_t HEADER = 0x59; // frame header of data package
void TFMiniSensor::setup() {
this->set_timeout(50, [this]() { this->setup_internal_(); });
}
void TFMiniSensor::setup_internal_() {
// Configure standard 9-byte output format (cm)
const uint8_t standard_mode[5] = {0x5A, 0x05, 0x05, 0x01, 0x65};
this->write_array(standard_mode, 5);
delay(100);
// Set refresh rate to 100Hz (1000/0x0A = 100)
const uint8_t rate100[6] = {0x5A, 0x06, 0x03, 0x0A, 0x00, 0x6D};
this->write_array(rate100, 6);
delay(100);
// Save the settings
const uint8_t save_setting[4] = {0x5A, 0x04, 0x11, 0x6F};
this->write_array(save_setting, 4);
// Wait for the sensor to come back online
delay(1000);
this->flush();
ESP_LOGD(TAG, "TFMini setup completed");
}
void TFMiniSensor::loop() {
while (this->available() >= 9) {
if (this->read() != HEADER) {
continue;
}
if (this->read() != HEADER) {
continue;
}
uint8_t data[7];
if (!this->read_array(data, 7)) {
continue;
}
// Verify checksum
uint8_t checksum = HEADER + HEADER;
for (size_t i = 0; i < 6; i++) {
checksum += data[i];
}
if (checksum != data[6]) {
ESP_LOGW(TAG, "TFMini checksum error");
continue;
}
// Extract distance data (first two bytes)
uint16_t distance_cm = data[0] | (data[1] << 8);
// Extract signal strength (next two bytes)
uint16_t strength = data[2] | (data[3] << 8);
// Extract temperature (next two bytes)
float temperature = (data[4] | (data[5] << 8)) / 8.0f - 256.0f;
// Only publish valid readings
if (strength < 100) {
ESP_LOGW(TAG, "TFMini signal strength too low: %u", strength);
continue;
}
// Convert to requested unit
float distance_value;
if (this->distance_unit_ == METERS) {
distance_value = distance_cm / 100.0f;
ESP_LOGD(TAG, "Distance: %.2f m, Strength: %u, Temperature: %.1f °C",
distance_value, strength, temperature);
} else {
distance_value = distance_cm;
ESP_LOGD(TAG, "Distance: %d cm, Strength: %u, Temperature: %.1f °C",
distance_cm, strength, temperature);
}
// Publish all values
this->publish_state(distance_value);
if (this->strength_sensor_ != nullptr) {
this->strength_sensor_->publish_state(strength);
}
if (this->temperature_sensor_ != nullptr) {
this->temperature_sensor_->publish_state(temperature);
}
return;
}
}
void TFMiniSensor::dump_config() {
ESP_LOGCONFIG(TAG, "TFMini:");
LOG_SENSOR(" ", "Distance", this);
ESP_LOGCONFIG(TAG, " Distance Unit: %s", this->distance_unit_ == METERS ? "meters" : "centimeters");
LOG_SENSOR(" ", "Signal Strength", this->strength_sensor_);
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
this->check_uart_settings(115200);
}
} // namespace tfmini
} // namespace esphome

View File

@@ -0,0 +1,41 @@
#pragma once
#include <esphome/core/component.h>
#include <esphome/components/sensor/sensor.h>
#include <esphome/components/uart/uart.h>
namespace esphome {
namespace tfmini {
enum DistanceUnit {
CENTIMETERS,
METERS
};
class TFMiniSensor : public sensor::Sensor, public Component, public uart::UARTDevice {
public:
void setup() override;
void loop() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::AFTER_CONNECTION; }
void set_strength_sensor(sensor::Sensor *strength_sensor) { strength_sensor_ = strength_sensor; }
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; }
void set_distance_unit(const std::string &distance_unit) {
if (distance_unit == "METERS") {
this->distance_unit_ = METERS;
} else {
this->distance_unit_ = CENTIMETERS;
}
}
protected:
void setup_internal_();
sensor::Sensor *strength_sensor_{nullptr};
sensor::Sensor *temperature_sensor_{nullptr};
DistanceUnit distance_unit_{CENTIMETERS};
};
} // namespace tfmini
} // namespace esphome