From 2b6ddd9d042a961f1ad69218e1ecaa1667ec1a86 Mon Sep 17 00:00:00 2001 From: Tomasz Duda Date: Tue, 1 Oct 2024 14:46:57 +0200 Subject: [PATCH] add usb_device --- esphome/components/usb_device/__init__.py | 43 +++++++++++++++++++ .../components/usb_device/binary_sensor.py | 32 ++++++++++++++ esphome/components/usb_device/usb_device.cpp | 32 ++++++++++++++ esphome/components/usb_device/usb_device.h | 26 +++++++++++ .../usb_device/test.esp32-s2-ard.yaml | 4 ++ .../usb_device/test.esp32-s3-ard.yaml | 4 ++ 6 files changed, 141 insertions(+) create mode 100644 esphome/components/usb_device/__init__.py create mode 100644 esphome/components/usb_device/binary_sensor.py create mode 100644 esphome/components/usb_device/usb_device.cpp create mode 100644 esphome/components/usb_device/usb_device.h create mode 100644 tests/components/usb_device/test.esp32-s2-ard.yaml create mode 100644 tests/components/usb_device/test.esp32-s3-ard.yaml diff --git a/esphome/components/usb_device/__init__.py b/esphome/components/usb_device/__init__.py new file mode 100644 index 0000000000..1f0bd0b60e --- /dev/null +++ b/esphome/components/usb_device/__init__.py @@ -0,0 +1,43 @@ +import esphome.config_validation as cv +import esphome.codegen as cg +from esphome.core import CORE +from esphome.const import ( + CONF_ID, +) +from esphome.components.esp32.const import ( + KEY_ESP32, + KEY_VARIANT, + VARIANT_ESP32S2, + VARIANT_ESP32S3, +) +import esphome.final_validate as fv + +CODEOWNERS = ["@tomaszduda23"] +CONF_USB_DEVICE_ID = "usb_device_id" + + +def _validate_variant(value): + variant = CORE.data[KEY_ESP32][KEY_VARIANT] + if variant not in [VARIANT_ESP32S2, VARIANT_ESP32S3]: + raise cv.Invalid(f"USB device is unsupported by ESP32 variant {variant}") + return value + +CONF_USB_DEVICE = "usb_device" + +usb_device_ns = cg.esphome_ns.namespace(CONF_USB_DEVICE) +UsbDevice = usb_device_ns.class_("UsbDevice", cg.PollingComponent) + +CONFIG_SCHEMA = cv.All( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(UsbDevice), + } + ).extend(cv.polling_component_schema("10s")), + cv.only_with_arduino, + cv.only_on_esp32, + _validate_variant, +) + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) diff --git a/esphome/components/usb_device/binary_sensor.py b/esphome/components/usb_device/binary_sensor.py new file mode 100644 index 0000000000..9c3b51090c --- /dev/null +++ b/esphome/components/usb_device/binary_sensor.py @@ -0,0 +1,32 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import binary_sensor +from . import CONF_USB_DEVICE_ID, UsbDevice, CONF_USB_DEVICE + +AUTO_LOAD = [CONF_USB_DEVICE] + +CONF_CONFIGURED = "configured" + +TYPES = [ + CONF_CONFIGURED, +] + +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(CONF_USB_DEVICE_ID): cv.use_id(UsbDevice), + cv.Optional(CONF_CONFIGURED): binary_sensor.binary_sensor_schema(), + } +).extend(cv.COMPONENT_SCHEMA) + + +async def setup_conf(config, key, hub): + if key in config: + conf = config[key] + var = await binary_sensor.new_binary_sensor(conf) + cg.add(getattr(hub, f"set_{key}_binary_sensor")(var)) + + +async def to_code(config): + hub = await cg.get_variable(config[CONF_USB_DEVICE_ID]) + for key in TYPES: + await setup_conf(config, key, hub) diff --git a/esphome/components/usb_device/usb_device.cpp b/esphome/components/usb_device/usb_device.cpp new file mode 100644 index 0000000000..d554f371de --- /dev/null +++ b/esphome/components/usb_device/usb_device.cpp @@ -0,0 +1,32 @@ +#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#include "usb_device.h" +#include "esphome/core/log.h" +#include "USB.h" + +namespace esphome { +namespace usb_device { + +static const char *const TAG = "usb_device"; + +void UsbDevice::update() { +#ifdef USE_BINARY_SENSOR + if (configured_ != nullptr) { + bool configured = USB; + configured_->publish_state(configured); + } +#endif +} + + +void UsbDevice::dump_config() { + bool configured = USB; + ESP_LOGCONFIG(TAG, "USB device - configured: %s", YESNO(configured)); +} + +#ifdef USE_BINARY_SENSOR +void UsbDevice::set_configured_binary_sensor(binary_sensor::BinarySensor *sensor) { configured_ = sensor; }; +#endif + +} // namespace usb_device +} // namespace esphome +#endif diff --git a/esphome/components/usb_device/usb_device.h b/esphome/components/usb_device/usb_device.h new file mode 100644 index 0000000000..c54f1876fc --- /dev/null +++ b/esphome/components/usb_device/usb_device.h @@ -0,0 +1,26 @@ +#pragma once +#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#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 { +namespace usb_device { + +class UsbDevice : public PollingComponent { + public: + void update() override; + void dump_config() override; +#ifdef USE_BINARY_SENSOR + void set_configured_binary_sensor(binary_sensor::BinarySensor *sensor); +#endif + protected: +#ifdef USE_BINARY_SENSOR + binary_sensor::BinarySensor *configured_; +#endif +}; + +} // namespace usb_device +} // namespace esphome +#endif diff --git a/tests/components/usb_device/test.esp32-s2-ard.yaml b/tests/components/usb_device/test.esp32-s2-ard.yaml new file mode 100644 index 0000000000..f70e9e7a41 --- /dev/null +++ b/tests/components/usb_device/test.esp32-s2-ard.yaml @@ -0,0 +1,4 @@ +binary_sensor: + - platform: usb_device + configured: + name: USB is configured diff --git a/tests/components/usb_device/test.esp32-s3-ard.yaml b/tests/components/usb_device/test.esp32-s3-ard.yaml new file mode 100644 index 0000000000..f70e9e7a41 --- /dev/null +++ b/tests/components/usb_device/test.esp32-s3-ard.yaml @@ -0,0 +1,4 @@ +binary_sensor: + - platform: usb_device + configured: + name: USB is configured