[husb238] Add HUSB238 USB PD controller hub with binary sensors (#16572)

Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
Anton Viktorov
2026-10-12 11:31:16 -10:00
committed by GitHub
co-authored by J. Nick Koston
parent 1c8808339a
commit 2cd7c0eb36
8 changed files with 168 additions and 0 deletions
+1
View File
@@ -266,6 +266,7 @@ esphome/components/http_request/ota/* @oarcher
esphome/components/http_request/update/* @jesserockz
esphome/components/htu31d/* @betterengineering
esphome/components/hub75/* @stuartparmenter
esphome/components/husb238/* @latonita
esphome/components/hydreon_rgxx/* @functionpointer
esphome/components/hyt271/* @Philippe12
esphome/components/i2c/* @esphome/core
+33
View File
@@ -0,0 +1,33 @@
import esphome.codegen as cg
from esphome.components import i2c
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.types import ConfigType
CODEOWNERS = ["@latonita"]
DEPENDENCIES = ["i2c"]
DOMAIN = "husb238"
MULTI_CONF = True
CONF_HUSB238_ID = "husb238_id"
husb238_ns = cg.esphome_ns.namespace("husb238")
Husb238Component = husb238_ns.class_(
"Husb238Component", cg.PollingComponent, i2c.I2CDevice
)
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(Husb238Component),
}
)
.extend(cv.polling_component_schema("1s"))
.extend(i2c.i2c_device_schema(0x08))
)
async def to_code(config: ConfigType) -> None:
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
@@ -0,0 +1,38 @@
import esphome.codegen as cg
from esphome.components import binary_sensor
import esphome.config_validation as cv
from esphome.const import CONF_NAME, DEVICE_CLASS_PLUG, ENTITY_CATEGORY_DIAGNOSTIC
from esphome.types import ConfigType
from . import CONF_HUSB238_ID, Husb238Component
DEPENDENCIES = ["husb238"]
CONF_ATTACHED = "attached"
CONF_CC_DIRECTION = "cc_direction"
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_HUSB238_ID): cv.use_id(Husb238Component),
cv.Optional(CONF_ATTACHED): cv.maybe_simple_value(
binary_sensor.binary_sensor_schema(
device_class=DEVICE_CLASS_PLUG,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
key=CONF_NAME,
),
cv.Optional(CONF_CC_DIRECTION): cv.maybe_simple_value(
binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC
),
key=CONF_NAME,
),
}
)
async def to_code(config: ConfigType) -> None:
hub = await cg.get_variable(config[CONF_HUSB238_ID])
sensors = binary_sensor.sub_binary_sensors(config)
await sensors(CONF_ATTACHED, hub.set_attached_binary_sensor)
await sensors(CONF_CC_DIRECTION, hub.set_cc_direction_binary_sensor)
+51
View File
@@ -0,0 +1,51 @@
#include "husb238.h"
#include "esphome/core/log.h"
namespace esphome::husb238 {
ESPHOME_LOG_TAG(TAG, "husb238");
void Husb238Component::setup() {
uint8_t status;
if (!this->read_byte(REG_PD_STATUS1, &status)) {
this->mark_failed(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
}
}
void Husb238Component::update() {
uint8_t status;
if (!this->read_byte(REG_PD_STATUS1, &status)) {
this->status_set_warning();
return;
}
this->status_clear_warning();
#ifdef USE_BINARY_SENSOR
if (this->attached_binary_sensor_ != nullptr) {
this->attached_binary_sensor_->publish_state((status & PD_STATUS1_ATTACHED) != 0);
}
if (this->cc_direction_binary_sensor_ != nullptr) {
// The CC line only means something while a source is attached
if (status & PD_STATUS1_ATTACHED) {
this->cc_direction_binary_sensor_->publish_state((status & PD_STATUS1_CC_DIR) != 0);
} else {
this->cc_direction_binary_sensor_->invalidate_state();
}
}
#endif
}
void Husb238Component::dump_config() {
ESP_LOGCONFIG(TAG, "HUSB238:");
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
if (this->is_failed()) {
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
}
#ifdef USE_BINARY_SENSOR
LOG_BINARY_SENSOR(" ", "PD Attached", this->attached_binary_sensor_);
LOG_BINARY_SENSOR(" ", "CC Direction", this->cc_direction_binary_sensor_);
#endif
}
} // namespace esphome::husb238
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
#ifdef USE_BINARY_SENSOR
#include "esphome/components/binary_sensor/binary_sensor.h"
#endif
namespace esphome::husb238 {
static constexpr uint8_t REG_PD_STATUS1 = 0x01;
static constexpr uint8_t PD_STATUS1_ATTACHED = 1 << 6;
static constexpr uint8_t PD_STATUS1_CC_DIR = 1 << 7;
class Husb238Component : public PollingComponent, public i2c::I2CDevice {
public:
void setup() override;
void update() override;
void dump_config() override;
#ifdef USE_BINARY_SENSOR
SUB_BINARY_SENSOR(attached)
SUB_BINARY_SENSOR(cc_direction)
#endif
};
} // namespace esphome::husb238
+11
View File
@@ -0,0 +1,11 @@
husb238:
id: husb238_hub
i2c_id: i2c_bus
binary_sensor:
- platform: husb238
husb238_id: husb238_hub
attached: "PD Attached"
cc_direction:
name: "CC Direction"
entity_category: diagnostic
@@ -0,0 +1,3 @@
packages:
i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml
husb238: !include common.yaml
@@ -0,0 +1,3 @@
packages:
i2c: !include ../../test_build_components/common/i2c/esp8266-ard.yaml
husb238: !include common.yaml