almost complete implementation of every feature, only a few left

This commit is contained in:
Gábor Poczkodi 2024-10-13 00:27:41 +02:00
parent 84d4372c36
commit b04e54dcd9
60 changed files with 2319 additions and 67 deletions

View file

@ -15,7 +15,7 @@ AUTO_LOAD = ["sensor", "text_sensor", "binary_sensor", "number", "switch", "sele
MULTI_CONF = True
UNIT_MEGA_HERTZ = "MHz"
UNIT_KILO_HERTZ = "KHz"
UNIT_KILO_HERTZ = "kHz"
UNIT_MILLI_VOLT = "mV"
UNIT_MICRO_AMPERE = "mA"
UNIT_DECIBEL_MICRO_VOLT = "dBµV"
@ -27,6 +27,7 @@ ICON_SLEEP = "mdi:sleep"
ICON_SINE_WAVE = "mdi:sine-wave"
ICON_RESISTOR = "mdi:resistor"
ICON_FORMAT_TEXT = "mdi:format-text"
ICON_SPEAKER = "mdi:speaker"
kt0803_ns = cg.esphome_ns.namespace("kt0803")
KT0803Component = kt0803_ns.class_(
@ -37,6 +38,32 @@ CONF_KT0803_ID = "kt0803_id"
CONF_CHIP_ID = "chip_id"
CONF_PW_OK = "pw_ok"
CONF_SLNCID = "slncid"
CONF_PGA = "pga"
CONF_RFGAIN = "rfgain"
CONF_MUTE = "mute"
CONF_MONO = "mono"
CONF_PRE_EMPHASIS = "pre_emphasis"
CONF_PILOT_TONE_AMPLITUDE = "pilot_tone_amplitude"
CONF_BASS_BOOST_CONTROL = "bass_boost_control"
CONF_ALC_ENABLE = "alc_enable"
CONF_AUTO_PA_DOWN = "auto_pa_down"
CONF_PA_DOWN = "pa_down"
CONF_STANDBY_ENABLE = "standby_enable"
CONF_ALC_ATTACK_TIME = "alc_attack_time"
CONF_ALC_DECAY_TIME = "alc_decay_time"
CONF_PA_BIAS = "pa_bias"
CONF_AUDIO_LIMITER_LEVEL = "audio_limiter_level"
CONF_SWITCH_MODE = "switch_mode"
CONF_SILENCE_HIGH = "silence_high"
CONF_SILENCE_LOW = "silence_low"
CONF_SILENCE_DETECTION = "silence_detection"
CONF_SILENCE_DURATION = "silence_duration"
CONF_SILENCE_HIGH_COUNTER = "silence_high_counter"
CONF_SILENCE_LOW_COUNTER = "silence_low_counter"
CONF_ALC_GAIN = "alc_gain"
CONF_XTAL_SEL = "xtal_sel"
CONF_AU_ENHANCE = "au_enhance"
CONF_FREQUENCY_DEVIATION = "frequency_deviation"
SetFrequencyAction = kt0803_ns.class_(
"SetFrequencyAction", automation.Action, cg.Parented.template(KT0803Component)
@ -50,12 +77,239 @@ CHIP_ID = {
"KT0803L": ChipId.KT0803L,
}
PreEmphasis = kt0803_ns.enum("PreEmphasis", True)
PRE_EMPHASIS = {
"50us": PreEmphasis.PHTCNST_50US,
"75us": PreEmphasis.PHTCNST_75US,
}
PilotToneAmplitude = kt0803_ns.enum("PilotToneAmplitude", True)
PILOT_TONE_AMPLITUDE = {
"Low": PilotToneAmplitude.PLTADJ_LOW,
"High": PilotToneAmplitude.PLTADJ_HIGH,
}
BassBoostControl = kt0803_ns.enum("BassBoostControl", True)
BASS_BOOST_CONTROL = {
"Disabled": BassBoostControl.BASS_DISABLED,
"5dB": BassBoostControl.BASS_5DB,
"11dB": BassBoostControl.BASS_11DB,
"17dB": BassBoostControl.BASS_17DB,
}
AlcTime = kt0803_ns.enum("AlcTime", True)
ALC_TIME = {
"25us": AlcTime.ALC_TIME_25US,
"50us": AlcTime.ALC_TIME_50US,
"75us": AlcTime.ALC_TIME_75US,
"100us": AlcTime.ALC_TIME_100US,
"125us": AlcTime.ALC_TIME_125US,
"150us": AlcTime.ALC_TIME_150US,
"175us": AlcTime.ALC_TIME_175US,
"200us": AlcTime.ALC_TIME_200US,
"50ms": AlcTime.ALC_TIME_50MS,
"100ms": AlcTime.ALC_TIME_100MS,
"150ms": AlcTime.ALC_TIME_150MS,
"200ms": AlcTime.ALC_TIME_200MS,
"250ms": AlcTime.ALC_TIME_250MS,
"300ms": AlcTime.ALC_TIME_300MS,
"350ms": AlcTime.ALC_TIME_350MS,
"40ms": AlcTime.ALC_TIME_40MS,
}
SwitchMode = kt0803_ns.enum("SwitchMode", True)
SWITCH_MODE = {
"Mute": SwitchMode.SW_MOD_MUTE,
"PA Off": SwitchMode.SW_MOD_PA_OFF,
}
SilenceHigh = kt0803_ns.enum("SilenceHigh", True)
SILENCE_HIGH = {
"0.5mV": SilenceHigh.SLNCTHH_0M5V,
"1mV": SilenceHigh.SLNCTHH_1MV,
"2mV": SilenceHigh.SLNCTHH_2MV,
"4mV": SilenceHigh.SLNCTHH_4MV,
"8mV": SilenceHigh.SLNCTHH_8MV,
"16mV": SilenceHigh.SLNCTHH_16MV,
"32mV": SilenceHigh.SLNCTHH_32MV,
"64mV": SilenceHigh.SLNCTHH_64MV,
}
SilenceLow = kt0803_ns.enum("SilenceLow", True)
SILENCE_LOW = {
"0.25mV": SilenceLow.SLNCTHL_0M25V,
"0.5mV": SilenceLow.SLNCTHL_0M5V,
"1mV": SilenceLow.SLNCTHL_1MV,
"2mV": SilenceLow.SLNCTHL_2MV,
"4mV": SilenceLow.SLNCTHL_4MV,
"8mV": SilenceLow.SLNCTHL_8MV,
"16mV": SilenceLow.SLNCTHL_16MV,
"32mV": SilenceLow.SLNCTHL_32MV,
}
SilenceLowAndHighLevelDurationTime = kt0803_ns.enum("SilenceLowAndHighLevelDurationTime", True)
SILENCE_LOW_AND_HIGH_LEVEL_DURATION_TIME = {
"50ms": SilenceLowAndHighLevelDurationTime.SLNCTIME_50MS,
"100ms": SilenceLowAndHighLevelDurationTime.SLNCTIME_100MS,
"200ms": SilenceLowAndHighLevelDurationTime.SLNCTIME_200MS,
"400ms": SilenceLowAndHighLevelDurationTime.SLNCTIME_400MS,
"1s": SilenceLowAndHighLevelDurationTime.SLNCTIME_1S,
"2s": SilenceLowAndHighLevelDurationTime.SLNCTIME_2S,
"4s": SilenceLowAndHighLevelDurationTime.SLNCTIME_4S,
"8s": SilenceLowAndHighLevelDurationTime.SLNCTIME_8S,
"16s": SilenceLowAndHighLevelDurationTime.SLNCTIME_16S,
"24s": SilenceLowAndHighLevelDurationTime.SLNCTIME_24S,
"32s": SilenceLowAndHighLevelDurationTime.SLNCTIME_32S,
"40s": SilenceLowAndHighLevelDurationTime.SLNCTIME_40S,
"48s": SilenceLowAndHighLevelDurationTime.SLNCTIME_48S,
"56s": SilenceLowAndHighLevelDurationTime.SLNCTIME_56S,
"60s": SilenceLowAndHighLevelDurationTime.SLNCTIME_60S,
"64s": SilenceLowAndHighLevelDurationTime.SLNCTIME_64S,
}
SilenceHighLevelCounter = kt0803_ns.enum("SilenceHighLevelCounter", True)
SILENCE_HIGH_LEVEL_COUNTER = {
"15": SilenceHighLevelCounter.SLNCCNTHIGH_15,
"31": SilenceHighLevelCounter.SLNCCNTHIGH_31,
"63": SilenceHighLevelCounter.SLNCCNTHIGH_63,
"127": SilenceHighLevelCounter.SLNCCNTHIGH_127,
"255": SilenceHighLevelCounter.SLNCCNTHIGH_255,
"511": SilenceHighLevelCounter.SLNCCNTHIGH_511,
"1023": SilenceHighLevelCounter.SLNCCNTHIGH_1023,
"2047": SilenceHighLevelCounter.SLNCCNTHIGH_2047,
}
AlcCompressedGain = kt0803_ns.enum("AlcCompressedGain", True)
ALC_COMPRESSED_GAIN = {
"-6dB": AlcCompressedGain.ALCCMPGAIN_N6DB,
"-9dB": AlcCompressedGain.ALCCMPGAIN_N9DB,
"-12dB": AlcCompressedGain.ALCCMPGAIN_N12DB,
"-15dB": AlcCompressedGain.ALCCMPGAIN_N15DB,
"6dB": AlcCompressedGain.ALCCMPGAIN_6DB,
"3dB": AlcCompressedGain.ALCCMPGAIN_3DB,
"0dB": AlcCompressedGain.ALCCMPGAIN_0DB,
"-3dB": AlcCompressedGain.ALCCMPGAIN_N3DB,
}
SilenceLowLevelCounter = kt0803_ns.enum("SilenceLowLevelCounter", True)
SILENCE_LOW_LEVEL_COUNTER = {
"1": SilenceLowLevelCounter.SLNCCNTLOW_1,
"2": SilenceLowLevelCounter.SLNCCNTLOW_2,
"4": SilenceLowLevelCounter.SLNCCNTLOW_4,
"8": SilenceLowLevelCounter.SLNCCNTLOW_8,
"16": SilenceLowLevelCounter.SLNCCNTLOW_16,
"32": SilenceLowLevelCounter.SLNCCNTLOW_32,
"64": SilenceLowLevelCounter.SLNCCNTLOW_64,
"128": SilenceLowLevelCounter.SLNCCNTLOW_128,
}
XtalSel = kt0803_ns.enum("XtalSel", True)
XTAL_SEL = {
"32.768kHz": XtalSel.XTAL_SEL_32K768HZ,
"7.6MHz": XtalSel.XTAL_SEL_7M6HZ,
}
FrequencyDeviation = kt0803_ns.enum("FrequencyDeviation", True)
FREQUENCY_DEVIATION = {
"75kHz": FrequencyDeviation.FDEV_75KHZ,
"112.5kHz": FrequencyDeviation.FDEV_112K5HZ,
"150kHz": FrequencyDeviation.FDEV_150KHZ,
"187.5kHz": FrequencyDeviation.FDEV_187K5HZ,
}
ReferenceClock = kt0803_ns.enum("ReferenceClock", True)
REFERENCE_CLOCK = {
"32.768kHz": ReferenceClock.REF_CLK_32K768HZ,
"6.5MHz": ReferenceClock.REF_CLK_6M5HZ,
"7.6MHz": ReferenceClock.REF_CLK_7M6HZ,
"12MHz": ReferenceClock.REF_CLK_12MHZ,
"13MHz": ReferenceClock.REF_CLK_13MHZ,
"15.2MHz": ReferenceClock.REF_CLK_15M2HZ,
"19.2MHz": ReferenceClock.REF_CLK_19M2HZ,
"24MHz": ReferenceClock.REF_CLK_24MHZ,
"26MHz": ReferenceClock.REF_CLK_26MHZ,
}
AlcHigh = kt0803_ns.enum("AlcHigh", True)
ALC_HIGH_THRESHOLD_SELECTION = {
"50ms": AlcHigh.ALCHIGHTH_50MS,
"100ms": AlcHigh.ALCHIGHTH_100MS,
"150ms": AlcHigh.ALCHIGHTH_150MS,
"200ms": AlcHigh.ALCHIGHTH_200MS,
"1s": AlcHigh.ALCHIGHTH_1S,
"5s": AlcHigh.ALCHIGHTH_5S,
"10s": AlcHigh.ALCHIGHTH_10S,
"15s": AlcHigh.ALCHIGHTH_15S,
}
AlcHoldTime = kt0803_ns.enum("AlcHoldTime", True)
ALC_HOLD_TIME = {
"0.6": AlcHoldTime.ALCHOLD_06,
"0.5": AlcHoldTime.ALCHOLD_05,
"0.4": AlcHoldTime.ALCHOLD_04,
"0.3": AlcHoldTime.ALCHOLD_03,
"0.2": AlcHoldTime.ALCHOLD_02,
"0.1": AlcHoldTime.ALCHOLD_01,
"0.05": AlcHoldTime.ALCHOLD_005,
"0.01": AlcHoldTime.ALCHOLD_001,
}
AlcLow = kt0803_ns.enum("AlcLow", True)
ALC_LOW = {
"0.25": AlcLow.ALCLOWTH_025,
"0.20": AlcLow.ALCLOWTH_020,
"0.15": AlcLow.ALCLOWTH_015,
"0.10": AlcLow.ALCLOWTH_010,
"0.05": AlcLow.ALCLOWTH_005,
"0.03": AlcLow.ALCLOWTH_003,
"0.02": AlcLow.ALCLOWTH_002,
"0.01": AlcLow.ALCLOWTH_001,
"0.005": AlcLow.ALCLOWTH_0005,
"0.001": AlcLow.ALCLOWTH_0001,
"0.0005": AlcLow.ALCLOWTH_00005,
"0.0001": AlcLow.ALCLOWTH_00001,
}
AudioLimiterLevel = kt0803_ns.enum("AudioLimiterLevel", True)
AUDIO_LIMITER_LEVEL = {
"0.6875": AudioLimiterLevel.LMTLVL_06875,
"0.75": AudioLimiterLevel.LMTLVL_07500,
"0.875": AudioLimiterLevel.LMTLVL_08750,
"0.9625": AudioLimiterLevel.LMTLVL_09625,
}
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(KT0803Component),
cv.Required(CONF_CHIP_ID): cv.enum(CHIP_ID),
cv.Optional(CONF_FREQUENCY, default=87.50): cv.float_range(70, 108),
cv.Optional(CONF_PGA, default=-15): cv.float_range(-15, 12),
cv.Optional(CONF_RFGAIN, default=108): cv.float_range(95.5, 108),
cv.Optional(CONF_MUTE, default=False): cv.boolean,
cv.Optional(CONF_MONO, default=False): cv.boolean,
cv.Optional(CONF_PRE_EMPHASIS, default="75us"): cv.enum(PRE_EMPHASIS),
cv.Optional(CONF_PILOT_TONE_AMPLITUDE, default="LOW"): cv.enum(PILOT_TONE_AMPLITUDE),
cv.Optional(CONF_BASS_BOOST_CONTROL, default="Disabled"): cv.enum(BASS_BOOST_CONTROL),
cv.Optional(CONF_ALC_ENABLE, default=False): cv.boolean,
cv.Optional(CONF_AUTO_PA_DOWN, default=True): cv.boolean,
cv.Optional(CONF_PA_DOWN, default=False): cv.boolean,
cv.Optional(CONF_STANDBY_ENABLE, default=False): cv.boolean,
cv.Optional(CONF_ALC_ATTACK_TIME, default="25us"): cv.enum(ALC_TIME),
cv.Optional(CONF_ALC_DECAY_TIME, default="25us"): cv.enum(ALC_TIME),
cv.Optional(CONF_PA_BIAS, default=False): cv.boolean,
cv.Optional(CONF_AUDIO_LIMITER_LEVEL, default="0.875"): cv.enum(AUDIO_LIMITER_LEVEL),
cv.Optional(CONF_SWITCH_MODE, default="Mute"): cv.enum(SWITCH_MODE),
cv.Optional(CONF_SILENCE_HIGH, default="32mV"): cv.enum(SILENCE_HIGH),
cv.Optional(CONF_SILENCE_LOW, default="8mV"): cv.enum(SILENCE_LOW),
cv.Optional(CONF_SILENCE_DETECTION, default=False): cv.boolean,
cv.Optional(CONF_SILENCE_DURATION, default="100ms"): cv.enum(SILENCE_LOW_AND_HIGH_LEVEL_DURATION_TIME),
cv.Optional(CONF_SILENCE_HIGH_COUNTER, default='15'): cv.enum(SILENCE_HIGH_LEVEL_COUNTER),
cv.Optional(CONF_SILENCE_LOW_COUNTER, default='1'): cv.enum(SILENCE_LOW_LEVEL_COUNTER),
cv.Optional(CONF_ALC_GAIN, default=-3): cv.float_range(-15, 6),
cv.Optional(CONF_XTAL_SEL, default="32.768kHz"): cv.enum(XTAL_SEL),
cv.Optional(CONF_AU_ENHANCE, default=False): cv.boolean,
cv.Optional(CONF_FREQUENCY_DEVIATION, default="75kHz"): cv.enum(FREQUENCY_DEVIATION),
cv.Optional(CONF_PW_OK): binary_sensor.binary_sensor_schema(
device_class=DEVICE_CLASS_POWER,
icon=ICON_RADIO_TOWER,
@ -71,16 +325,48 @@ CONFIG_SCHEMA = (
)
async def set_var(config, id, setter):
if c := config.get(id):
cg.add(setter(c))
async def set_binary_sensor(config, id, setter):
if c := config.get(id):
s = await binary_sensor.new_binary_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)
cg.add(var.set_chip_id(config.get(CONF_CHIP_ID)))
if conf_frequency := config.get(CONF_FREQUENCY):
cg.add(var.set_frequency(conf_frequency))
if conf_pw_ok := config.get(CONF_PW_OK):
s = await binary_sensor.new_binary_sensor(conf_pw_ok)
cg.add(var.set_pw_ok_binary_sensor(s))
if conf_slncid := config.get(CONF_SLNCID):
s = await binary_sensor.new_binary_sensor(conf_slncid)
cg.add(var.set_slncid_binary_sensor(s))
await set_var(config, CONF_CHIP_ID, var.set_chip_id)
await set_var(config, CONF_FREQUENCY, var.set_frequency)
await set_var(config, CONF_PGA, var.set_pga)
await set_var(config, CONF_RFGAIN, var.set_rfgain)
await set_var(config, CONF_MUTE, var.set_mute)
await set_var(config, CONF_MONO, var.set_mono)
await set_var(config, CONF_PRE_EMPHASIS, var.set_pre_emphasis)
await set_var(config, CONF_PILOT_TONE_AMPLITUDE, var.set_pilot_tone_amplitude)
await set_var(config, CONF_BASS_BOOST_CONTROL, var.set_bass_boost_control)
await set_var(config, CONF_ALC_ENABLE, var.set_alc_enable)
await set_var(config, CONF_AUTO_PA_DOWN, var.set_auto_pa_down)
await set_var(config, CONF_PA_DOWN, var.set_pa_down)
await set_var(config, CONF_STANDBY_ENABLE, var.set_standby_enable)
await set_var(config, CONF_ALC_ATTACK_TIME, var.set_alc_attack_time)
await set_var(config, CONF_ALC_DECAY_TIME, var.set_alc_decay_time)
await set_var(config, CONF_PA_BIAS, var.set_pa_bias)
await set_var(config, CONF_AUDIO_LIMITER_LEVEL, var.set_audio_limiter_level)
await set_var(config, CONF_SWITCH_MODE, var.set_switch_mode)
await set_var(config, CONF_SILENCE_HIGH, var.set_silence_high)
await set_var(config, CONF_SILENCE_LOW, var.set_silence_low)
await set_var(config, CONF_SILENCE_DETECTION, var.set_silence_detection)
await set_var(config, CONF_SILENCE_DURATION, var.set_silence_duration)
await set_var(config, CONF_SILENCE_HIGH_COUNTER, var.set_silence_high_counter)
await set_var(config, CONF_SILENCE_LOW_COUNTER, var.set_silence_low_counter)
await set_var(config, CONF_ALC_GAIN, var.set_alc_gain)
await set_var(config, CONF_XTAL_SEL, var.set_xtal_sel)
await set_var(config, CONF_AU_ENHANCE, var.set_au_enhance)
await set_var(config, CONF_FREQUENCY_DEVIATION, var.set_frequency_deviation)
await set_binary_sensor(config, CONF_PW_OK, var.set_pw_ok_binary_sensor)
await set_binary_sensor(config, CONF_SLNCID, var.set_slncid_binary_sensor)

View file

@ -7,6 +7,8 @@
namespace esphome {
namespace kt0803 {
#define countof(s) sizeof(s) / sizeof(s[0])
// TODO: std::clamp isn't here yet
#define clamp(v, lo, hi) std::max(std::min(v, hi), lo)
@ -57,6 +59,8 @@ bool KT0803Component::check_reg_(uint8_t addr) {
if (this->chip_id_ == ChipId::KT0803L) {
switch (addr) { // check KT0803L address range too
case 0x0C:
case 0x15:
case 0x17:
case 0x1E:
case 0x26:
@ -117,9 +121,12 @@ void KT0803Component::setup() {
}
}
*/
this->reset_ = true;
if (this->chip_id_ != ChipId::KT0803) {
this->state_.PGAMOD = 1; // enable 1dB resolution for PGA
}
for (size_t addr = 0; addr < sizeof(this->state_); addr++) {
if (addr != 0x0F && this->check_reg_(addr)) {
this->write_reg_(addr);
@ -129,6 +136,32 @@ void KT0803Component::setup() {
this->publish_pw_ok();
this->publish_slncid();
this->publish_frequency();
this->publish_pga();
this->publish_rfgain();
this->publish_mute();
this->publish_mono();
this->publish_pre_emphasis();
this->publish_pilot_tone_amplitude();
this->publish_bass_boost_control();
this->publish_alc_enable();
this->publish_auto_pa_down();
this->publish_pa_down();
this->publish_standby_enable();
this->publish_alc_attack_time();
this->publish_alc_decay_time();
this->publish_pa_bias();
this->publish_audio_limiter_level();
this->publish_switch_mode();
this->publish_silence_high();
this->publish_silence_low();
this->publish_silence_detection();
this->publish_silence_duration();
this->publish_silence_high_counter();
this->publish_silence_low_counter();
this->publish_alc_gain();
this->publish_xtal_sel();
this->publish_au_enhance();
this->publish_frequency_deviation();
}
void KT0803Component::dump_config() {
@ -204,12 +237,485 @@ float KT0803Component::get_frequency() {
uint16_t ch = 0;
ch |= (uint16_t) this->state_.CHSEL2 << 9;
ch |= (uint16_t) this->state_.CHSEL1 << 1;
if (this->chip_id_ != ChipId::KT0803) {
ch |= (uint16_t) this->state_.CHSEL0 << 0;
}
ch |= (uint16_t) this->state_.CHSEL0 << 0;
return (float) ch / 20;
}
void KT0803Component::set_pga(float value) {
if (!(PGA_MIN <= value && value <= PGA_MAX)) {
ESP_LOGE(TAG, "set_pga(%.2f) invalid (%.2f - %.2f)", value, PGA_MIN, PGA_MAX);
return;
}
/*
12 01100 => 11111 31
11 01011 => 11110 30
10 01010 => 11101 29
9 01001 => 11100 28
8 01000 => 11011 27
7 00111 => 11010 26
6 00110 => 11001 25
5 00101 => 11000 24
4 00100 => 10111 23
3 00011 => 10110 22
2 00010 => 10101 21
1 00001 => 10100 20
0 00000 => 10011 19
0 00000 => 10010 18
0 00000 => 10001 17
0 00000 => 10000 16
0 00000 => 00000 0
-1 11111 => 00001 1
-2 11110 => 00010 2
-3 11101 => 00011 3
-4 11100 => 00100 4
-5 11011 => 00101 5
-6 11010 => 00110 6
-7 11001 => 00111 7
-8 11000 => 01000 8
-9 10111 => 01001 9
-10 10110 => 01010 10
-11 10101 => 01011 11
-12 10100 => 01100 12
-13 10011 => 01101 13
-14 10010 => 01110 14
-15 10001 => 01111 15
*/
long pga = lround(value);
if (pga > 0) {
pga += 19;
} else if (pga < 0) {
pga = -pga;
}
this->state_.PGA = pga >> 2;
this->state_.PGA_LSB = pga & 3;
this->write_reg_(0x01);
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x04);
}
this->publish_pga();
}
float KT0803Component::get_pga() {
int pga = (int) ((this->state_.PGA << 2) | this->state_.PGA_LSB);
if (pga >= 20) {
pga -= 19;
} else if (0 < pga && pga <= 15) {
pga = -pga;
} else
pga = 0;
return (float) pga;
}
static const uint16_t RfGainMap[] = {
955, 965, 975, 982, 989, 1000, 1015, 1028, 1051, 1056, 1062, 1065, 1070, 1074, 1077, 1080,
};
void KT0803Component::set_rfgain(float value) {
if (!(RFGAIN_MIN <= value && value <= RFGAIN_MAX)) {
ESP_LOGE(TAG, "set_rfgain(%.2f) invalid (%.2f - %.2f)", value, RFGAIN_MIN, RFGAIN_MAX);
return;
}
long v = std::lround(value * 10);
for (size_t i = 0; i < countof(RfGainMap); i++) {
if (v <= RfGainMap[i]) {
this->state_.RFGAIN0 = (i >> 0) & 3;
this->state_.RFGAIN1 = (i >> 2) & 1;
this->state_.RFGAIN2 = (i >> 3) & 1;
break;
}
}
// TODO: there is an annoying hiss during this, mute/unmute does nothing
// maybe write all three registers in one go
this->write_reg_(0x00);
this->write_reg_(0x01);
this->write_reg_(0x13);
this->publish_rfgain();
}
float KT0803Component::get_rfgain() {
uint8_t i = (this->state_.RFGAIN2 << 3) | (this->state_.RFGAIN1 << 2) | this->state_.RFGAIN0;
return (float) RfGainMap[i] / 10;
}
void KT0803Component::set_mute(bool value) {
this->state_.MUTE = value ? 1 : 0;
this->write_reg_(0x02);
this->publish_mute();
}
bool KT0803Component::get_mute() { return this->state_.MUTE == 1; }
void KT0803Component::set_mono(bool value) {
this->state_.MONO = value ? 1 : 0;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x04);
}
this->publish_mono();
}
bool KT0803Component::get_mono() { return this->state_.MONO == 1; }
void KT0803Component::set_pre_emphasis(PreEmphasis value) {
if (value >= PreEmphasis::LAST) {
ESP_LOGE(TAG, "set_pre_emphasis(%d) invalid (50 or 75)", (int) value);
return;
}
this->state_.PHTCNST = (uint8_t) value;
this->write_reg_(0x02);
this->publish_pre_emphasis();
}
PreEmphasis KT0803Component::get_pre_emphasis() { return (PreEmphasis) this->state_.PHTCNST; }
void KT0803Component::set_pilot_tone_amplitude(PilotToneAmplitude value) {
if (value >= PilotToneAmplitude::LAST) {
ESP_LOGE(TAG, "PilotToneAmplitude(%d) invalid (LOW or HIGH)", (int) value);
return;
}
this->state_.PLTADJ = (uint8_t) value;
this->write_reg_(0x02);
this->publish_pilot_tone_amplitude();
}
PilotToneAmplitude KT0803Component::get_pilot_tone_amplitude() { return (PilotToneAmplitude) this->state_.PLTADJ; }
void KT0803Component::set_bass_boost_control(BassBoostControl value) {
if (value >= BassBoostControl::LAST) {
ESP_LOGE(TAG, "set_bass(%d) invalid", (int) value);
return;
}
this->state_.BASS = (uint8_t) value;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x04);
}
this->publish_bass_boost_control();
}
BassBoostControl KT0803Component::get_bass_boost_control() { return (BassBoostControl) this->state_.BASS; }
void KT0803Component::set_alc_enable(bool value) {
this->state_.ALC_EN = value ? 1 : 0;
if (this->chip_id_ == ChipId::KT0803L) {
this->write_reg_(0x04);
}
this->publish_alc_enable();
}
bool KT0803Component::get_alc_enable() { return this->state_.ALC_EN == 1; }
void KT0803Component::set_auto_pa_down(bool value) {
this->state_.AUTO_PADN = value ? 1 : 0;
if (this->chip_id_ == ChipId::KT0803L) {
this->write_reg_(0x0B);
}
this->publish_auto_pa_down();
}
bool KT0803Component::get_auto_pa_down() { return this->state_.AUTO_PADN == 1; }
void KT0803Component::set_pa_down(bool value) {
this->state_.PDPA = value ? 1 : 0;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x0B);
}
this->publish_pa_down();
}
bool KT0803Component::get_pa_down() { return this->state_.PDPA == 1; }
void KT0803Component::set_standby_enable(bool value) {
this->state_.Standby = value ? 1 : 0;
if (this->chip_id_ == ChipId::KT0803L) {
this->write_reg_(0x0B);
}
this->publish_standby_enable();
}
bool KT0803Component::get_standby_enable() { return this->state_.Standby == 1; }
void KT0803Component::set_alc_attack_time(AlcTime value) {
if (value >= AlcTime::LAST) {
ESP_LOGE(TAG, "set_alc_attack_time(%d) invalid", (int) value);
return;
}
this->state_.ALC_ATTACK_TIME = (uint8_t) value;
if (this->chip_id_ == ChipId::KT0803L) {
this->write_reg_(0x0C);
}
this->publish_alc_attack_time();
}
AlcTime KT0803Component::get_alc_attack_time() { return (AlcTime) this->state_.ALC_ATTACK_TIME; }
void KT0803Component::set_alc_decay_time(AlcTime value) {
if (value >= AlcTime::LAST) {
ESP_LOGE(TAG, "set_alc_decay_time(%d) invalid", (int) value);
return;
}
this->state_.ALC_DECAY_TIME = (uint8_t) value;
if (this->chip_id_ == ChipId::KT0803L) {
this->write_reg_(0x0C);
}
this->publish_alc_decay_time();
}
AlcTime KT0803Component::get_alc_decay_time() { return (AlcTime) this->state_.ALC_DECAY_TIME; }
void KT0803Component::set_pa_bias(bool value) {
this->state_.PA_BIAS = value ? 1 : 0;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x0E);
}
this->publish_pa_bias();
}
bool KT0803Component::get_pa_bias() { return this->state_.PA_BIAS == 1; }
void KT0803Component::set_audio_limiter_level(AudioLimiterLevel value) {
if (value >= AudioLimiterLevel::LAST) {
ESP_LOGE(TAG, "set_audio_limiter_level(%d) invalid", (int) value);
return;
}
this->state_.LMTLVL = (uint8_t) value;
if (this->chip_id_ == ChipId::KT0803K || this->chip_id_ == ChipId::KT0803M) {
this->write_reg_(0x10);
}
this->publish_audio_limiter_level();
}
AudioLimiterLevel KT0803Component::get_audio_limiter_level() { return (AudioLimiterLevel) this->state_.LMTLVL; }
void KT0803Component::set_switch_mode(SwitchMode value) {
if (value >= SwitchMode::LAST) {
ESP_LOGE(TAG, "set_switch_mode(%d) invalid", (int) value);
return;
}
this->state_.SW_MOD = (uint8_t) value;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x12);
}
this->publish_switch_mode();
}
SwitchMode KT0803Component::get_switch_mode() { return (SwitchMode) this->state_.SW_MOD; }
void KT0803Component::set_silence_high(SilenceHigh value) {
if (value >= SilenceHigh::LAST) {
ESP_LOGE(TAG, "set_silence_high(%d) invalid", (int) value);
return;
}
this->state_.SLNCTHH = (uint8_t) value;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x12);
}
this->publish_silence_high();
}
SilenceHigh KT0803Component::get_silence_high() { return (SilenceHigh) this->state_.SLNCTHH; }
void KT0803Component::set_silence_low(SilenceLow value) {
if (value >= SilenceLow::LAST) {
ESP_LOGE(TAG, "set_silence_low(%d) invalid", (int) value);
return;
}
this->state_.SLNCTHL = (uint8_t) value;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x12);
}
this->publish_silence_low();
}
SilenceLow KT0803Component::get_silence_low() { return (SilenceLow) this->state_.SLNCTHL; }
void KT0803Component::set_silence_detection(bool value) {
this->state_.SLNCDIS = value ? 0 : 1;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x12);
}
this->publish_silence_detection();
}
bool KT0803Component::get_silence_detection() { return this->state_.SLNCDIS == 0; }
void KT0803Component::set_silence_duration(SilenceLowAndHighLevelDurationTime value) {
if (value >= SilenceLowAndHighLevelDurationTime::LAST) {
ESP_LOGE(TAG, "set_silence_duration(%d) invalid", (int) value);
return;
}
this->state_.SLNCTIME0 = (uint8_t) value & 7;
this->state_.SLNCTIME1 = (uint8_t) value >> 3;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x14);
}
this->publish_silence_duration();
}
SilenceLowAndHighLevelDurationTime KT0803Component::get_silence_duration() {
return (SilenceLowAndHighLevelDurationTime) ((this->state_.SLNCTIME1 << 3) | this->state_.SLNCTIME0);
}
void KT0803Component::set_silence_high_counter(SilenceHighLevelCounter value) {
if (value >= SilenceHighLevelCounter::LAST) {
ESP_LOGE(TAG, "set_silence_high_counter(%d) invalid", (int) value);
return;
}
this->state_.SLNCCNTHIGH = (uint8_t) value;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x14);
}
this->publish_silence_high_counter();
}
SilenceHighLevelCounter KT0803Component::get_silence_high_counter() {
return (SilenceHighLevelCounter) this->state_.SLNCCNTHIGH;
}
void KT0803Component::set_silence_low_counter(SilenceLowLevelCounter value) {
if (value >= SilenceLowLevelCounter::LAST) {
ESP_LOGE(TAG, "set_silence_low_counter(%d) invalid", (int) value);
return;
}
this->state_.SLNCCNTLOW = (uint8_t) value;
if (this->chip_id_ != ChipId::KT0803) {
this->write_reg_(0x16);
}
this->publish_silence_low_counter();
}
SilenceLowLevelCounter KT0803Component::get_silence_low_counter() {
return (SilenceLowLevelCounter) this->state_.SLNCCNTLOW;
}
static const int8_t AlcGainMap[] = {-6, -9, -12, -15, 6, 3, 0, -3};
void KT0803Component::set_alc_gain(float value) {
if (!(ALC_GAIN_MIN <= value && value <= ALC_GAIN_MAX)) {
ESP_LOGE(TAG, "set_alc_gain(%.2f) invalid (%.2f - %.2f)", value, ALC_GAIN_MIN, ALC_GAIN_MAX);
return;
}
long v = lround(value);
if (v <= -15) {
this->state_.ALCCMPGAIN = 3;
} else if (v <= -12) {
this->state_.ALCCMPGAIN = 2;
} else if (v <= -9) {
this->state_.ALCCMPGAIN = 1;
} else if (v <= -6) {
this->state_.ALCCMPGAIN = 0;
} else if (v <= -3) {
this->state_.ALCCMPGAIN = 7;
} else if (v <= 0) {
this->state_.ALCCMPGAIN = 6;
} else if (v <= 3) {
this->state_.ALCCMPGAIN = 5;
} else if (v <= 6) {
this->state_.ALCCMPGAIN = 4;
}
if (this->chip_id_ == ChipId::KT0803L) {
this->write_reg_(0x15);
}
this->publish_alc_gain();
}
float KT0803Component::get_alc_gain() { return (float) AlcGainMap[this->state_.ALCCMPGAIN]; }
void KT0803Component::set_xtal_sel(XtalSel value) {
if (value >= XtalSel::LAST) {
ESP_LOGE(TAG, "set_xtal_sel(%d) invalid", value);
return;
}
this->state_.XTAL_SEL = (uint8_t) value;
if (this->chip_id_ == ChipId::KT0803L) {
this->write_reg_(0x17);
}
this->publish_xtal_sel();
}
XtalSel KT0803Component::get_xtal_sel() { return (XtalSel) this->state_.XTAL_SEL; }
void KT0803Component::set_au_enhance(bool value) {
this->state_.AU_ENHANCE = value ? 1 : 0;
if (this->chip_id_ == ChipId::KT0803L) {
this->write_reg_(0x17);
}
this->publish_au_enhance();
}
bool KT0803Component::get_au_enhance() { return this->state_.AU_ENHANCE == 1; }
void KT0803Component::set_frequency_deviation(FrequencyDeviation value) {
if (value >= FrequencyDeviation::LAST) {
ESP_LOGE(TAG, "set_frequency_deviation(%d) invalid", (int) value);
return;
}
if (this->chip_id_ == ChipId::KT0803K || this->chip_id_ == ChipId::KT0803M) {
this->state_.FDEV_K = (uint8_t) value;
this->write_reg_(0x04);
} else if (this->chip_id_ == ChipId::KT0803L) {
this->state_.FDEV_L = (uint8_t) value;
this->write_reg_(0x17);
}
this->publish_frequency_deviation();
}
FrequencyDeviation KT0803Component::get_frequency_deviation() {
if (this->chip_id_ == ChipId::KT0803K || this->chip_id_ == ChipId::KT0803M) {
return (FrequencyDeviation) this->state_.FDEV_K;
} else if (this->chip_id_ == ChipId::KT0803L) {
return (FrequencyDeviation) this->state_.FDEV_L;
}
return FrequencyDeviation::FDEV_75KHZ;
}
// publish
void KT0803Component::publish_pw_ok() { this->publish(this->pw_ok_binary_sensor_, this->state_.PW_OK == 1); }
@ -218,6 +724,88 @@ void KT0803Component::publish_slncid() { this->publish(this->slncid_binary_senso
void KT0803Component::publish_frequency() { this->publish(this->frequency_number_, this->get_frequency()); }
void KT0803Component::publish_pga() { this->publish(this->pga_number_, this->get_pga()); }
void KT0803Component::publish_rfgain() { this->publish(this->rfgain_number_, this->get_rfgain()); }
void KT0803Component::publish_mute() { this->publish(this->mute_switch_, this->get_mute()); }
void KT0803Component::publish_mono() { this->publish(this->mono_switch_, this->get_mono()); }
void KT0803Component::publish_pre_emphasis() {
this->publish(this->pre_emphasis_select_, (size_t) this->get_pre_emphasis());
}
void KT0803Component::publish_pilot_tone_amplitude() {
this->publish(this->pilot_tone_amplitude_select_, (size_t) this->get_pilot_tone_amplitude());
}
void KT0803Component::publish_bass_boost_control() {
this->publish(this->bass_boost_control_select_, (size_t) this->get_bass_boost_control());
}
void KT0803Component::publish_alc_enable() { this->publish(this->alc_enable_switch_, this->get_alc_enable()); }
void KT0803Component::publish_auto_pa_down() { this->publish(this->auto_pa_down_switch_, this->get_auto_pa_down()); }
void KT0803Component::publish_pa_down() { this->publish(this->pa_down_switch_, this->get_pa_down()); }
void KT0803Component::publish_alc_attack_time() {
this->publish(this->alc_attack_time_select_, (size_t) this->get_alc_attack_time());
}
void KT0803Component::publish_alc_decay_time() {
this->publish(this->alc_decay_time_select_, (size_t) this->get_alc_decay_time());
}
void KT0803Component::publish_standby_enable() {
this->publish(this->standby_enable_switch_, this->get_standby_enable());
}
void KT0803Component::publish_pa_bias() { this->publish(this->pa_bias_switch_, this->get_pa_bias()); }
void KT0803Component::publish_audio_limiter_level() {
this->publish(this->audio_limiter_level_select_, (size_t) this->get_audio_limiter_level());
}
void KT0803Component::publish_switch_mode() {
this->publish(this->switch_mode_select_, (size_t) this->get_switch_mode());
}
void KT0803Component::publish_silence_high() {
this->publish(this->silence_high_select_, (size_t) this->get_silence_high());
}
void KT0803Component::publish_silence_low() {
this->publish(this->silence_low_select_, (size_t) this->get_silence_low());
}
void KT0803Component::publish_silence_detection() {
this->publish(this->silence_detection_switch_, this->get_silence_detection());
}
void KT0803Component::publish_silence_duration() {
this->publish(this->silence_duration_select_, (size_t) this->get_silence_duration());
}
void KT0803Component::publish_silence_high_counter() {
this->publish(this->silence_high_counter_select_, (size_t) this->get_silence_high_counter());
}
void KT0803Component::publish_silence_low_counter() {
this->publish(this->silence_low_counter_select_, (size_t) this->get_silence_low_counter());
}
void KT0803Component::publish_alc_gain() { this->publish(this->alc_gain_number_, this->get_alc_gain()); }
void KT0803Component::publish_xtal_sel() { this->publish(this->xtal_sel_select_, (size_t) this->get_xtal_sel()); }
void KT0803Component::publish_au_enhance() { this->publish(this->au_enhance_switch_, this->get_au_enhance()); }
void KT0803Component::publish_frequency_deviation() {
this->publish(this->frequency_deviation_select_, (size_t) this->get_frequency_deviation());
}
void KT0803Component::publish(text_sensor::TextSensor *s, const std::string &state) {
if (s != nullptr) {
if (!s->has_state() || s->state != state) {

View file

@ -40,10 +40,62 @@ class KT0803Component : public PollingComponent, public i2c::I2CDevice {
SUB_BINARY_SENSOR(pw_ok)
SUB_BINARY_SENSOR(slncid)
SUB_NUMBER(frequency)
SUB_NUMBER(pga)
SUB_NUMBER(rfgain)
SUB_SWITCH(mute)
SUB_SWITCH(mono)
SUB_SELECT(pre_emphasis)
SUB_SELECT(pilot_tone_amplitude)
SUB_SELECT(bass_boost_control)
SUB_SWITCH(alc_enable)
SUB_SWITCH(auto_pa_down)
SUB_SWITCH(pa_down)
SUB_SWITCH(standby_enable)
SUB_SELECT(alc_attack_time)
SUB_SELECT(alc_decay_time)
SUB_SWITCH(pa_bias)
SUB_SELECT(audio_limiter_level)
SUB_SELECT(switch_mode)
SUB_SELECT(silence_high)
SUB_SELECT(silence_low)
SUB_SWITCH(silence_detection)
SUB_SELECT(silence_duration)
SUB_SELECT(silence_high_counter)
SUB_SELECT(silence_low_counter)
SUB_NUMBER(alc_gain)
SUB_SELECT(xtal_sel)
SUB_SWITCH(au_enhance)
SUB_SELECT(frequency_deviation)
void publish_pw_ok();
void publish_slncid();
void publish_frequency();
void publish_pga();
void publish_rfgain();
void publish_mute();
void publish_mono();
void publish_pre_emphasis();
void publish_pilot_tone_amplitude();
void publish_bass_boost_control();
void publish_alc_enable();
void publish_auto_pa_down();
void publish_pa_down();
void publish_standby_enable();
void publish_alc_attack_time();
void publish_alc_decay_time();
void publish_pa_bias();
void publish_audio_limiter_level();
void publish_switch_mode();
void publish_silence_high();
void publish_silence_low();
void publish_silence_detection();
void publish_silence_duration();
void publish_silence_high_counter();
void publish_silence_low_counter();
void publish_alc_gain();
void publish_xtal_sel();
void publish_au_enhance();
void publish_frequency_deviation();
void publish(sensor::Sensor *s, float state);
void publish(binary_sensor::BinarySensor *s, bool state);
@ -68,6 +120,58 @@ class KT0803Component : public PollingComponent, public i2c::I2CDevice {
void set_frequency(float value); // MHz
float get_frequency();
void set_pga(float value);
float get_pga();
void set_rfgain(float value);
float get_rfgain();
void set_mute(bool value);
bool get_mute();
void set_mono(bool value);
bool get_mono();
void set_pre_emphasis(PreEmphasis value);
PreEmphasis get_pre_emphasis();
void set_pilot_tone_amplitude(PilotToneAmplitude value);
PilotToneAmplitude get_pilot_tone_amplitude();
void set_bass_boost_control(BassBoostControl value);
BassBoostControl get_bass_boost_control();
void set_alc_enable(bool value);
bool get_alc_enable();
void set_auto_pa_down(bool value);
bool get_auto_pa_down();
void set_pa_down(bool value);
bool get_pa_down();
void set_standby_enable(bool value);
bool get_standby_enable();
void set_alc_attack_time(AlcTime value);
AlcTime get_alc_attack_time();
void set_alc_decay_time(AlcTime value);
AlcTime get_alc_decay_time();
void set_pa_bias(bool value);
bool get_pa_bias();
void set_audio_limiter_level(AudioLimiterLevel value);
AudioLimiterLevel get_audio_limiter_level();
void set_switch_mode(SwitchMode value);
SwitchMode get_switch_mode();
void set_silence_high(SilenceHigh value);
SilenceHigh get_silence_high();
void set_silence_low(SilenceLow value);
SilenceLow get_silence_low();
void set_silence_detection(bool value);
bool get_silence_detection();
void set_silence_duration(SilenceLowAndHighLevelDurationTime value);
SilenceLowAndHighLevelDurationTime get_silence_duration();
void set_silence_high_counter(SilenceHighLevelCounter value);
SilenceHighLevelCounter get_silence_high_counter();
void set_silence_low_counter(SilenceLowLevelCounter value);
SilenceLowLevelCounter get_silence_low_counter();
void set_alc_gain(float value);
float get_alc_gain();
void set_xtal_sel(XtalSel value);
XtalSel get_xtal_sel();
void set_au_enhance(bool value);
bool get_au_enhance();
void set_frequency_deviation(FrequencyDeviation value);
FrequencyDeviation get_frequency_deviation();
};
} // namespace kt0803

View file

@ -5,13 +5,18 @@ namespace kt0803 {
static float CHSEL_MIN = 70.0f;
static float CHSEL_MAX = 108.0f;
static float CHSEL_STEP = 0.05;
static float PGA_MIN = -15;
static float PGA_MAX = 12;
static float PGA_STEP = 1;
static float RFGAIN_MIN = 95.5f;
static float RFGAIN_MAX = 108.0f;
static float ALC_GAIN_MIN = -15;
static float ALC_GAIN_MAX = 6;
enum class ChipId {
KT0803,
KT0803K,
@ -25,7 +30,7 @@ enum class PreEmphasis {
LAST,
};
enum class PilotToneAmplitudeAdjustment {
enum class PilotToneAmplitude {
PLTADJ_LOW,
PLTADJ_HIGH,
LAST,
@ -39,7 +44,7 @@ enum class BassBoostControl {
LAST,
};
enum class AlcTimeSelection {
enum class AlcTime {
ALC_TIME_25US,
ALC_TIME_50US,
ALC_TIME_75US,
@ -59,20 +64,14 @@ enum class AlcTimeSelection {
LAST,
};
enum class SilenceDetectionLowThreshold {
SLNCTHL_025MV,
SLNCTHL_050MV,
SLNCTHL_1MV,
SLNCTHL_2MV,
SLNCTHL_4MV,
SLNCTHL_8MV,
SLNCTHL_16MV,
SLNCTHL_32MV,
enum class SwitchMode {
SW_MOD_MUTE,
SW_MOD_PA_OFF,
LAST,
};
enum class SilenceDetectionHighThreshold {
SLNCTHH_050MV,
enum class SilenceHigh {
SLNCTHH_0M5V,
SLNCTHH_1MV,
SLNCTHH_2MV,
SLNCTHH_4MV,
@ -83,19 +82,19 @@ enum class SilenceDetectionHighThreshold {
LAST,
};
enum class SilenceDetectionHighLevelCounterThreshold {
SLNCCNTHIGH_15,
SLNCCNTHIGH_31,
SLNCCNTHIGH_63,
SLNCCNTHIGH_127,
SLNCCNTHIGH_255,
SLNCCNTHIGH_511,
SLNCCNTHIGH_1023,
SLNCCNTHIGH_2047,
enum class SilenceLow {
SLNCTHL_0M25V,
SLNCTHL_0M5V,
SLNCTHL_1MV,
SLNCTHL_2MV,
SLNCTHL_4MV,
SLNCTHL_8MV,
SLNCTHL_16MV,
SLNCTHL_32MV,
LAST,
};
enum class SilenceDetectionLowAndHighLevelDurationTime {
enum class SilenceLowAndHighLevelDurationTime {
SLNCTIME_50MS,
SLNCTIME_100MS,
SLNCTIME_200MS,
@ -115,7 +114,19 @@ enum class SilenceDetectionLowAndHighLevelDurationTime {
LAST,
};
enum class AlcCompressedGainSetting {
enum class SilenceHighLevelCounter {
SLNCCNTHIGH_15,
SLNCCNTHIGH_31,
SLNCCNTHIGH_63,
SLNCCNTHIGH_127,
SLNCCNTHIGH_255,
SLNCCNTHIGH_511,
SLNCCNTHIGH_1023,
SLNCCNTHIGH_2047,
LAST,
};
enum class AlcCompressedGain {
ALCCMPGAIN_N6DB,
ALCCMPGAIN_N9DB,
ALCCMPGAIN_N12DB,
@ -127,7 +138,7 @@ enum class AlcCompressedGainSetting {
LAST,
};
enum class SilenceLowCounter {
enum class SilenceLowLevelCounter {
SLNCCNTLOW_1,
SLNCCNTLOW_2,
SLNCCNTLOW_4,
@ -139,7 +150,13 @@ enum class SilenceLowCounter {
LAST,
};
enum class FrequencyDeviationAdjustment {
enum class XtalSel {
XTAL_SEL_32K768HZ,
XTAL_SEL_7M6HZ,
LAST,
};
enum class FrequencyDeviation {
FDEV_75KHZ,
FDEV_112K5HZ,
FDEV_150KHZ,
@ -147,13 +164,7 @@ enum class FrequencyDeviationAdjustment {
LAST,
};
enum class XtalSelection {
XTAL_SEL_32K768HZ,
XTAL_SEL_7M6HZ,
LAST,
};
enum class ReferenceClockSelection {
enum class ReferenceClock {
REF_CLK_32K768HZ,
REF_CLK_6M5HZ,
REF_CLK_7M6HZ,
@ -166,19 +177,7 @@ enum class ReferenceClockSelection {
LAST,
};
enum class AlcHighThresholdSelection {
ALCHIGHTH_50MS,
ALCHIGHTH_100MS,
ALCHIGHTH_150MS,
ALCHIGHTH_200MS,
ALCHIGHTH_1S,
ALCHIGHTH_5S,
ALCHIGHTH_10S,
ALCHIGHTH_15S,
LAST,
};
enum class AlcHoldTimeSelection {
enum class AlcHigh {
ALCHOLD_06,
ALCHOLD_05,
ALCHOLD_04,
@ -190,7 +189,19 @@ enum class AlcHoldTimeSelection {
LAST,
};
enum class AlcLowThreshold {
enum class AlcHoldTime {
ALCHIGHTH_50MS,
ALCHIGHTH_100MS,
ALCHIGHTH_150MS,
ALCHIGHTH_200MS,
ALCHIGHTH_1S,
ALCHIGHTH_5S,
ALCHIGHTH_10S,
ALCHIGHTH_15S,
LAST,
};
enum class AlcLow {
ALCLOWTH_025,
ALCLOWTH_020,
ALCLOWTH_015,
@ -206,6 +217,14 @@ enum class AlcLowThreshold {
LAST,
};
enum class AudioLimiterLevel {
LMTLVL_06875,
LMTLVL_07500,
LMTLVL_08750,
LMTLVL_09625,
LAST,
};
// 0 = KT0803
// K = KT0803K or KT0803M (not datasheet for M, it should be mostly the same as K)
// L = KT0803L
@ -234,7 +253,7 @@ struct KT0803State {
uint8_t MUTE : 1; // 0 K L
uint8_t _02_2 : 2;
uint8_t RFGAIN2 : 1; // 0 K L
uint8_t CHSEL0 : 1; // K L (no LSB on 0, step size is only 100KHz)
uint8_t CHSEL0 : 1; // K L (no LSB on 0, step size is only 100kHz)
};
};
uint8_t REG_03;
@ -272,6 +291,7 @@ struct KT0803State {
uint8_t ALC_DECAY_TIME : 4; // L
};
};
uint8_t REG_0D;
union {
uint8_t REG_0E;
struct {
@ -296,7 +316,7 @@ struct KT0803State {
uint8_t PGAMOD : 1; // K L
uint8_t _10_1 : 2;
uint8_t LMTLVL : 2; // K
uint8_t _10_2 : 4;
uint8_t _10_2 : 3;
};
};
uint8_t REG_11;
@ -321,10 +341,10 @@ struct KT0803State {
union {
uint8_t REG_14;
struct {
uint8_t SLNCTIME_MSB : 1; // L
uint8_t SLNCTIME1 : 1; // L
uint8_t _14_1 : 1;
uint8_t SLNCCNTHIGH : 3; // K L
uint8_t SLNCTIME : 3; // K L
uint8_t SLNCTIME0 : 3; // K L
};
};
union {
@ -349,7 +369,7 @@ struct KT0803State {
uint8_t _17_2 : 1;
uint8_t AU_ENHANCE : 1; // L
uint8_t FDEV_L : 1; // L
uint8_t _17_3 : 1;
uint8_t _17_3 : 1; // is this part of FDEV? FDEV_K is two bits
};
};
uint8_t REG_18;

View file

@ -3,17 +3,26 @@ from esphome.components import number
import esphome.config_validation as cv
from esphome.const import (
CONF_FREQUENCY,
UNIT_DECIBEL,
DEVICE_CLASS_FREQUENCY,
DEVICE_CLASS_SIGNAL_STRENGTH,
ENTITY_CATEGORY_CONFIG,
)
from .. import (
CONF_KT0803_ID,
KT0803Component,
kt0803_ns,
CONF_PGA,
CONF_RFGAIN,
CONF_ALC_GAIN,
UNIT_MEGA_HERTZ,
UNIT_DECIBEL_MICRO_VOLT,
)
FrequencyNumber = kt0803_ns.class_("FrequencyNumber", number.Number)
PgaNumber = kt0803_ns.class_("PgaNumber", number.Number)
RfGainNumber = kt0803_ns.class_("RfGainNumber", number.Number)
AlcGainNumber = kt0803_ns.class_("AlcGainNumber", number.Number)
CONFIG_SCHEMA = cv.Schema(
{
@ -24,6 +33,24 @@ CONFIG_SCHEMA = cv.Schema(
device_class=DEVICE_CLASS_FREQUENCY,
entity_category=ENTITY_CATEGORY_CONFIG,
),
cv.Optional(CONF_PGA): number.number_schema(
PgaNumber,
unit_of_measurement=UNIT_DECIBEL,
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
entity_category=ENTITY_CATEGORY_CONFIG,
),
cv.Optional(CONF_RFGAIN): number.number_schema(
RfGainNumber,
unit_of_measurement=UNIT_DECIBEL_MICRO_VOLT,
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
entity_category=ENTITY_CATEGORY_CONFIG,
),
cv.Optional(CONF_ALC_GAIN): number.number_schema(
AlcGainNumber,
unit_of_measurement=UNIT_DECIBEL,
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
entity_category=ENTITY_CATEGORY_CONFIG,
),
}
)
@ -36,4 +63,7 @@ async def new_number(config, id, setter, min_value, max_value, step):
async def to_code(config):
kt0803_component = await cg.get_variable(config[CONF_KT0803_ID])
await new_number(config, CONF_FREQUENCY, kt0803_component.set_frequency_number, 70, 108, 0.05)
await new_number(config, CONF_FREQUENCY, kt0803_component.set_frequency_number, kt0803_ns.CHSEL_MIN, kt0803_ns.CHSEL_MAX, kt0803_ns.CHSEL_STEP)
await new_number(config, CONF_PGA, kt0803_component.set_pga_number, kt0803_ns.PGA_MIN, kt0803_ns.PGA_MAX, kt0803_ns.PGA_STEP)
await new_number(config, CONF_RFGAIN, kt0803_component.set_rfgain_number, kt0803_ns.RFGAIN_MIN, kt0803_ns.RFGAIN_MAX, 0.1)
await new_number(config, CONF_ALC_GAIN, kt0803_component.set_alc_gain_number, kt0803_ns.ALC_GAIN_MIN, kt0803_ns.ALC_GAIN_MAX, 3)

View file

@ -0,0 +1,12 @@
#include "alc_gain_number.h"
namespace esphome {
namespace kt0803 {
void AlcGainNumber::control(float value) {
this->publish_state(value);
this->parent_->set_alc_gain(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/number/number.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class AlcGainNumber : public number::Number, public Parented<KT0803Component> {
public:
AlcGainNumber() = default;
protected:
void control(float value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "pga_number.h"
namespace esphome {
namespace kt0803 {
void PgaNumber::control(float value) {
this->publish_state(value);
this->parent_->set_pga(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/number/number.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class PgaNumber : public number::Number, public Parented<KT0803Component> {
public:
PgaNumber() = default;
protected:
void control(float value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "rfgain_number.h"
namespace esphome {
namespace kt0803 {
void RfGainNumber::control(float value) {
this->publish_state(value);
this->parent_->set_rfgain(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/number/number.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class RfGainNumber : public number::Number, public Parented<KT0803Component> {
public:
RfGainNumber() = default;
protected:
void control(float value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,160 @@
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_KT0803_ID,
KT0803Component,
kt0803_ns,
CONF_CHIP_ID,
CONF_PRE_EMPHASIS,
CONF_PILOT_TONE_AMPLITUDE,
CONF_BASS_BOOST_CONTROL,
CONF_ALC_ATTACK_TIME,
CONF_ALC_DECAY_TIME,
CONF_AUDIO_LIMITER_LEVEL,
CONF_SWITCH_MODE,
CONF_SILENCE_HIGH,
CONF_SILENCE_LOW,
CONF_SILENCE_DURATION,
CONF_SILENCE_HIGH_COUNTER,
CONF_SILENCE_LOW_COUNTER,
CONF_XTAL_SEL,
CONF_FREQUENCY_DEVIATION,
ICON_SLEEP,
ICON_SINE_WAVE,
ICON_SPEAKER,
ICON_EAR_HEARING,
PRE_EMPHASIS,
PILOT_TONE_AMPLITUDE,
BASS_BOOST_CONTROL,
ALC_TIME,
AUDIO_LIMITER_LEVEL,
SWITCH_MODE,
SILENCE_HIGH,
SILENCE_LOW,
SILENCE_LOW_AND_HIGH_LEVEL_DURATION_TIME,
SILENCE_HIGH_LEVEL_COUNTER,
SILENCE_LOW_LEVEL_COUNTER,
XTAL_SEL,
FREQUENCY_DEVIATION,
)
PreEmphasisSelect = kt0803_ns.class_("PreEmphasisSelect", select.Select)
PilotToneAmplitudeSelect = kt0803_ns.class_("PilotToneAmplitudeSelect", select.Select)
BassBoostControlSelect = kt0803_ns.class_("BassBoostControlSelect", select.Select)
AlcAttackTimeSelect = kt0803_ns.class_("AlcAttackTimeSelect", select.Select)
AlcDecayTimeSelect = kt0803_ns.class_("AlcDecayTimeSelect", select.Select)
AudioLimiterLevelSelect = kt0803_ns.class_("AudioLimiterLevelSelect", select.Select)
SwitchModeSelect = kt0803_ns.class_("SwitchModeSelect", select.Select)
SilenceHighSelect = kt0803_ns.class_("SilenceHighSelect", select.Select)
SilenceLowSelect = kt0803_ns.class_("SilenceLowSelect", select.Select)
SilenceDurationSelect = kt0803_ns.class_("SilenceDurationSelect", select.Select)
SilenceHighCounterSelect = kt0803_ns.class_("SilenceHighCounterSelect", select.Select)
SilenceLowCounterSelect = kt0803_ns.class_("SilenceLowCounterSelect", select.Select)
XtalSelSelect = kt0803_ns.class_("XtalSelSelect", select.Select)
FrequencyDeviationSelect = kt0803_ns.class_("FrequencyDeviationSelect", select.Select)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_KT0803_ID): cv.use_id(KT0803Component),
cv.Optional(CONF_PRE_EMPHASIS): select.select_schema(
PreEmphasisSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SINE_WAVE,
),
cv.Optional(CONF_PILOT_TONE_AMPLITUDE): select.select_schema(
PilotToneAmplitudeSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SINE_WAVE,
),
cv.Optional(CONF_BASS_BOOST_CONTROL): select.select_schema(
BassBoostControlSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SPEAKER,
),
cv.Optional(CONF_ALC_ATTACK_TIME): select.select_schema(
AlcAttackTimeSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SPEAKER,
),
cv.Optional(CONF_ALC_DECAY_TIME): select.select_schema(
AlcDecayTimeSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SPEAKER,
),
cv.Optional(CONF_AUDIO_LIMITER_LEVEL): select.select_schema(
AudioLimiterLevelSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SINE_WAVE,
),
cv.Optional(CONF_SWITCH_MODE): select.select_schema(
SwitchModeSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
#icon=ICON_,
),
cv.Optional(CONF_SILENCE_HIGH): select.select_schema(
SilenceHighSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_SILENCE_LOW): select.select_schema(
SilenceLowSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_SILENCE_DURATION): select.select_schema(
SilenceDurationSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_SILENCE_HIGH_COUNTER): select.select_schema(
SilenceHighCounterSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_SILENCE_LOW_COUNTER): select.select_schema(
SilenceLowCounterSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_XTAL_SEL): select.select_schema(
XtalSelSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_PULSE,
),
cv.Optional(CONF_FREQUENCY_DEVIATION): select.select_schema(
FrequencyDeviationSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SINE_WAVE,
),
}
)
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_KT0803_ID])
cg.add(setter(s))
async def to_code(config):
c = await cg.get_variable(config[CONF_KT0803_ID])
await new_select(config, CONF_PRE_EMPHASIS, c.set_pre_emphasis_select, PRE_EMPHASIS)
await new_select(config, CONF_PILOT_TONE_AMPLITUDE, c.set_pilot_tone_amplitude_select, PILOT_TONE_AMPLITUDE)
await new_select(config, CONF_BASS_BOOST_CONTROL, c.set_bass_boost_control_select, BASS_BOOST_CONTROL)
await new_select(config, CONF_ALC_ATTACK_TIME, c.set_alc_attack_time_select, ALC_TIME)
await new_select(config, CONF_ALC_DECAY_TIME, c.set_alc_decay_time_select, ALC_TIME)
await new_select(config, CONF_AUDIO_LIMITER_LEVEL, c.set_audio_limiter_level_select, AUDIO_LIMITER_LEVEL)
await new_select(config, CONF_SWITCH_MODE, c.set_switch_mode_select, SWITCH_MODE)
await new_select(config, CONF_SILENCE_HIGH, c.set_silence_high_select, SILENCE_HIGH)
await new_select(config, CONF_SILENCE_LOW, c.set_silence_low_select, SILENCE_LOW)
await new_select(config, CONF_SILENCE_DURATION, c.set_silence_duration_select, SILENCE_LOW_AND_HIGH_LEVEL_DURATION_TIME)
await new_select(config, CONF_SILENCE_HIGH_COUNTER, c.set_silence_high_counter_select, SILENCE_HIGH_LEVEL_COUNTER)
await new_select(config, CONF_SILENCE_LOW_COUNTER, c.set_silence_low_counter_select, SILENCE_LOW_LEVEL_COUNTER)
await new_select(config, CONF_XTAL_SEL, c.set_xtal_sel_select, XTAL_SEL)
await new_select(config, CONF_FREQUENCY_DEVIATION, c.set_frequency_deviation_select, FREQUENCY_DEVIATION)

View file

@ -0,0 +1,14 @@
#include "alc_attack_time_select.h"
namespace esphome {
namespace kt0803 {
void AlcAttackTimeSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_alc_attack_time((AlcTime) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class AlcAttackTimeSelect : public select::Select, public Parented<KT0803Component> {
public:
AlcAttackTimeSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "alc_decay_time_select.h"
namespace esphome {
namespace kt0803 {
void AlcDecayTimeSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_alc_decay_time((AlcTime) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class AlcDecayTimeSelect : public select::Select, public Parented<KT0803Component> {
public:
AlcDecayTimeSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "audio_limiter_level_select.h"
namespace esphome {
namespace kt0803 {
void AudioLimiterLevelSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_audio_limiter_level((AudioLimiterLevel) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class AudioLimiterLevelSelect : public select::Select, public Parented<KT0803Component> {
public:
AudioLimiterLevelSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "bass_boost_control_select.h"
namespace esphome {
namespace kt0803 {
void BassBoostControlSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_bass_boost_control((BassBoostControl) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class BassBoostControlSelect : public select::Select, public Parented<KT0803Component> {
public:
BassBoostControlSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "frequency_deviation_select.h"
namespace esphome {
namespace kt0803 {
void FrequencyDeviationSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_frequency_deviation((FrequencyDeviation) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class FrequencyDeviationSelect : public select::Select, public Parented<KT0803Component> {
public:
FrequencyDeviationSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "pilot_tone_amplitude_select.h"
namespace esphome {
namespace kt0803 {
void PilotToneAmplitudeSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_pilot_tone_amplitude((PilotToneAmplitude) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class PilotToneAmplitudeSelect : public select::Select, public Parented<KT0803Component> {
public:
PilotToneAmplitudeSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "pre_emphasis_select.h"
namespace esphome {
namespace kt0803 {
void PreEmphasisSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_pre_emphasis((PreEmphasis) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class PreEmphasisSelect : public select::Select, public Parented<KT0803Component> {
public:
PreEmphasisSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "silence_duration_select.h"
namespace esphome {
namespace kt0803 {
void SilenceDurationSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_silence_duration((SilenceLowAndHighLevelDurationTime) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class SilenceDurationSelect : public select::Select, public Parented<KT0803Component> {
public:
SilenceDurationSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "silence_high_counter_select.h"
namespace esphome {
namespace kt0803 {
void SilenceHighCounterSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_silence_high_counter((SilenceHighLevelCounter) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class SilenceHighCounterSelect : public select::Select, public Parented<KT0803Component> {
public:
SilenceHighCounterSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "silence_high_select.h"
namespace esphome {
namespace kt0803 {
void SilenceHighSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_silence_high((SilenceHigh) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class SilenceHighSelect : public select::Select, public Parented<KT0803Component> {
public:
SilenceHighSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "silence_low_counter_select.h"
namespace esphome {
namespace kt0803 {
void SilenceLowCounterSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_silence_low_counter((SilenceLowLevelCounter) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class SilenceLowCounterSelect : public select::Select, public Parented<KT0803Component> {
public:
SilenceLowCounterSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "silence_low_select.h"
namespace esphome {
namespace kt0803 {
void SilenceLowSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_silence_low((SilenceLow) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class SilenceLowSelect : public select::Select, public Parented<KT0803Component> {
public:
SilenceLowSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "switch_mode_select.h"
namespace esphome {
namespace kt0803 {
void SwitchModeSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_switch_mode((SwitchMode) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class SwitchModeSelect : public select::Select, public Parented<KT0803Component> {
public:
SwitchModeSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,14 @@
#include "xtal_sel_select.h"
namespace esphome {
namespace kt0803 {
void XtalSelSelect::control(const std::string &value) {
this->publish_state(value);
if (auto index = this->active_index()) {
this->parent_->set_xtal_sel((XtalSel) *index);
}
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/select/select.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class XtalSelSelect : public select::Select, public Parented<KT0803Component> {
public:
XtalSelSelect() = default;
protected:
void control(const std::string &value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,118 @@
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_KT0803_ID,
KT0803Component,
kt0803_ns,
CONF_MUTE,
CONF_MONO,
CONF_ALC_ENABLE,
CONF_AUTO_PA_DOWN,
CONF_PA_DOWN,
CONF_STANDBY_ENABLE,
CONF_PA_BIAS,
CONF_SILENCE_DETECTION,
CONF_AU_ENHANCE,
ICON_VOLUME_MUTE,
ICON_EAR_HEARING,
ICON_SINE_WAVE,
ICON_SLEEP,
ICON_RADIO_TOWER,
ICON_FORMAT_TEXT,
)
MuteSwitch = kt0803_ns.class_("MuteSwitch", switch.Switch)
MonoSwitch = kt0803_ns.class_("MonoSwitch", switch.Switch)
AlcEnableSwitch = kt0803_ns.class_("AlcEnableSwitch", switch.Switch)
AutoPaDownSwitch = kt0803_ns.class_("AutoPaDownSwitch", switch.Switch)
PaDownSwitch = kt0803_ns.class_("PaDownSwitch", switch.Switch)
StandbyEnableSwitch = kt0803_ns.class_("StandbyEnableSwitch", switch.Switch)
PaBiasSwitch = kt0803_ns.class_("PaBiasSwitch", switch.Switch)
SilenceDetectionSwitch = kt0803_ns.class_("SilenceDetectionSwitch", switch.Switch)
AuEnhanceSwitch = kt0803_ns.class_("AuEnhanceSwitch", switch.Switch)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_KT0803_ID): cv.use_id(KT0803Component),
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_ALC_ENABLE): switch.switch_schema(
AlcEnableSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SINE_WAVE,
),
cv.Optional(CONF_AUTO_PA_DOWN): switch.switch_schema(
AutoPaDownSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_PA_DOWN): switch.switch_schema(
PaDownSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_STANDBY_ENABLE): switch.switch_schema(
StandbyEnableSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_PA_BIAS): switch.switch_schema(
PaBiasSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SINE_WAVE,
),
cv.Optional(CONF_SILENCE_DETECTION): switch.switch_schema(
SilenceDetectionSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SLEEP,
),
cv.Optional(CONF_AU_ENHANCE): switch.switch_schema(
AuEnhanceSwitch,
device_class=DEVICE_CLASS_SWITCH,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SINE_WAVE,
),
}
)
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_KT0803_ID])
cg.add(setter(s))
async def to_code(config):
c = await cg.get_variable(config[CONF_KT0803_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_ALC_ENABLE, c.set_alc_enable_switch)
await new_switch(config, CONF_AUTO_PA_DOWN, c.set_auto_pa_down_switch)
await new_switch(config, CONF_PA_DOWN, c.set_pa_down_switch)
await new_switch(config, CONF_STANDBY_ENABLE, c.set_standby_enable_switch)
await new_switch(config, CONF_PA_BIAS, c.set_pa_bias_switch)
await new_switch(config, CONF_SILENCE_DETECTION, c.set_silence_detection_switch)
await new_switch(config, CONF_AU_ENHANCE, c.set_au_enhance_switch)

View file

@ -0,0 +1,12 @@
#include "alc_enable_switch.h"
namespace esphome {
namespace kt0803 {
void AlcEnableSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_alc_enable(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class AlcEnableSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
AlcEnableSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "au_enhance_switch.h"
namespace esphome {
namespace kt0803 {
void AuEnhanceSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_au_enhance(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class AuEnhanceSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
AuEnhanceSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "auto_pa_down_switch.h"
namespace esphome {
namespace kt0803 {
void AutoPaDownSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_auto_pa_down(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class AutoPaDownSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
AutoPaDownSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "mono_switch.h"
namespace esphome {
namespace kt0803 {
void MonoSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_mono(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class MonoSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
MonoSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "mute_switch.h"
namespace esphome {
namespace kt0803 {
void MuteSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_mute(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class MuteSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
MuteSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "pa_bias_switch.h"
namespace esphome {
namespace kt0803 {
void PaBiasSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_pa_bias(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class PaBiasSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
PaBiasSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "pa_down_switch.h"
namespace esphome {
namespace kt0803 {
void PaDownSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_pa_down(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class PaDownSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
PaDownSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "silence_detection_switch.h"
namespace esphome {
namespace kt0803 {
void SilenceDetectionSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_silence_detection(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class SilenceDetectionSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
SilenceDetectionSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,12 @@
#include "standby_enable_switch.h"
namespace esphome {
namespace kt0803 {
void StandbyEnableSwitch::write_state(bool value) {
this->publish_state(value);
this->parent_->set_standby_enable(value);
}
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include "esphome/components/switch/switch.h"
#include "../kt0803.h"
namespace esphome {
namespace kt0803 {
class StandbyEnableSwitch : public switch_::Switch, public Parented<KT0803Component> {
public:
StandbyEnableSwitch() = default;
protected:
void write_state(bool value) override;
};
} // namespace kt0803
} // namespace esphome

View file

@ -0,0 +1,138 @@
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_KT0803_ID,
KT0803Component,
kt0803_ns,
#CONF_..,
ICON_FORMAT_TEXT,
)
#...Text = kt0803_ns.class_("...Text", 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_KT0803_ID): cv.use_id(KT0803Component),
#cv.Optional(CONF_..): text_schema(..Text, 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_KT0803_ID])
cg.add(setter(t))
async def to_code(config):
c = await cg.get_variable(config[CONF_KT0803_ID])
#await new_text_simple(config, CONF_.., c.set_.._text, 0, kt0803_ns..._MAX)