si4713 wip

This commit is contained in:
Gábor Poczkodi 2024-10-15 22:07:07 +02:00
parent 8033ef48a8
commit b695d1e804
9 changed files with 677 additions and 522 deletions

View file

@ -0,0 +1,27 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import output
from esphome.const import CONF_ID, CONF_PIN
from .. import (
CONF_SI4713_ID,
Si4713Component,
si4713_ns,
)
BinaryOutput = si4713_ns.class_("BinaryOutput", output.BinaryOutput, cg.Component)
CONFIG_SCHEMA = output.BINARY_OUTPUT_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(BinaryOutput),
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
cv.Required(CONF_PIN): cv.int_range(min=1, max=3),
}
).extend(cv.COMPONENT_SCHEMA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await output.register_output(var, config)
await cg.register_component(var, config)
await cg.register_parented(var, config[CONF_SI4713_ID])
cg.add(var.set_pin(config[CONF_PIN]))

View file

@ -0,0 +1,25 @@
#include "binary_output.h"
#include "esphome/core/log.h"
namespace esphome {
namespace si4713 {
static const char *const TAG = "si4713";
void BinaryOutput::dump_config() {
ESP_LOGCONFIG(TAG, "Si4713 Output:");
LOG_BINARY_OUTPUT(this);
ESP_LOGCONFIG(TAG, " Pin: %d", this->pin_);
}
void Si4713BinaryOutput::write_state(bool state) {
this->parent_->set_gpio(this->pin_, state);
}
} // namespace si4713
} // namespace esphome

View file

@ -0,0 +1,23 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/output/binary_output.h"
#include "../si4713.h"
namespace esphome {
namespace si4713 {
class BinaryOutput : public output::BinaryOutput, public Component, public Parented<Si4713Component> {
public:
void dump_config() override;
void set_pin(uint8_t pin) { this->pin_ = pin - 1; }
protected:
void write_state(bool state) override;
uint8_t pin_{0};
};
} // namespace si4713
} // namespace esphome

View file

@ -15,6 +15,7 @@ static const char *const TAG = "si4713";
Si4713Component::Si4713Component() { Si4713Component::Si4713Component() {
this->reset_pin_ = nullptr; this->reset_pin_ = nullptr;
this->reset_ = false; this->reset_ = false;
memset(this->gpio_, 0, sizeof(gpio_));
// memset(&this->state_, 0, sizeof(this->state_)); // memset(&this->state_, 0, sizeof(this->state_));
this->rds_station_pos_ = 0; this->rds_station_pos_ = 0;
this->rds_text_pos_ = 0; this->rds_text_pos_ = 0;
@ -22,45 +23,7 @@ Si4713Component::Si4713Component() {
// our defaults // our defaults
// this->state_. = ; // start with tx enabled // this->state_. = ; // start with tx enabled
} }
/*
void Si4713Component::write_reg_(uint8_t addr) {
switch (addr) {
case 0x00: // REG_..
break;
default:
ESP_LOGE(TAG, "write_reg_(0x%02X) invalid register address", addr);
return;
}
if (this->reset_) {
uint8_t value = this->regs_[addr];
ESP_LOGV(TAG, "write_reg_(0x%02X) = 0x%02X", addr, value);
this->write_byte(addr, value);
} else {
if (this->get_component_state() & COMPONENT_STATE_LOOP) {
ESP_LOGE(TAG, "write_reg_(0x%02X) device was not reset", addr);
}
}
}
bool Si4713Component::read_reg_(uint8_t addr) {
switch (addr) {
case 0x00: // REG_..
break;
default:
ESP_LOGE(TAG, "read_reg_(0x%02X) trying to read invalid register", addr);
return false;
}
if (auto b = this->read_byte(addr)) {
this->regs_[addr] = *b;
return true;
}
ESP_LOGE(TAG, "read_reg_(0x%02X) cannot read register", addr);
return false;
}
*/
bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size_t res_size) { bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size_t res_size) {
const uint8_t *buff = (const uint8_t *) cmd; const uint8_t *buff = (const uint8_t *) cmd;
@ -74,7 +37,7 @@ bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size
i2c::ErrorCode err = this->write(buff, cmd_size); i2c::ErrorCode err = this->write(buff, cmd_size);
if (err != i2c::ERROR_OK) { if (err != i2c::ERROR_OK) {
ESP_LOGE(TAG, "send_cmd(0x%02X, %d) write error", buff[0], cmd_size); ESP_LOGE(TAG, "send_cmd(0x%02X, %d) write error", buff[0], cmd_size);
this->mark_failed(); // this->mark_failed();
return false; return false;
} }
@ -83,7 +46,7 @@ bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size
err = this->read(&status, 1); // TODO: read res_size into res here? err = this->read(&status, 1); // TODO: read res_size into res here?
if (err != i2c::ERROR_OK) { if (err != i2c::ERROR_OK) {
ESP_LOGE(TAG, "send_cmd(0x%02X, %d) read status error", buff[0], cmd_size); ESP_LOGE(TAG, "send_cmd(0x%02X, %d) read status error", buff[0], cmd_size);
this->mark_failed(); // this->mark_failed();
return false; return false;
} }
} }
@ -93,7 +56,7 @@ bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size
err = this->read((uint8_t *) res, res_size); err = this->read((uint8_t *) res, res_size);
if (err != i2c::ERROR_OK) { if (err != i2c::ERROR_OK) {
ESP_LOGE(TAG, "send_cmd(0x%02X, %d) read response error", buff[0], cmd_size); ESP_LOGE(TAG, "send_cmd(0x%02X, %d) read response error", buff[0], cmd_size);
this->mark_failed(); // this->mark_failed();
return false; return false;
} }
} }
@ -101,112 +64,131 @@ bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size
return true; return true;
} }
bool Si4713Component::power_up() {
// Note: In FMTX component 1.0 and 2.0, a reset is required when the system controller writes a command other than
// POWER_UP when in powerdown mode
this->reset_pin_->digital_write(true);
delay_microseconds_safe(10);
this->reset_pin_->digital_write(false);
delay_microseconds_safe(10);
this->reset_pin_->digital_write(true);
CmdPowerUp cmd;
cmd.FUNC = 2;
cmd.XOSCEN = 1; // TODO: external oscillator
cmd.OPMODE = 0x50; // TODO: digital
cmd.GPO2OEN = 0; // TODO: GPIO2 enable
return this->send_cmd(cmd);
}
bool Si4713Component::power_down() { return this->send_cmd(CmdPowerDown()); }
bool Si4713Component::detect_chip_id() {
ResGetRev res;
if (!this->send_cmd(CmdGetRev(), res)) {
return false;
}
char buff[32] = {0};
snprintf(buff, sizeof(buff), "Si47%02d Rev %d", res.PN, res.CHIPREV);
this->chip_id_ = buff;
// TODO: support all transmitters 10/11/12/13/20/21
if (res.PN != 10 && res.PN != 11 && res.PN != 12 && res.PN != 13) {
ESP_LOGE(TAG, "Si47%02d is not supported", res.PN);
this->mark_failed();
return false;
}
return true;
}
bool Si4713Component::tune_power(uint8_t power, uint8_t antcap) {
if (!this->send_cmd(CmdTxTunePower(power, antcap))) {
return false;
}
return this->tune_ready();
}
bool Si4713Component::tune_freq(uint16_t freq) {
if (!this->send_cmd(CmdTxTuneFreq(freq))) {
return false;
}
return this->tune_ready();
}
bool Si4713Component::tune_ready() {
ResGetIntStatus res;
while (res.CTS != 1 || res.STCINT != 1) {
if (!this->send_cmd(CmdGetIntStatus(), res)) {
return false;
}
}
return true;
}
void Si4713Component::rds_update_() {} void Si4713Component::rds_update_() {}
// overrides // overrides
void Si4713Component::setup() { void Si4713Component::setup() {
if (this->reset_pin_ == nullptr) { // CHIP STATE: POWER DOWN
ESP_LOGE(TAG, "setup cannot reset device, reset pin is not set");
if (!this->power_up()) {
this->mark_failed(); this->mark_failed();
return; return;
} }
// reset
this->reset_ = true;
this->reset_pin_->setup();
if (!this->power_up()) {
return;
}
if (!this->detect_chip_id()) { if (!this->detect_chip_id()) {
this->mark_failed();
return; return;
} }
// CHIP STATE: POWER UP
uint16_t pilot = 1;
uint16_t stereo = 1;
uint16_t rds = 0;
uint16_t fmpe = 1;
uint16_t acen = 0;
uint16_t limiter = 1;
uint16_t digital = 0;
// Use GPO?
// Set RCLK settings
this->set_prop(PropRefClkFreq(32768)); this->set_prop(PropRefClkFreq(32768));
this->set_prop(PropTxPreEmphasis()); this->set_prop(PropRefClkPreScale(1, 0)); // div1, RCLK source
/*
// configuration! see page 254
setProperty(SI4713_PROP_REFCLK_FREQ, 32768); // crystal is 32.768
setProperty(SI4713_PROP_TX_PREEMPHASIS, 0); // 74uS pre-emph (USA std)
setProperty(SI4713_PROP_TX_ACOMP_GAIN, 10); // max gain?
// setProperty(SI4713_PROP_TX_ACOMP_ENABLE, 0x02); // turn on limiter, but no
// dynamic ranging
setProperty(SI4713_PROP_TX_ACOMP_ENABLE, 0x0); // turn on limiter and AGC
*/
// TODO: set properties // Mono/Stereo?
this->set_prop(PropTxPilotFrequency(19000));
this->set_prop(PropTxPilotDeviation(675));
this->set_prop(PropTxComponentEnable(pilot, stereo, rds));
// Set Audio Deviation
this->set_prop(PropTxAudioDeviation(6825));
// Transmit RDS?
// this->set_prop(PropTxRdsDeviation(200));
// if(rds) PropTxRds*
// if(rds) CmdTxRdsPs
// if(rds) CmdTxRdsBuff
// Preemphasis?
this->set_prop(PropTxPreEmphasis(fmpe));
this->set_prop(PropTxAcompEnable(acen, limiter));
// Compressor?
if (acen) {
// minimal compression
this->set_prop(PropTxAcompThreshold(-40)); // -40dBFS
this->set_prop(PropTxAcompAttackTime(0)); // 5ms
this->set_prop(PropTxAcompReleaseTime(0)); // 100ms
this->set_prop(PropTxAcompGain(15)); // 15dB
// aggressive compression
// this->set_prop(PropTxAcompThreshold(-15)); // -15dBFS
// this->set_prop(PropTxAcompAttackTime(9)); // 0.5ms
// this->set_prop(PropTxAcompReleaseTime(4)); // 1000ms
// this->set_prop(PropTxAcompGain(5)); // 5dB
}
// Limiter?
if (limiter) {
this->set_prop(PropTxLimiterReleaseTime(102)); // 5.01 ms
}
this->tune_power(115);
this->tune_freq(8750); this->tune_freq(8750);
this->tune_power(115);
// // CHIP STATE: TRANSMITTING
if (digital) {
// Digital Audio Input?
this->set_prop(PropDigitalInputFormat(0, 0, 1, 0)); // 16-bit, stereo, I2S mode, rising edge
this->set_prop(PropDigitalInputSampleRate(44100));
} else {
// Analog Audio Input?
this->set_prop(PropTxLineInputLevel(636, 3)); // 636 mvPK, 60 kOhm
}
// Mute?
this->set_prop(PropTxLineInputMute(0, 0)); // left no mute, right no mute
// Optional: Mute or Unmute Audio based on ASQ status
// Enable GPIO1, GPIO2
// TOOD:
// output:
// - platform: si4713
// pin: 1/2
// ...
this->send_cmd(CmdGpioCtl(1, 1));
/*
this->set_interval(3000, [this]() {
static uint8_t gpio1 = 0, gpio2 = 0;
this->send_cmd(CmdGpioSet(gpio1++ & 1, gpio2++ & 1));
});
*/
this->set_interval(3000, [this]() {
ResTxTuneStatus res;
if (this->send_cmd(CmdTxTuneStatus(), res)) {
ESP_LOGD(TAG, "ResTxTuneStatus FREQ %d RFdBuV %d ANTCAP %d NL %d", (res.READFREQH << 8) | res.READFREQL,
res.READRFdBuV, res.READANTCAP, res.RNL);
}
});
// Monitor Audio Signal Quality (ASQ)?
// TODO: PropTxAsqInterruptSource
// TODO: PropTxAsqLevelLow
// TODO: PropTxAsqDurationLow
// TODO: PropTxAsqLevelHigh
// TODO: PropTxAsqDurationHigh
this->set_interval(3000, [this]() {
ResTxAsqStatus res;
if (this->send_cmd(CmdTxAsqStatus(), res)) {
ESP_LOGD(TAG, "ResTxAsqStatus OVERMOD %d IALH %d IALL %d INLEVEL %d", res.OVERMOD, res.IALH, res.IALL,
res.INLEVEL);
}
});
// TODO
this->publish_frequency(); this->publish_frequency();
this->publish_mute(); this->publish_mute();
@ -214,6 +196,9 @@ void Si4713Component::setup() {
this->publish_rds_enable(); this->publish_rds_enable();
this->publish_rds_station(); this->publish_rds_station();
this->publish_rds_text(); this->publish_rds_text();
this->publish_gpio(0);
this->publish_gpio(1);
this->publish_gpio(2);
this->set_interval(1000, [this]() { this->rds_update_(); }); this->set_interval(1000, [this]() { this->rds_update_(); });
} }
@ -244,6 +229,94 @@ void Si4713Component::update() {
void Si4713Component::loop() {} void Si4713Component::loop() {}
//
bool Si4713Component::reset() {
if (this->reset_pin_ == nullptr) {
ESP_LOGE(TAG, "cannot reset device, reset pin is not set");
return false;
}
if (!this->reset_) {
this->reset_pin_->setup();
}
this->reset_pin_->digital_write(true);
delay_microseconds_safe(10);
this->reset_pin_->digital_write(false);
delay_microseconds_safe(10);
this->reset_pin_->digital_write(true);
this->reset_ = true;
return true;
}
bool Si4713Component::power_up() {
// Note: In FMTX component 1.0 and 2.0, a reset is required when the system
// controller writes a command other than POWER_UP when in powerdown mode
this->reset();
CmdPowerUp cmd;
cmd.FUNC = 2;
cmd.XOSCEN = 1; // TODO: external oscillator
cmd.OPMODE = 0x50; // TODO: digital
cmd.GPO2OEN = 0; // TODO: GPIO2 enable
return this->send_cmd(cmd);
}
bool Si4713Component::power_down() { return this->send_cmd(CmdPowerDown()); }
bool Si4713Component::detect_chip_id() {
ResGetRev res;
if (!this->send_cmd(CmdGetRev(), res)) {
return false;
}
char buff[32] = {0};
snprintf(buff, sizeof(buff), "Si47%02d Rev %d", res.PN, res.CHIPREV);
this->chip_id_ = buff;
// TODO: support all transmitters 10/11/12/13/20/21
if (res.PN != 10 && res.PN != 11 && res.PN != 12 && res.PN != 13) {
ESP_LOGE(TAG, "Si47%02d is not supported", res.PN);
return false;
}
return true;
}
bool Si4713Component::tune_freq(uint16_t freq) {
if (!this->send_cmd(CmdTxTuneFreq(freq))) {
return false;
}
return this->tune_wait();
}
bool Si4713Component::tune_power(uint8_t power, uint8_t antcap) {
if (!this->send_cmd(CmdTxTunePower(power, antcap))) {
return false;
}
return this->tune_wait();
}
bool Si4713Component::tune_wait() {
ResGetIntStatus res;
while (res.CTS != 1 || res.STCINT != 1) {
if (!this->send_cmd(CmdGetIntStatus(), res)) {
return false;
}
}
ResTxTuneStatus res2; // TODO: maybe store this as the last tune result and report it through sensors
if (!this->send_cmd(CmdTxTuneStatus(), res2)) {
return false;
}
return true;
}
// config // config
void Si4713Component::set_reset_pin(InternalGPIOPin *pin) { this->reset_pin_ = pin; } void Si4713Component::set_reset_pin(InternalGPIOPin *pin) { this->reset_pin_ = pin; }
@ -326,6 +399,26 @@ void Si4713Component::set_rds_text(const std::string &value) {
this->publish_rds_text(); this->publish_rds_text();
} }
void Si4713Component::set_gpio(uint8_t pin, bool value) {
if (pin > 2) {
ESP_LOGE(TAG, "set_gpio(%d, %d) invalid pin number, 0 to 2", pin, value ? 1 : 0);
return;
}
ESP_LOGD(TAG, "set_gpio(%d, %d)", pin, value ? 1 : 0);
this->gpio_[pin] = value ? 1 : 0;
this->send_cmd(CmdGpioCtl(this->gpio_[0], this->gpio_[1], this->gpio_[2]));
this->publish_gpio(pin);
}
bool Si4713Component::get_gpio(uint8_t pin) {
if (pin > 2) {
ESP_LOGE(TAG, "get_gpio(%d) invalid pin number, 0 to 2", pin);
return false;
}
return this->gpio_[pin];
}
// publish // publish
void Si4713Component::publish_() { void Si4713Component::publish_() {
@ -346,6 +439,22 @@ void Si4713Component::publish_rds_station() { this->publish(this->rds_station_te
void Si4713Component::publish_rds_text() { this->publish(this->rds_text_text_, this->rds_text_); } void Si4713Component::publish_rds_text() { this->publish(this->rds_text_text_, this->rds_text_); }
void Si4713Component::publish_gpio(uint8_t pin) {
switch (pin) {
case 0:
this->publish(this->gpio1_switch_, this->gpio_[pin]);
break;
case 1:
this->publish(this->gpio2_switch_, this->gpio_[pin]);
break;
case 2:
this->publish(this->gpio3_switch_, this->gpio_[pin]);
break;
default:
return;
}
}
void Si4713Component::publish(text_sensor::TextSensor *s, const std::string &state) { void Si4713Component::publish(text_sensor::TextSensor *s, const std::string &state) {
if (s != nullptr) { if (s != nullptr) {
if (!s->has_state() || s->state != state) { if (!s->has_state() || s->state != state) {

View file

@ -29,6 +29,7 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
std::string chip_id_; std::string chip_id_;
InternalGPIOPin *reset_pin_; InternalGPIOPin *reset_pin_;
bool reset_; bool reset_;
bool gpio_[3];
/* /*
union { union {
struct Si4713State state_; struct Si4713State state_;
@ -63,13 +64,6 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
return false; return false;
} }
bool power_up();
bool power_down();
bool detect_chip_id();
bool tune_power(uint8_t power = 0, uint8_t antcap = 0);
bool tune_freq(uint16_t freq);
bool tune_ready();
std::string rds_station_; std::string rds_station_;
std::string rds_text_; std::string rds_text_;
uint8_t rds_station_pos_; uint8_t rds_station_pos_;
@ -87,7 +81,9 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
SUB_SWITCH(rds_enable) SUB_SWITCH(rds_enable)
SUB_TEXT(rds_station) SUB_TEXT(rds_station)
SUB_TEXT(rds_text) SUB_TEXT(rds_text)
// TODO: GPIO switches SUB_SWITCH(gpio1)
SUB_SWITCH(gpio2)
SUB_SWITCH(gpio3)
void publish_(); void publish_();
void publish_chip_id(); void publish_chip_id();
@ -97,6 +93,7 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
void publish_rds_enable(); void publish_rds_enable();
void publish_rds_station(); void publish_rds_station();
void publish_rds_text(); void publish_rds_text();
void publish_gpio(uint8_t pin);
void publish(sensor::Sensor *s, float state); void publish(sensor::Sensor *s, float state);
void publish(text_sensor::TextSensor *s, const std::string &state); void publish(text_sensor::TextSensor *s, const std::string &state);
void publish(number::Number *n, float state); void publish(number::Number *n, float state);
@ -113,6 +110,14 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
void update() override; void update() override;
void loop() override; void loop() override;
bool reset();
bool power_up();
bool power_down();
bool detect_chip_id();
bool tune_freq(uint16_t freq);
bool tune_power(uint8_t power = 0, uint8_t antcap = 0);
bool tune_wait();
void set_reset_pin(InternalGPIOPin *pin); void set_reset_pin(InternalGPIOPin *pin);
void set_frequency(float value); void set_frequency(float value);
float get_frequency(); float get_frequency();
@ -124,6 +129,8 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
bool get_rds_enable(); bool get_rds_enable();
void set_rds_station(const std::string &value); void set_rds_station(const std::string &value);
void set_rds_text(const std::string &value); void set_rds_text(const std::string &value);
void set_gpio(uint8_t pin, bool value);
bool get_gpio(uint8_t pin);
}; };
} // namespace si4713 } // namespace si4713

File diff suppressed because it is too large Load diff

View file

@ -18,9 +18,14 @@ from .. import (
ICON_FORMAT_TEXT, ICON_FORMAT_TEXT,
) )
CONF_GPIO1="gpio1"
CONF_GPIO2="gpio2"
CONF_GPIO3="gpio3"
MuteSwitch = si4713_ns.class_("MuteSwitch", switch.Switch) MuteSwitch = si4713_ns.class_("MuteSwitch", switch.Switch)
MonoSwitch = si4713_ns.class_("MonoSwitch", switch.Switch) MonoSwitch = si4713_ns.class_("MonoSwitch", switch.Switch)
RDSEnableSwitch = si4713_ns.class_("RDSEnableSwitch", switch.Switch) RDSEnableSwitch = si4713_ns.class_("RDSEnableSwitch", switch.Switch)
GPIOSwitch = si4713_ns.class_("GPIOSwitch", switch.Switch)
CONFIG_SCHEMA = cv.Schema( CONFIG_SCHEMA = cv.Schema(
{ {
@ -43,6 +48,24 @@ CONFIG_SCHEMA = cv.Schema(
entity_category=ENTITY_CATEGORY_CONFIG, entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_FORMAT_TEXT, icon=ICON_FORMAT_TEXT,
), ),
cv.Optional(CONF_GPIO1): switch.switch_schema(
GPIOSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
# icon=,
),
cv.Optional(CONF_GPIO2): switch.switch_schema(
GPIOSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
# icon=,
),
cv.Optional(CONF_GPIO3): switch.switch_schema(
GPIOSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
# icon=,
),
} }
) )
@ -52,6 +75,7 @@ async def new_switch(config, id, setter):
s = await switch.new_switch(c) s = await switch.new_switch(c)
await cg.register_parented(s, config[CONF_SI4713_ID]) await cg.register_parented(s, config[CONF_SI4713_ID])
cg.add(setter(s)) cg.add(setter(s))
return s
async def to_code(config): async def to_code(config):
@ -59,3 +83,9 @@ async def to_code(config):
await new_switch(config, CONF_MUTE, c.set_mute_switch) await new_switch(config, CONF_MUTE, c.set_mute_switch)
await new_switch(config, CONF_MONO, c.set_mono_switch) await new_switch(config, CONF_MONO, c.set_mono_switch)
await new_switch(config, CONF_RDS_ENABLE, c.set_rds_enable_switch) await new_switch(config, CONF_RDS_ENABLE, c.set_rds_enable_switch)
s = await new_switch(config, CONF_GPIO1, c.set_gpio1_switch)
s.set_pin(1)
s = await new_switch(config, CONF_GPIO2, c.set_gpio2_switch)
s.set_pin(2)
s = await new_switch(config, CONF_GPIO3, c.set_gpio3_switch)
s.set_pin(3)

View file

@ -0,0 +1,12 @@
#include "gpio_switch.h"
namespace esphome {
namespace si4713 {
void GPIOSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_gpio(this->pin_, value);
}
} // namespace si4713
} // namespace esphome

View file

@ -0,0 +1,22 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../si4713.h"
namespace esphome {
namespace si4713 {
class GPIOSwitch : public switch_::Switch, public Parented<Si4713Component> {
public:
GPIOSwitch() = default;
void set_pin(uint8_t pin) { this->pin_ = pin - 1; }
protected:
void write_state(bool value) override;
uint8_t pin_{0};
};
} // namespace si4713
} // namespace esphome