From 679633245d8bb6980f041ed5300694608515460e Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 8 May 2023 12:45:12 +1200 Subject: [PATCH] Add gp8403 output component (#4495) Co-authored-by: Samuel Sieb --- CODEOWNERS | 1 + esphome/components/gp8403/__init__.py | 40 +++++++++++++++++++ esphome/components/gp8403/gp8403.cpp | 21 ++++++++++ esphome/components/gp8403/gp8403.h | 27 +++++++++++++ esphome/components/gp8403/output/__init__.py | 31 ++++++++++++++ .../gp8403/output/gp8403_output.cpp | 26 ++++++++++++ .../components/gp8403/output/gp8403_output.h | 25 ++++++++++++ tests/test5.yaml | 15 +++++++ 8 files changed, 186 insertions(+) create mode 100644 esphome/components/gp8403/__init__.py create mode 100644 esphome/components/gp8403/gp8403.cpp create mode 100644 esphome/components/gp8403/gp8403.h create mode 100644 esphome/components/gp8403/output/__init__.py create mode 100644 esphome/components/gp8403/output/gp8403_output.cpp create mode 100644 esphome/components/gp8403/output/gp8403_output.h diff --git a/CODEOWNERS b/CODEOWNERS index d3216db695..70f8d6864a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -95,6 +95,7 @@ esphome/components/feedback/* @ianchi esphome/components/fingerprint_grow/* @OnFreund @loongyh esphome/components/fs3000/* @kahrendt esphome/components/globals/* @esphome/core +esphome/components/gp8403/* @jesserockz esphome/components/gpio/* @esphome/core esphome/components/gps/* @coogle esphome/components/graph/* @synco diff --git a/esphome/components/gp8403/__init__.py b/esphome/components/gp8403/__init__.py new file mode 100644 index 0000000000..a7a2b46f58 --- /dev/null +++ b/esphome/components/gp8403/__init__.py @@ -0,0 +1,40 @@ +import esphome.config_validation as cv +import esphome.codegen as cg + +from esphome.components import i2c +from esphome.const import CONF_ID, CONF_VOLTAGE + +CODEOWNERS = ["@jesserockz"] +DEPENDENCIES = ["i2c"] +MULTI_CONF = True + +gp8403_ns = cg.esphome_ns.namespace("gp8403") +GP8403 = gp8403_ns.class_("GP8403", cg.Component, i2c.I2CDevice) + +GP8403Voltage = gp8403_ns.enum("GP8403Voltage") + +CONF_GP8403_ID = "gp8403_id" + +VOLTAGES = { + "5V": GP8403Voltage.GP8403_VOLTAGE_5V, + "10V": GP8403Voltage.GP8403_VOLTAGE_10V, +} + +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(GP8403), + cv.Required(CONF_VOLTAGE): cv.enum(VOLTAGES, upper=True), + } + ) + .extend(cv.COMPONENT_SCHEMA) + .extend(i2c.i2c_device_schema(0x58)) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await i2c.register_i2c_device(var, config) + + cg.add(var.set_voltage(config[CONF_VOLTAGE])) diff --git a/esphome/components/gp8403/gp8403.cpp b/esphome/components/gp8403/gp8403.cpp new file mode 100644 index 0000000000..7a08a18a8f --- /dev/null +++ b/esphome/components/gp8403/gp8403.cpp @@ -0,0 +1,21 @@ +#include "gp8403.h" + +#include "esphome/core/log.h" + +namespace esphome { +namespace gp8403 { + +static const char *const TAG = "gp8403"; + +static const uint8_t RANGE_REGISTER = 0x01; + +void GP8403::setup() { this->write_register(RANGE_REGISTER, (uint8_t *) (&this->voltage_), 1); } + +void GP8403::dump_config() { + ESP_LOGCONFIG(TAG, "GP8403:"); + ESP_LOGCONFIG(TAG, " Voltage: %dV", this->voltage_ == GP8403_VOLTAGE_5V ? 5 : 10); + LOG_I2C_DEVICE(this); +} + +} // namespace gp8403 +} // namespace esphome diff --git a/esphome/components/gp8403/gp8403.h b/esphome/components/gp8403/gp8403.h new file mode 100644 index 0000000000..65182ef301 --- /dev/null +++ b/esphome/components/gp8403/gp8403.h @@ -0,0 +1,27 @@ +#pragma once + +#include "esphome/components/i2c/i2c.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace gp8403 { + +enum GP8403Voltage { + GP8403_VOLTAGE_5V = 0x00, + GP8403_VOLTAGE_10V = 0x11, +}; + +class GP8403 : public Component, public i2c::I2CDevice { + public: + void setup() override; + void dump_config() override; + float get_setup_priority() const override { return setup_priority::DATA; } + + void set_voltage(gp8403::GP8403Voltage voltage) { this->voltage_ = voltage; } + + protected: + GP8403Voltage voltage_; +}; + +} // namespace gp8403 +} // namespace esphome diff --git a/esphome/components/gp8403/output/__init__.py b/esphome/components/gp8403/output/__init__.py new file mode 100644 index 0000000000..1cf95ac6e5 --- /dev/null +++ b/esphome/components/gp8403/output/__init__.py @@ -0,0 +1,31 @@ +import esphome.config_validation as cv +import esphome.codegen as cg + +from esphome.components import i2c, output +from esphome.const import CONF_ID, CONF_CHANNEL + +from .. import gp8403_ns, GP8403, CONF_GP8403_ID + +DEPENDENCIES = ["gp8403"] + +GP8403Output = gp8403_ns.class_( + "GP8403Output", cg.Component, i2c.I2CDevice, output.FloatOutput +) + +CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( + { + cv.GenerateID(): cv.declare_id(GP8403Output), + cv.GenerateID(CONF_GP8403_ID): cv.use_id(GP8403), + cv.Required(CONF_CHANNEL): cv.one_of(0, 1), + } +).extend(cv.COMPONENT_SCHEMA) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await output.register_output(var, config) + + await cg.register_parented(var, config[CONF_GP8403_ID]) + + cg.add(var.set_channel(config[CONF_CHANNEL])) diff --git a/esphome/components/gp8403/output/gp8403_output.cpp b/esphome/components/gp8403/output/gp8403_output.cpp new file mode 100644 index 0000000000..ff73bb4627 --- /dev/null +++ b/esphome/components/gp8403/output/gp8403_output.cpp @@ -0,0 +1,26 @@ +#include "gp8403_output.h" + +#include "esphome/core/log.h" + +namespace esphome { +namespace gp8403 { + +static const char *const TAG = "gp8403.output"; + +static const uint8_t OUTPUT_REGISTER = 0x02; + +void GP8403Output::dump_config() { + ESP_LOGCONFIG(TAG, "GP8403 Output:"); + ESP_LOGCONFIG(TAG, " Channel: %u", this->channel_); +} + +void GP8403Output::write_state(float state) { + uint16_t value = ((uint16_t) (state * 4095)) << 4; + i2c::ErrorCode err = this->parent_->write_register(OUTPUT_REGISTER + (2 * this->channel_), (uint8_t *) &value, 2); + if (err != i2c::ERROR_OK) { + ESP_LOGE(TAG, "Error writing to GP8403, code %d", err); + } +} + +} // namespace gp8403 +} // namespace esphome diff --git a/esphome/components/gp8403/output/gp8403_output.h b/esphome/components/gp8403/output/gp8403_output.h new file mode 100644 index 0000000000..71e5efb1cb --- /dev/null +++ b/esphome/components/gp8403/output/gp8403_output.h @@ -0,0 +1,25 @@ +#pragma once + +#include "esphome/components/output/float_output.h" +#include "esphome/core/component.h" + +#include "esphome/components/gp8403/gp8403.h" + +namespace esphome { +namespace gp8403 { + +class GP8403Output : public Component, public output::FloatOutput, public Parented { + public: + void dump_config() override; + float get_setup_priority() const override { return setup_priority::DATA - 1; } + + void set_channel(uint8_t channel) { this->channel_ = channel; } + + void write_state(float state) override; + + protected: + uint8_t channel_; +}; + +} // namespace gp8403 +} // namespace esphome diff --git a/tests/test5.yaml b/tests/test5.yaml index 0d044ac241..856889c1f3 100644 --- a/tests/test5.yaml +++ b/tests/test5.yaml @@ -208,6 +208,12 @@ tlc5947: clock_pin: GPIO14 lat_pin: GPIO15 +gp8403: + - id: gp8403_5v + voltage: 5V + - id: gp8403_10v + voltage: 10V + output: - platform: gpio pin: GPIO2 @@ -245,6 +251,15 @@ output: id: Led7 led: 7 + - platform: gp8403 + id: gp8403_output_0 + gp8403_id: gp8403_5v + channel: 0 + - platform: gp8403 + gp8403_id: gp8403_10v + id: gp8403_output_1 + channel: 1 + demo: esp32_ble: