mirror of
https://github.com/esphome/esphome.git
synced 2024-12-25 06:54:52 +01:00
si4713 commands, properties
This commit is contained in:
parent
0c7c84011a
commit
8033ef48a8
20 changed files with 2415 additions and 0 deletions
131
esphome/components/si4713_i2c/__init__.py
Normal file
131
esphome/components/si4713_i2c/__init__.py
Normal file
|
@ -0,0 +1,131 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation, pins
|
||||
from esphome.components import i2c, sensor, text_sensor
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_FREQUENCY,
|
||||
UNIT_EMPTY,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
ICON_CHIP,
|
||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@gabest11"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["sensor", "text_sensor", "number", "switch", "select", "text"]
|
||||
MULTI_CONF = True
|
||||
|
||||
UNIT_MEGA_HERTZ = "MHz"
|
||||
UNIT_KILO_HERTZ = "kHz"
|
||||
UNIT_MILLI_VOLT = "mV"
|
||||
UNIT_MICRO_AMPERE = "mA"
|
||||
UNIT_DECIBEL_MICRO_VOLT = "dBµV"
|
||||
|
||||
ICON_VOLUME_MUTE = "mdi:volume-mute"
|
||||
ICON_EAR_HEARING = "mdi:ear-hearing"
|
||||
ICON_RADIO_TOWER = "mdi:radio-tower"
|
||||
ICON_SLEEP = "mdi:sleep"
|
||||
ICON_SINE_WAVE = "mdi:sine-wave"
|
||||
ICON_RESISTOR = "mdi:resistor"
|
||||
ICON_FORMAT_TEXT = "mdi:format-text"
|
||||
|
||||
si4713_ns = cg.esphome_ns.namespace("si4713")
|
||||
Si4713Component = si4713_ns.class_(
|
||||
"Si4713Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONF_SI4713_ID = "si4713_id"
|
||||
CONF_RESET_PIN = "reset_pin"
|
||||
CONF_FREQUENCY_DEVIATION = "frequency_deviation"
|
||||
CONF_MUTE = "mute"
|
||||
CONF_MONO = "mono"
|
||||
CONF_TX_ENABLE = "tx_enable"
|
||||
CONF_TX_PILOT = "tx_pilot"
|
||||
CONF_T1M_SEL = "t1m_sel"
|
||||
CONF_PRIV_EN = "priv_en"
|
||||
CONF_PRE_EMPHASIS = "pre_emphasis"
|
||||
CONF_XTAL_SOURCE = "xtal_source"
|
||||
CONF_XTAL_CURRENT = "xtal_current"
|
||||
CONF_XTAL_FREQUENCY = "xtal_frequency"
|
||||
CONF_INPUT_IMPEDANCE = "input_impedance"
|
||||
CONF_INPUT_GAIN = "input_gain"
|
||||
CONF_DIGITAL_GAIN = "digital_gain"
|
||||
CONF_POWER_TARGET = "power_target"
|
||||
CONF_RDS_ENABLE = "rds_enable"
|
||||
CONF_RDS_FREQUENCY_DEVIATION = "rds_frequency_deviation"
|
||||
CONF_RDS_STATION = "rds_station"
|
||||
CONF_RDS_TEXT = "rds_text"
|
||||
CONF_AUD_PK = "aud_pk"
|
||||
CONF_FSM = "fsm"
|
||||
CONF_CHIP_ID = "chip_id"
|
||||
CONF_REG30 = "reg30"
|
||||
|
||||
SetFrequencyAction = si4713_ns.class_(
|
||||
"SetFrequencyAction", automation.Action, cg.Parented.template(Si4713Component)
|
||||
)
|
||||
|
||||
#T1mSel = si4713_ns.enum("T1mSel", True)
|
||||
#T1M_SEL = {
|
||||
# "58s": T1mSel.T1M_SEL_58S,
|
||||
# "59s": T1mSel.T1M_SEL_59S,
|
||||
# "60s": T1mSel.T1M_SEL_60S,
|
||||
# "Never": T1mSel.T1M_SEL_NEVER,
|
||||
#}
|
||||
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Si4713Component),
|
||||
cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_FREQUENCY, default=87.50): cv.float_range(76, 108),
|
||||
cv.Optional(CONF_MUTE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_MONO, default=False): cv.boolean,
|
||||
# cv.Optional(CONF_T1M_SEL, default="60s"): cv.enum(T1M_SEL),
|
||||
cv.Optional(CONF_RDS_ENABLE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_RDS_STATION): cv.string,
|
||||
cv.Optional(CONF_RDS_TEXT): cv.string,
|
||||
cv.Optional(CONF_CHIP_ID): text_sensor.text_sensor_schema(
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
icon=ICON_CHIP,
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x63))
|
||||
)
|
||||
|
||||
|
||||
async def set_var(config, id, setter):
|
||||
if c := config.get(id):
|
||||
cg.add(setter(c))
|
||||
|
||||
|
||||
async def set_sensor(config, id, setter):
|
||||
if c := config.get(id):
|
||||
s = await sensor.new_sensor(c)
|
||||
cg.add(setter(s))
|
||||
|
||||
|
||||
async def set_text_sensor(config, id, setter):
|
||||
if c := config.get(id):
|
||||
s = await text_sensor.new_text_sensor(c)
|
||||
cg.add(setter(s))
|
||||
|
||||
|
||||
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)
|
||||
reset_pin = await cg.gpio_pin_expression(config[CONF_RESET_PIN])
|
||||
cg.add(var.set_reset_pin(reset_pin))
|
||||
await set_var(config, CONF_FREQUENCY, var.set_frequency)
|
||||
await set_var(config, CONF_MUTE, var.set_mute)
|
||||
await set_var(config, CONF_MONO, var.set_mono)
|
||||
# await set_var(config, CONF_T1M_SEL, var.set_t1m_sel)
|
||||
await set_var(config, CONF_RDS_ENABLE, var.set_rds_enable)
|
||||
await set_var(config, CONF_RDS_STATION, var.set_rds_station)
|
||||
await set_var(config, CONF_RDS_TEXT, var.set_rds_text)
|
||||
await set_text_sensor(config, CONF_CHIP_ID, var.set_chip_id_text_sensor)
|
51
esphome/components/si4713_i2c/number/__init__.py
Normal file
51
esphome/components/si4713_i2c/number/__init__.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
import esphome.codegen as cg
|
||||
from esphome.components import number
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_FREQUENCY,
|
||||
UNIT_PERCENT,
|
||||
UNIT_DECIBEL,
|
||||
DEVICE_CLASS_FREQUENCY,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
)
|
||||
from .. import (
|
||||
CONF_SI4713_ID,
|
||||
Si4713Component,
|
||||
si4713_ns,
|
||||
# CONF_,
|
||||
UNIT_MEGA_HERTZ,
|
||||
UNIT_KILO_HERTZ,
|
||||
UNIT_MICRO_AMPERE,
|
||||
UNIT_DECIBEL_MICRO_VOLT,
|
||||
)
|
||||
|
||||
FrequencyNumber = si4713_ns.class_("FrequencyNumber", number.Number)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
||||
cv.Optional(CONF_FREQUENCY): number.number_schema(
|
||||
FrequencyNumber,
|
||||
unit_of_measurement=UNIT_MEGA_HERTZ,
|
||||
device_class=DEVICE_CLASS_FREQUENCY,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def new_number(config, id, setter, min_value, max_value, step, *args):
|
||||
if c := config.get(id):
|
||||
n = await number.new_number(
|
||||
c, *args, min_value=min_value, max_value=max_value, step=step
|
||||
)
|
||||
await cg.register_parented(n, config[CONF_SI4713_ID])
|
||||
cg.add(setter(n))
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
c = await cg.get_variable(config[CONF_SI4713_ID])
|
||||
await new_number(config, CONF_FREQUENCY, c.set_frequency_number, 76, 108, 0.05)
|
12
esphome/components/si4713_i2c/number/frequency_number.cpp
Normal file
12
esphome/components/si4713_i2c/number/frequency_number.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "frequency_number.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
void FrequencyNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_frequency(value);
|
||||
}
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
18
esphome/components/si4713_i2c/number/frequency_number.h
Normal file
18
esphome/components/si4713_i2c/number/frequency_number.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../si4713.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
class FrequencyNumber : public number::Number, public Parented<Si4713Component> {
|
||||
public:
|
||||
FrequencyNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
42
esphome/components/si4713_i2c/select/__init__.py
Normal file
42
esphome/components/si4713_i2c/select/__init__.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
import esphome.codegen as cg
|
||||
from esphome.components import select
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
ICON_PULSE,
|
||||
)
|
||||
from .. import (
|
||||
CONF_SI4713_ID,
|
||||
Si4713Component,
|
||||
si4713_ns,
|
||||
CONF_,
|
||||
ICON_SLEEP,
|
||||
ICON_SINE_WAVE,
|
||||
ICON_RESISTOR,
|
||||
# T1M_SEL,
|
||||
)
|
||||
|
||||
#T1mSelSelect = si4713_ns.class_("T1mSelSelect", select.Select)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
||||
# cv.Optional(CONF_T1M_SEL): select.select_schema(
|
||||
# T1mSelSelect,
|
||||
# entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
# icon=ICON_SLEEP,
|
||||
# ),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def new_select(config, id, setter, options):
|
||||
if c := config.get(id):
|
||||
s = await select.new_select(c, options=list(options.keys()))
|
||||
await cg.register_parented(s, config[CONF_SI4713_ID])
|
||||
cg.add(setter(s))
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
c = await cg.get_variable(config[CONF_SI4713_ID])
|
||||
# await new_select(config, CONF_T1M_SEL, c.set_t1m_sel_select, T1M_SEL)
|
400
esphome/components/si4713_i2c/si4713.cpp
Normal file
400
esphome/components/si4713_i2c/si4713.cpp
Normal file
|
@ -0,0 +1,400 @@
|
|||
#include "si4713.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
// TODO: std::clamp isn't here yet
|
||||
#define clamp(v, lo, hi) std::max(std::min(v, hi), lo)
|
||||
|
||||
static const char *const TAG = "si4713";
|
||||
|
||||
Si4713Component::Si4713Component() {
|
||||
this->reset_pin_ = nullptr;
|
||||
this->reset_ = false;
|
||||
// memset(&this->state_, 0, sizeof(this->state_));
|
||||
this->rds_station_pos_ = 0;
|
||||
this->rds_text_pos_ = 0;
|
||||
// this->state_. = ;
|
||||
// our defaults
|
||||
// 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) {
|
||||
const uint8_t *buff = (const uint8_t *) cmd;
|
||||
|
||||
if (!this->reset_) {
|
||||
if (this->get_component_state() & COMPONENT_STATE_LOOP) {
|
||||
ESP_LOGE(TAG, "send_cmd(0x%02X, %d) device was not reset", buff[0], cmd_size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
i2c::ErrorCode err = this->write(buff, cmd_size);
|
||||
if (err != i2c::ERROR_OK) {
|
||||
ESP_LOGE(TAG, "send_cmd(0x%02X, %d) write error", buff[0], cmd_size);
|
||||
this->mark_failed();
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t status = 0;
|
||||
while (!(status & SI4710_STATUS_CTS)) {
|
||||
err = this->read(&status, 1); // TODO: read res_size into res here?
|
||||
if (err != i2c::ERROR_OK) {
|
||||
ESP_LOGE(TAG, "send_cmd(0x%02X, %d) read status error", buff[0], cmd_size);
|
||||
this->mark_failed();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != nullptr) {
|
||||
//((uint8_t*) res)[0] = status;
|
||||
err = this->read((uint8_t *) res, res_size);
|
||||
if (err != i2c::ERROR_OK) {
|
||||
ESP_LOGE(TAG, "send_cmd(0x%02X, %d) read response error", buff[0], cmd_size);
|
||||
this->mark_failed();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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_() {}
|
||||
|
||||
// overrides
|
||||
|
||||
void Si4713Component::setup() {
|
||||
if (this->reset_pin_ == nullptr) {
|
||||
ESP_LOGE(TAG, "setup cannot reset device, reset pin is not set");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
// reset
|
||||
|
||||
this->reset_ = true;
|
||||
this->reset_pin_->setup();
|
||||
|
||||
if (!this->power_up()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->detect_chip_id()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->set_prop(PropRefClkFreq(32768));
|
||||
this->set_prop(PropTxPreEmphasis());
|
||||
/*
|
||||
// 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
|
||||
|
||||
this->tune_power(115);
|
||||
this->tune_freq(8750);
|
||||
|
||||
//
|
||||
|
||||
this->publish_frequency();
|
||||
this->publish_mute();
|
||||
this->publish_mono();
|
||||
this->publish_rds_enable();
|
||||
this->publish_rds_station();
|
||||
this->publish_rds_text();
|
||||
|
||||
this->set_interval(1000, [this]() { this->rds_update_(); });
|
||||
}
|
||||
|
||||
void Si4713Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Si4713:");
|
||||
LOG_I2C_DEVICE(this);
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, "failed!");
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " Chip: %s", this->chip_id_.c_str());
|
||||
ESP_LOGCONFIG(TAG, " Frequency: %.2f MHz", this->get_frequency());
|
||||
ESP_LOGCONFIG(TAG, " RDS station: %s", this->rds_station_.c_str());
|
||||
ESP_LOGCONFIG(TAG, " RDS text: %s", this->rds_text_.c_str());
|
||||
// TODO: ...and everything else...
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
void Si4713Component::update() {
|
||||
/*
|
||||
if (this->read_reg_(REG_)) {
|
||||
this->publish_();
|
||||
} else {
|
||||
ESP_LOGE(TAG, "update cannot read the status register");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void Si4713Component::loop() {}
|
||||
|
||||
// config
|
||||
|
||||
void Si4713Component::set_reset_pin(InternalGPIOPin *pin) { this->reset_pin_ = pin; }
|
||||
|
||||
void Si4713Component::set_frequency(float value) {
|
||||
if (!(CH_FREQ_MIN <= value && value <= CH_FREQ_MAX)) {
|
||||
ESP_LOGE(TAG, "set_frequency(%.2f) invalid (%.2f - %.2f)", value, CH_FREQ_MIN, CH_FREQ_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
// int f = clamp((int) std::lround((value - 76) * 20), CH_FREQ_RAW_MIN, CH_FREQ_RAW_MAX);
|
||||
// this->state_.CH_UPPER = (uint8_t) (f >> 8);
|
||||
// this->state_.CH_LOWER = (uint8_t) (f & 0xff);
|
||||
// this->write_reg_(REG_SYSTEM_ADDR);
|
||||
// this->write_reg_(REG_CH1_ADDR);
|
||||
|
||||
this->publish_frequency();
|
||||
}
|
||||
|
||||
float Si4713Component::get_frequency() {
|
||||
// uint16_t ch = ((uint16_t) this->state_.CH_UPPER << 8) | this->state_.CH_LOWER;
|
||||
// return (float) ch / 20 + 76;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Si4713Component::set_mute(bool value) {
|
||||
// this->state_.MUTE = value ? 1 : 0;
|
||||
// this->write_reg_(REG_SYSTEM_ADDR);
|
||||
|
||||
this->publish_mute();
|
||||
}
|
||||
|
||||
bool Si4713Component::get_mute() {
|
||||
// return this->state_.MUTE == 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Si4713Component::set_mono(bool value) {
|
||||
// this->state_.MONO = value ? 1 : 0;
|
||||
// this->write_reg_(REG_SYSTEM_ADDR);
|
||||
|
||||
this->publish_mono();
|
||||
}
|
||||
|
||||
bool Si4713Component::get_mono() {
|
||||
// return this->state_.MONO == 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Si4713Component::set_rds_enable(bool value) {
|
||||
// TODO
|
||||
|
||||
this->publish_rds_enable();
|
||||
}
|
||||
|
||||
bool Si4713Component::get_rds_enable() {
|
||||
// return this->state_.RDSEN == 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Si4713Component::set_rds_station(const std::string &value) {
|
||||
this->rds_station_ = value;
|
||||
this->rds_station_pos_ = 0;
|
||||
if (this->rds_station_.size() > RDS_STATION_MAX) {
|
||||
ESP_LOGW(TAG, "rds station too long '%s' (max %d characters)", value.c_str(), RDS_STATION_MAX);
|
||||
this->rds_station_.resize(RDS_STATION_MAX);
|
||||
}
|
||||
|
||||
this->publish_rds_station();
|
||||
}
|
||||
|
||||
void Si4713Component::set_rds_text(const std::string &value) {
|
||||
this->rds_text_ = value;
|
||||
this->rds_text_pos_ = 0;
|
||||
if (this->rds_text_.size() > RDS_TEXT_MAX) {
|
||||
ESP_LOGW(TAG, "rds text to long '%s' (max %d characters)", value.c_str(), RDS_TEXT_MAX);
|
||||
this->rds_text_.resize(RDS_TEXT_MAX);
|
||||
}
|
||||
|
||||
this->publish_rds_text();
|
||||
}
|
||||
|
||||
// publish
|
||||
|
||||
void Si4713Component::publish_() {
|
||||
// this->publish(this->_sensor_, this->state_.);
|
||||
}
|
||||
|
||||
void Si4713Component::publish_chip_id() { this->publish(this->chip_id_text_sensor_, this->chip_id_); }
|
||||
|
||||
void Si4713Component::publish_frequency() { this->publish(this->frequency_number_, this->get_frequency()); }
|
||||
|
||||
void Si4713Component::publish_mute() { this->publish(this->mute_switch_, this->get_mute()); }
|
||||
|
||||
void Si4713Component::publish_mono() { this->publish(this->mono_switch_, this->get_mono()); }
|
||||
|
||||
void Si4713Component::publish_rds_enable() { this->publish(this->rds_enable_switch_, this->get_rds_enable()); }
|
||||
|
||||
void Si4713Component::publish_rds_station() { this->publish(this->rds_station_text_, this->rds_station_); }
|
||||
|
||||
void Si4713Component::publish_rds_text() { this->publish(this->rds_text_text_, this->rds_text_); }
|
||||
|
||||
void Si4713Component::publish(text_sensor::TextSensor *s, const std::string &state) {
|
||||
if (s != nullptr) {
|
||||
if (!s->has_state() || s->state != state) {
|
||||
s->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Si4713Component::publish(sensor::Sensor *s, float state) {
|
||||
if (s != nullptr) {
|
||||
if (!s->has_state() || s->state != state) {
|
||||
s->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Si4713Component::publish(number::Number *n, float state) {
|
||||
if (n != nullptr) {
|
||||
if (!n->has_state() || n->state != state) {
|
||||
n->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Si4713Component::publish(switch_::Switch *s, bool state) {
|
||||
if (s != nullptr) {
|
||||
if (s->state != state) { // ?
|
||||
s->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Si4713Component::publish(select::Select *s, size_t index) {
|
||||
if (s != nullptr) {
|
||||
if (auto state = s->at(index)) {
|
||||
if (!s->has_state() || s->state != *state) {
|
||||
s->publish_state(*state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Si4713Component::publish(text::Text *t, const std::string &state) {
|
||||
if (t != nullptr) {
|
||||
if (!t->has_state() || t->state != state) {
|
||||
t->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
130
esphome/components/si4713_i2c/si4713.h
Normal file
130
esphome/components/si4713_i2c/si4713.h
Normal file
|
@ -0,0 +1,130 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/gpio.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "esphome/components/text/text.h"
|
||||
#include <string>
|
||||
#include "si4713defs.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
#ifndef SUB_TEXT
|
||||
#define SUB_TEXT(name) \
|
||||
protected: \
|
||||
text::Text *name##_text_{nullptr}; \
|
||||
\
|
||||
public: \
|
||||
void set_##name##_text(text::Text *text) { this->name##_text_ = text; }
|
||||
#endif
|
||||
|
||||
class Si4713Component : public PollingComponent, public i2c::I2CDevice {
|
||||
std::string chip_id_;
|
||||
InternalGPIOPin *reset_pin_;
|
||||
bool reset_;
|
||||
/*
|
||||
union {
|
||||
struct Si4713State state_;
|
||||
uint8_t regs_[sizeof(struct Si4713State)];
|
||||
};
|
||||
|
||||
void write_reg_(uint8_t addr);
|
||||
bool read_reg_(uint8_t addr);
|
||||
*/
|
||||
bool send_cmd(const void *cmd, size_t cmd_size, void *res, size_t res_size);
|
||||
|
||||
template<typename CMD> bool send_cmd(const CMD &cmd) {
|
||||
return this->send_cmd((const void *) &cmd, sizeof(cmd), nullptr, 0);
|
||||
}
|
||||
|
||||
template<typename CMD, typename RES> bool send_cmd(CMD cmd, RES &res) {
|
||||
return this->send_cmd((const void *) &cmd, sizeof(cmd), (void *) &res, sizeof(res));
|
||||
}
|
||||
|
||||
template<typename P> bool set_prop(P p) {
|
||||
CmdSetProperty cmd = CmdSetProperty(p.PROP, p.PROPD);
|
||||
return this->send_cmd(cmd);
|
||||
}
|
||||
|
||||
template<typename P> bool get_prop(P &p) {
|
||||
ResGetProperty res;
|
||||
if (this->send_cmd(CmdGetProperty(p.PROP), res)) {
|
||||
p.PROPD = ((uint16_t) res.PROPDH << 8) | res.PROPDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
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_text_;
|
||||
uint8_t rds_station_pos_;
|
||||
uint8_t rds_text_pos_;
|
||||
uint8_t rds_upd_;
|
||||
|
||||
void rds_update_();
|
||||
|
||||
SUB_TEXT_SENSOR(chip_id)
|
||||
// TODO: sensors TX_TUNE_STATUS / FREQ, RFuV, ANTCAP, NL
|
||||
// TODO: sensors TX_ASQ_STATUS / OVERMOD, IALH, IALL, INLEVEL
|
||||
SUB_NUMBER(frequency)
|
||||
SUB_SWITCH(mute)
|
||||
SUB_SWITCH(mono)
|
||||
SUB_SWITCH(rds_enable)
|
||||
SUB_TEXT(rds_station)
|
||||
SUB_TEXT(rds_text)
|
||||
// TODO: GPIO switches
|
||||
|
||||
void publish_();
|
||||
void publish_chip_id();
|
||||
void publish_frequency();
|
||||
void publish_mute();
|
||||
void publish_mono();
|
||||
void publish_rds_enable();
|
||||
void publish_rds_station();
|
||||
void publish_rds_text();
|
||||
void publish(sensor::Sensor *s, float state);
|
||||
void publish(text_sensor::TextSensor *s, const std::string &state);
|
||||
void publish(number::Number *n, float state);
|
||||
void publish(switch_::Switch *s, bool state);
|
||||
void publish(select::Select *s, size_t index);
|
||||
void publish(text::Text *t, const std::string &state);
|
||||
|
||||
public:
|
||||
Si4713Component();
|
||||
|
||||
// float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
void update() override;
|
||||
void loop() override;
|
||||
|
||||
void set_reset_pin(InternalGPIOPin *pin);
|
||||
void set_frequency(float value);
|
||||
float get_frequency();
|
||||
void set_mute(bool value);
|
||||
bool get_mute();
|
||||
void set_mono(bool value);
|
||||
bool get_mono();
|
||||
void set_rds_enable(bool value);
|
||||
bool get_rds_enable();
|
||||
void set_rds_station(const std::string &value);
|
||||
void set_rds_text(const std::string &value);
|
||||
};
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
1266
esphome/components/si4713_i2c/si4713defs.h
Normal file
1266
esphome/components/si4713_i2c/si4713defs.h
Normal file
File diff suppressed because it is too large
Load diff
61
esphome/components/si4713_i2c/switch/__init__.py
Normal file
61
esphome/components/si4713_i2c/switch/__init__.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import esphome.codegen as cg
|
||||
from esphome.components import switch
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
DEVICE_CLASS_SWITCH,
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
ICON_SECURITY,
|
||||
)
|
||||
from .. import (
|
||||
CONF_SI4713_ID,
|
||||
Si4713Component,
|
||||
si4713_ns,
|
||||
CONF_MUTE,
|
||||
CONF_MONO,
|
||||
CONF_RDS_ENABLE,
|
||||
ICON_VOLUME_MUTE,
|
||||
ICON_EAR_HEARING,
|
||||
ICON_FORMAT_TEXT,
|
||||
)
|
||||
|
||||
MuteSwitch = si4713_ns.class_("MuteSwitch", switch.Switch)
|
||||
MonoSwitch = si4713_ns.class_("MonoSwitch", switch.Switch)
|
||||
RDSEnableSwitch = si4713_ns.class_("RDSEnableSwitch", switch.Switch)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
||||
cv.Optional(CONF_MUTE): switch.switch_schema(
|
||||
MuteSwitch,
|
||||
device_class=DEVICE_CLASS_SWITCH,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_VOLUME_MUTE,
|
||||
),
|
||||
cv.Optional(CONF_MONO): switch.switch_schema(
|
||||
MonoSwitch,
|
||||
device_class=DEVICE_CLASS_SWITCH,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_EAR_HEARING,
|
||||
),
|
||||
cv.Optional(CONF_RDS_ENABLE): switch.switch_schema(
|
||||
RDSEnableSwitch,
|
||||
device_class=DEVICE_CLASS_SWITCH,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_FORMAT_TEXT,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def new_switch(config, id, setter):
|
||||
if c := config.get(id):
|
||||
s = await switch.new_switch(c)
|
||||
await cg.register_parented(s, config[CONF_SI4713_ID])
|
||||
cg.add(setter(s))
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
c = await cg.get_variable(config[CONF_SI4713_ID])
|
||||
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_RDS_ENABLE, c.set_rds_enable_switch)
|
12
esphome/components/si4713_i2c/switch/mono_switch.cpp
Normal file
12
esphome/components/si4713_i2c/switch/mono_switch.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "mono_switch.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
void MonoSwitch::write_state(bool value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_mono(value);
|
||||
}
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
18
esphome/components/si4713_i2c/switch/mono_switch.h
Normal file
18
esphome/components/si4713_i2c/switch/mono_switch.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "../si4713.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
class MonoSwitch : public switch_::Switch, public Parented<Si4713Component> {
|
||||
public:
|
||||
MonoSwitch() = default;
|
||||
|
||||
protected:
|
||||
void write_state(bool value) override;
|
||||
};
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
12
esphome/components/si4713_i2c/switch/mute_switch.cpp
Normal file
12
esphome/components/si4713_i2c/switch/mute_switch.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "mute_switch.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
void MuteSwitch::write_state(bool value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_mute(value);
|
||||
}
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
18
esphome/components/si4713_i2c/switch/mute_switch.h
Normal file
18
esphome/components/si4713_i2c/switch/mute_switch.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "../si4713.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
class MuteSwitch : public switch_::Switch, public Parented<Si4713Component> {
|
||||
public:
|
||||
MuteSwitch() = default;
|
||||
|
||||
protected:
|
||||
void write_state(bool value) override;
|
||||
};
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
12
esphome/components/si4713_i2c/switch/rds_enable_switch.cpp
Normal file
12
esphome/components/si4713_i2c/switch/rds_enable_switch.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "rds_enable_switch.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
void RDSEnableSwitch::write_state(bool value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_rds_enable(value);
|
||||
}
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
18
esphome/components/si4713_i2c/switch/rds_enable_switch.h
Normal file
18
esphome/components/si4713_i2c/switch/rds_enable_switch.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "../si4713.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
class RDSEnableSwitch : public switch_::Switch, public Parented<Si4713Component> {
|
||||
public:
|
||||
RDSEnableSwitch() = default;
|
||||
|
||||
protected:
|
||||
void write_state(bool value) override;
|
||||
};
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
154
esphome/components/si4713_i2c/text/__init__.py
Normal file
154
esphome/components/si4713_i2c/text/__init__.py
Normal file
|
@ -0,0 +1,154 @@
|
|||
from typing import Optional
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import text
|
||||
from esphome.components import mqtt, web_server
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_ENTITY_CATEGORY,
|
||||
CONF_ICON,
|
||||
CONF_MQTT_ID,
|
||||
CONF_WEB_SERVER,
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
from esphome.cpp_generator import MockObjClass
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
from .. import (
|
||||
CONF_SI4713_ID,
|
||||
Si4713Component,
|
||||
si4713_ns,
|
||||
CONF_RDS_STATION,
|
||||
CONF_RDS_TEXT,
|
||||
ICON_FORMAT_TEXT,
|
||||
)
|
||||
|
||||
RDSStationText = si4713_ns.class_("RDSStationText", text.Text)
|
||||
RDSTextText = si4713_ns.class_("RDSTextText", text.Text)
|
||||
|
||||
# The text component isn't implemented the same way as switch, select, number.
|
||||
# It is not possible to create our own text platform as it is now, so I adopted
|
||||
# the necessary code from those.
|
||||
|
||||
_TEXT_SCHEMA = (
|
||||
cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
|
||||
.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA)
|
||||
.extend(
|
||||
{
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTTextComponent),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
_UNDEF = object()
|
||||
|
||||
|
||||
def text_schema(
|
||||
class_: MockObjClass = _UNDEF,
|
||||
*,
|
||||
entity_category: str = _UNDEF,
|
||||
device_class: str = _UNDEF,
|
||||
icon: str = _UNDEF,
|
||||
):
|
||||
schema = _TEXT_SCHEMA
|
||||
if class_ is not _UNDEF:
|
||||
schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)})
|
||||
if entity_category is not _UNDEF:
|
||||
schema = schema.extend(
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_ENTITY_CATEGORY, default=entity_category
|
||||
): cv.entity_category
|
||||
}
|
||||
)
|
||||
if icon is not _UNDEF:
|
||||
schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon})
|
||||
return schema
|
||||
|
||||
|
||||
TEXT_SCHEMA = text_schema() # for compatibility
|
||||
|
||||
|
||||
async def setup_text_core_(
|
||||
var,
|
||||
config,
|
||||
*,
|
||||
min_length: Optional[int],
|
||||
max_length: Optional[int],
|
||||
pattern: Optional[str],
|
||||
):
|
||||
await setup_entity(var, config)
|
||||
cg.add(var.traits.set_min_length(min_length))
|
||||
cg.add(var.traits.set_max_length(max_length))
|
||||
if pattern is not None:
|
||||
cg.add(var.traits.set_pattern(pattern))
|
||||
|
||||
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
|
||||
mqtt_ = cg.new_Pvariable(mqtt_id, var)
|
||||
await mqtt.register_mqtt_component(mqtt_, config)
|
||||
|
||||
if web_server_config := config.get(CONF_WEB_SERVER):
|
||||
await web_server.add_entity_config(var, web_server_config)
|
||||
|
||||
|
||||
async def register_text(
|
||||
var,
|
||||
config,
|
||||
min_length: Optional[int] = 0,
|
||||
max_length: Optional[int] = 255,
|
||||
pattern: Optional[str] = None,
|
||||
):
|
||||
if not CORE.has_id(config[CONF_ID]):
|
||||
var = cg.Pvariable(config[CONF_ID], var)
|
||||
cg.add(cg.App.register_text(var))
|
||||
await setup_text_core_(
|
||||
var, config, min_length=min_length, max_length=max_length, pattern=pattern
|
||||
)
|
||||
|
||||
|
||||
async def new_text(
|
||||
config,
|
||||
*args,
|
||||
min_length: Optional[int] = 0,
|
||||
max_length: Optional[int] = 255,
|
||||
pattern: Optional[str] = None,
|
||||
):
|
||||
var = cg.new_Pvariable(config[CONF_ID], *args)
|
||||
await register_text(
|
||||
var, config, min_length=min_length, max_length=max_length, pattern=pattern
|
||||
)
|
||||
return var
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
||||
cv.Optional(CONF_RDS_STATION): text_schema(
|
||||
RDSStationText,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_FORMAT_TEXT,
|
||||
),
|
||||
cv.Optional(CONF_RDS_TEXT): text_schema(
|
||||
RDSTextText,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
icon=ICON_FORMAT_TEXT,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def new_text_simple(config, id, setter, min_length, max_length, *args):
|
||||
if c := config.get(id):
|
||||
t = await new_text(c, *args, min_length=min_length, max_length=max_length)
|
||||
await cg.register_parented(t, config[CONF_SI4713_ID])
|
||||
cg.add(setter(t))
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
c = await cg.get_variable(config[CONF_SI4713_ID])
|
||||
await new_text_simple(
|
||||
config, CONF_RDS_STATION, c.set_rds_station_text, 0, si4713_ns.RDS_STATION_MAX
|
||||
)
|
||||
await new_text_simple(
|
||||
config, CONF_RDS_TEXT, c.set_rds_text_text, 0, si4713_ns.RDS_TEXT_MAX
|
||||
)
|
12
esphome/components/si4713_i2c/text/rds_station_text.cpp
Normal file
12
esphome/components/si4713_i2c/text/rds_station_text.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "rds_station_text.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
void RDSStationText::control(const std::string &value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_rds_station(value);
|
||||
}
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
18
esphome/components/si4713_i2c/text/rds_station_text.h
Normal file
18
esphome/components/si4713_i2c/text/rds_station_text.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/text/text.h"
|
||||
#include "../si4713.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
class RDSStationText : public text::Text, public Parented<Si4713Component> {
|
||||
public:
|
||||
RDSStationText() = default;
|
||||
|
||||
protected:
|
||||
void control(const std::string &value) override;
|
||||
};
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
12
esphome/components/si4713_i2c/text/rds_text_text.cpp
Normal file
12
esphome/components/si4713_i2c/text/rds_text_text.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "rds_text_text.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
void RDSTextText::control(const std::string &value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_rds_text(value);
|
||||
}
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
18
esphome/components/si4713_i2c/text/rds_text_text.h
Normal file
18
esphome/components/si4713_i2c/text/rds_text_text.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/text/text.h"
|
||||
#include "../si4713.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace si4713 {
|
||||
|
||||
class RDSTextText : public text::Text, public Parented<Si4713Component> {
|
||||
public:
|
||||
RDSTextText() = default;
|
||||
|
||||
protected:
|
||||
void control(const std::string &value) override;
|
||||
};
|
||||
|
||||
} // namespace si4713
|
||||
} // namespace esphome
|
Loading…
Reference in a new issue