Add support for a01nyub (#4863)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
André Cirne 2023-08-07 01:22:18 +01:00 committed by GitHub
parent 62fed4c1eb
commit 1495fada90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 142 additions and 3 deletions

View file

@ -11,6 +11,7 @@ esphome/*.py @esphome/core
esphome/core/* @esphome/core esphome/core/* @esphome/core
# Integrations # Integrations
esphome/components/a01nyub/* @MrSuicideParrot
esphome/components/absolute_humidity/* @DAVe3283 esphome/components/absolute_humidity/* @DAVe3283
esphome/components/ac_dimmer/* @glmnet esphome/components/ac_dimmer/* @glmnet
esphome/components/adc/* @esphome/core esphome/components/adc/* @esphome/core

View file

@ -0,0 +1 @@
CODEOWNERS = ["@MrSuicideParrot"]

View file

@ -0,0 +1,57 @@
// Datasheet https://wiki.dfrobot.com/A01NYUB%20Waterproof%20Ultrasonic%20Sensor%20SKU:%20SEN0313
#include "a01nyub.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace a01nyub {
static const char *const TAG = "a01nyub.sensor";
static const uint8_t MAX_DATA_LENGTH_BYTES = 4;
void A01nyubComponent::loop() {
uint8_t data;
while (this->available() > 0) {
if (this->read_byte(&data)) {
buffer_.push_back(data);
this->check_buffer_();
}
}
}
void A01nyubComponent::check_buffer_() {
if (this->buffer_.size() >= MAX_DATA_LENGTH_BYTES) {
size_t i;
for (i = 0; i < this->buffer_.size(); i++) {
// Look for the first packet
if (this->buffer_[i] == 0xFF) {
if (i + 1 + 3 < this->buffer_.size()) { // Packet is not complete
return; // Wait for completion
}
uint8_t checksum = (this->buffer_[i] + this->buffer_[i + 1] + this->buffer_[i + 2]) & 0xFF;
if (this->buffer_[i + 3] == checksum) {
float distance = (this->buffer_[i + 1] << 8) + this->buffer_[i + 2];
if (distance > 280) {
float meters = distance / 1000.0;
ESP_LOGV(TAG, "Distance from sensor: %f mm, %f m", distance, meters);
this->publish_state(meters);
} else {
ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str());
}
}
break;
}
}
this->buffer_.clear();
}
}
void A01nyubComponent::dump_config() {
ESP_LOGCONFIG(TAG, "A01nyub Sensor:");
LOG_SENSOR(" ", "Distance", this);
}
} // namespace a01nyub
} // namespace esphome

View file

@ -0,0 +1,27 @@
#pragma once
#include <vector>
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
namespace esphome {
namespace a01nyub {
class A01nyubComponent : public sensor::Sensor, public Component, public uart::UARTDevice {
public:
// Nothing really public.
// ========== INTERNAL METHODS ==========
void loop() override;
void dump_config() override;
protected:
void check_buffer_();
std::vector<uint8_t> buffer_;
};
} // namespace a01nyub
} // namespace esphome

View file

@ -0,0 +1,41 @@
import esphome.codegen as cg
from esphome.components import sensor, uart
from esphome.const import (
STATE_CLASS_MEASUREMENT,
UNIT_METER,
ICON_ARROW_EXPAND_VERTICAL,
DEVICE_CLASS_DISTANCE,
)
CODEOWNERS = ["@MrSuicideParrot"]
DEPENDENCIES = ["uart"]
a01nyub_ns = cg.esphome_ns.namespace("a01nyub")
A01nyubComponent = a01nyub_ns.class_(
"A01nyubComponent", sensor.Sensor, cg.Component, uart.UARTDevice
)
CONFIG_SCHEMA = sensor.sensor_schema(
A01nyubComponent,
unit_of_measurement=UNIT_METER,
icon=ICON_ARROW_EXPAND_VERTICAL,
accuracy_decimals=3,
state_class=STATE_CLASS_MEASUREMENT,
device_class=DEVICE_CLASS_DISTANCE,
).extend(uart.UART_DEVICE_SCHEMA)
FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
"a01nyub",
baud_rate=9600,
require_tx=False,
require_rx=True,
data_bits=8,
parity=None,
stop_bits=1,
)
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

@ -34,9 +34,14 @@ spi:
miso_pin: GPIO23 miso_pin: GPIO23
uart: uart:
tx_pin: GPIO22 - id: uart115200
rx_pin: GPIO23 tx_pin: GPIO22
baud_rate: 115200 rx_pin: GPIO23
baud_rate: 115200
- id: uart9600
tx_pin: GPIO22
rx_pin: GPIO23
baud_rate: 9600
ota: ota:
safe_mode: true safe_mode: true
@ -58,6 +63,7 @@ time:
tuya: tuya:
time_id: sntp_time time_id: sntp_time
uart_id: uart115200
status_pin: status_pin:
number: 14 number: 14
inverted: true inverted: true
@ -73,6 +79,7 @@ select:
pipsolar: pipsolar:
id: inverter0 id: inverter0
uart_id: uart115200
sx1509: sx1509:
- id: sx1509_hub - id: sx1509_hub
@ -229,6 +236,7 @@ sensor:
name: inverter0_pv_charging_power name: inverter0_pv_charging_power
- platform: hrxl_maxsonar_wr - platform: hrxl_maxsonar_wr
name: Rainwater Tank Level name: Rainwater Tank Level
uart_id: uart115200
filters: filters:
- sliding_window_moving_average: - sliding_window_moving_average:
window_size: 12 window_size: 12
@ -257,6 +265,10 @@ sensor:
name: Ufire Temperature name: Ufire Temperature
ph: ph:
name: Ufire pH name: Ufire pH
- platform: a01nyub
id: a01nyub_sensor
name: "a01nyub Distance"
uart_id: uart9600
# #
# platform sensor.apds9960 requires component apds9960 # platform sensor.apds9960 requires component apds9960