mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 15:08:10 +01:00
commit
3be3267d06
9 changed files with 117 additions and 35 deletions
|
@ -1,15 +1,11 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
import esphome.final_validate as fv
|
|
||||||
from esphome.components import logger
|
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_BLOCK,
|
CONF_BLOCK,
|
||||||
CONF_DEVICE,
|
CONF_DEVICE,
|
||||||
CONF_FRAGMENTATION,
|
CONF_FRAGMENTATION,
|
||||||
CONF_FREE,
|
CONF_FREE,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_LEVEL,
|
|
||||||
CONF_LOGGER,
|
|
||||||
CONF_LOOP_TIME,
|
CONF_LOOP_TIME,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -43,18 +39,6 @@ CONFIG_SCHEMA = cv.Schema(
|
||||||
).extend(cv.polling_component_schema("60s"))
|
).extend(cv.polling_component_schema("60s"))
|
||||||
|
|
||||||
|
|
||||||
def _final_validate(_):
|
|
||||||
logger_conf = fv.full_config.get()[CONF_LOGGER]
|
|
||||||
severity = logger.LOG_LEVEL_SEVERITY.index(logger_conf[CONF_LEVEL])
|
|
||||||
if severity < logger.LOG_LEVEL_SEVERITY.index("DEBUG"):
|
|
||||||
raise cv.Invalid(
|
|
||||||
"The debug component requires the logger to be at least at DEBUG level"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
FINAL_VALIDATE_SCHEMA = _final_validate
|
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
|
|
|
@ -37,6 +37,10 @@ static uint32_t get_free_heap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugComponent::dump_config() {
|
void DebugComponent::dump_config() {
|
||||||
|
#ifndef ESPHOME_LOG_HAS_DEBUG
|
||||||
|
return; // Can't log below if debug logging is disabled
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string device_info;
|
std::string device_info;
|
||||||
std::string reset_reason;
|
std::string reset_reason;
|
||||||
device_info.reserve(256);
|
device_info.reserve(256);
|
||||||
|
|
|
@ -276,7 +276,7 @@ void EthernetComponent::start_connect_() {
|
||||||
#endif
|
#endif
|
||||||
dns_setserver(0, &d);
|
dns_setserver(0, &d);
|
||||||
}
|
}
|
||||||
if (uint32_t(this->manual_ip_->dns1) != 0) {
|
if (uint32_t(this->manual_ip_->dns2) != 0) {
|
||||||
ip_addr_t d;
|
ip_addr_t d;
|
||||||
#if LWIP_IPV6
|
#if LWIP_IPV6
|
||||||
d.type = IPADDR_TYPE_V4;
|
d.type = IPADDR_TYPE_V4;
|
||||||
|
|
|
@ -154,19 +154,26 @@ ErrorCode ArduinoI2CBus::writev(uint8_t address, WriteBuffer *buffers, size_t cn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t status = wire_->endTransmission(stop);
|
uint8_t status = wire_->endTransmission(stop);
|
||||||
if (status == 0) {
|
switch (status) {
|
||||||
|
case 0:
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
} else if (status == 1) {
|
case 1:
|
||||||
// transmit buffer not large enough
|
// transmit buffer not large enough
|
||||||
ESP_LOGVV(TAG, "TX failed: buffer not large enough");
|
ESP_LOGVV(TAG, "TX failed: buffer not large enough");
|
||||||
return ERROR_UNKNOWN;
|
return ERROR_UNKNOWN;
|
||||||
} else if (status == 2 || status == 3) {
|
case 2:
|
||||||
|
case 3:
|
||||||
ESP_LOGVV(TAG, "TX failed: not acknowledged");
|
ESP_LOGVV(TAG, "TX failed: not acknowledged");
|
||||||
return ERROR_NOT_ACKNOWLEDGED;
|
return ERROR_NOT_ACKNOWLEDGED;
|
||||||
}
|
case 5:
|
||||||
|
ESP_LOGVV(TAG, "TX failed: timeout");
|
||||||
|
return ERROR_UNKNOWN;
|
||||||
|
case 4:
|
||||||
|
default:
|
||||||
ESP_LOGVV(TAG, "TX failed: unknown error %u", status);
|
ESP_LOGVV(TAG, "TX failed: unknown error %u", status);
|
||||||
return ERROR_UNKNOWN;
|
return ERROR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Perform I2C bus recovery, see:
|
/// Perform I2C bus recovery, see:
|
||||||
/// https://www.nxp.com/docs/en/user-guide/UM10204.pdf
|
/// https://www.nxp.com/docs/en/user-guide/UM10204.pdf
|
||||||
|
|
|
@ -11,6 +11,14 @@ DEPENDENCIES = ["api", "microphone"]
|
||||||
|
|
||||||
CODEOWNERS = ["@jesserockz"]
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
|
||||||
|
CONF_ON_START = "on_start"
|
||||||
|
CONF_ON_STT_END = "on_stt_end"
|
||||||
|
CONF_ON_TTS_START = "on_tts_start"
|
||||||
|
CONF_ON_TTS_END = "on_tts_end"
|
||||||
|
CONF_ON_END = "on_end"
|
||||||
|
CONF_ON_ERROR = "on_error"
|
||||||
|
|
||||||
|
|
||||||
voice_assistant_ns = cg.esphome_ns.namespace("voice_assistant")
|
voice_assistant_ns = cg.esphome_ns.namespace("voice_assistant")
|
||||||
VoiceAssistant = voice_assistant_ns.class_("VoiceAssistant", cg.Component)
|
VoiceAssistant = voice_assistant_ns.class_("VoiceAssistant", cg.Component)
|
||||||
|
|
||||||
|
@ -26,6 +34,12 @@ CONFIG_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(VoiceAssistant),
|
cv.GenerateID(): cv.declare_id(VoiceAssistant),
|
||||||
cv.GenerateID(CONF_MICROPHONE): cv.use_id(microphone.Microphone),
|
cv.GenerateID(CONF_MICROPHONE): cv.use_id(microphone.Microphone),
|
||||||
|
cv.Optional(CONF_ON_START): automation.validate_automation(single=True),
|
||||||
|
cv.Optional(CONF_ON_STT_END): automation.validate_automation(single=True),
|
||||||
|
cv.Optional(CONF_ON_TTS_START): automation.validate_automation(single=True),
|
||||||
|
cv.Optional(CONF_ON_TTS_END): automation.validate_automation(single=True),
|
||||||
|
cv.Optional(CONF_ON_END): automation.validate_automation(single=True),
|
||||||
|
cv.Optional(CONF_ON_ERROR): automation.validate_automation(single=True),
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA)
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
|
||||||
|
@ -37,6 +51,40 @@ async def to_code(config):
|
||||||
mic = await cg.get_variable(config[CONF_MICROPHONE])
|
mic = await cg.get_variable(config[CONF_MICROPHONE])
|
||||||
cg.add(var.set_microphone(mic))
|
cg.add(var.set_microphone(mic))
|
||||||
|
|
||||||
|
if CONF_ON_START in config:
|
||||||
|
await automation.build_automation(
|
||||||
|
var.get_start_trigger(), [], config[CONF_ON_START]
|
||||||
|
)
|
||||||
|
|
||||||
|
if CONF_ON_STT_END in config:
|
||||||
|
await automation.build_automation(
|
||||||
|
var.get_stt_end_trigger(), [(cg.std_string, "x")], config[CONF_ON_STT_END]
|
||||||
|
)
|
||||||
|
|
||||||
|
if CONF_ON_TTS_START in config:
|
||||||
|
await automation.build_automation(
|
||||||
|
var.get_tts_start_trigger(),
|
||||||
|
[(cg.std_string, "x")],
|
||||||
|
config[CONF_ON_TTS_START],
|
||||||
|
)
|
||||||
|
|
||||||
|
if CONF_ON_TTS_END in config:
|
||||||
|
await automation.build_automation(
|
||||||
|
var.get_tts_end_trigger(), [(cg.std_string, "x")], config[CONF_ON_TTS_END]
|
||||||
|
)
|
||||||
|
|
||||||
|
if CONF_ON_END in config:
|
||||||
|
await automation.build_automation(
|
||||||
|
var.get_end_trigger(), [], config[CONF_ON_END]
|
||||||
|
)
|
||||||
|
|
||||||
|
if CONF_ON_ERROR in config:
|
||||||
|
await automation.build_automation(
|
||||||
|
var.get_error_trigger(),
|
||||||
|
[(cg.std_string, "code"), (cg.std_string, "message")],
|
||||||
|
config[CONF_ON_ERROR],
|
||||||
|
)
|
||||||
|
|
||||||
cg.add_define("USE_VOICE_ASSISTANT")
|
cg.add_define("USE_VOICE_ASSISTANT")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,9 @@ void VoiceAssistant::signal_stop() {
|
||||||
|
|
||||||
void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
|
void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
|
||||||
switch (msg.event_type) {
|
switch (msg.event_type) {
|
||||||
case api::enums::VOICE_ASSISTANT_RUN_END:
|
case api::enums::VOICE_ASSISTANT_RUN_START:
|
||||||
ESP_LOGD(TAG, "Voice Assistant ended.");
|
ESP_LOGD(TAG, "Assist Pipeline running");
|
||||||
|
this->start_trigger_->trigger();
|
||||||
break;
|
break;
|
||||||
case api::enums::VOICE_ASSISTANT_STT_END: {
|
case api::enums::VOICE_ASSISTANT_STT_END: {
|
||||||
std::string text;
|
std::string text;
|
||||||
|
@ -91,7 +92,7 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, "Speech recognised as: \"%s\"", text.c_str());
|
ESP_LOGD(TAG, "Speech recognised as: \"%s\"", text.c_str());
|
||||||
// TODO `on_stt_end` trigger
|
this->stt_end_trigger_->trigger(text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case api::enums::VOICE_ASSISTANT_TTS_START: {
|
case api::enums::VOICE_ASSISTANT_TTS_START: {
|
||||||
|
@ -106,7 +107,7 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, "Response: \"%s\"", text.c_str());
|
ESP_LOGD(TAG, "Response: \"%s\"", text.c_str());
|
||||||
// TODO `on_tts_start` trigger
|
this->tts_start_trigger_->trigger(text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case api::enums::VOICE_ASSISTANT_TTS_END: {
|
case api::enums::VOICE_ASSISTANT_TTS_END: {
|
||||||
|
@ -121,9 +122,13 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, "Response URL: \"%s\"", url.c_str());
|
ESP_LOGD(TAG, "Response URL: \"%s\"", url.c_str());
|
||||||
// TODO `on_tts_end` trigger
|
this->tts_end_trigger_->trigger(url);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case api::enums::VOICE_ASSISTANT_RUN_END:
|
||||||
|
ESP_LOGD(TAG, "Assist Pipeline ended");
|
||||||
|
this->end_trigger_->trigger();
|
||||||
|
break;
|
||||||
case api::enums::VOICE_ASSISTANT_ERROR: {
|
case api::enums::VOICE_ASSISTANT_ERROR: {
|
||||||
std::string code = "";
|
std::string code = "";
|
||||||
std::string message = "";
|
std::string message = "";
|
||||||
|
@ -135,7 +140,7 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_LOGE(TAG, "Error: %s - %s", code.c_str(), message.c_str());
|
ESP_LOGE(TAG, "Error: %s - %s", code.c_str(), message.c_str());
|
||||||
// TODO `on_error` trigger
|
this->error_trigger_->trigger(code, message);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -25,10 +25,24 @@ class VoiceAssistant : public Component {
|
||||||
|
|
||||||
void on_event(const api::VoiceAssistantEventResponse &msg);
|
void on_event(const api::VoiceAssistantEventResponse &msg);
|
||||||
|
|
||||||
|
Trigger<> *get_start_trigger() const { return this->start_trigger_; }
|
||||||
|
Trigger<std::string> *get_stt_end_trigger() const { return this->stt_end_trigger_; }
|
||||||
|
Trigger<std::string> *get_tts_start_trigger() const { return this->tts_start_trigger_; }
|
||||||
|
Trigger<std::string> *get_tts_end_trigger() const { return this->tts_end_trigger_; }
|
||||||
|
Trigger<> *get_end_trigger() const { return this->end_trigger_; }
|
||||||
|
Trigger<std::string, std::string> *get_error_trigger() const { return this->error_trigger_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<socket::Socket> socket_ = nullptr;
|
std::unique_ptr<socket::Socket> socket_ = nullptr;
|
||||||
struct sockaddr_storage dest_addr_;
|
struct sockaddr_storage dest_addr_;
|
||||||
|
|
||||||
|
Trigger<> *start_trigger_ = new Trigger<>();
|
||||||
|
Trigger<std::string> *stt_end_trigger_ = new Trigger<std::string>();
|
||||||
|
Trigger<std::string> *tts_start_trigger_ = new Trigger<std::string>();
|
||||||
|
Trigger<std::string> *tts_end_trigger_ = new Trigger<std::string>();
|
||||||
|
Trigger<> *end_trigger_ = new Trigger<>();
|
||||||
|
Trigger<std::string, std::string> *error_trigger_ = new Trigger<std::string, std::string>();
|
||||||
|
|
||||||
microphone::Microphone *mic_{nullptr};
|
microphone::Microphone *mic_{nullptr};
|
||||||
|
|
||||||
bool running_{false};
|
bool running_{false};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2023.4.0b1"
|
__version__ = "2023.4.0b2"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
|
|
||||||
|
|
|
@ -696,3 +696,23 @@ microphone:
|
||||||
|
|
||||||
voice_assistant:
|
voice_assistant:
|
||||||
microphone: mic_id
|
microphone: mic_id
|
||||||
|
on_start:
|
||||||
|
- logger.log: "Voice assistant started"
|
||||||
|
on_stt_end:
|
||||||
|
- logger.log:
|
||||||
|
format: "Voice assistant STT ended with result %s"
|
||||||
|
args: [x.c_str()]
|
||||||
|
on_tts_start:
|
||||||
|
- logger.log:
|
||||||
|
format: "Voice assistant TTS started with text %s"
|
||||||
|
args: [x.c_str()]
|
||||||
|
on_tts_end:
|
||||||
|
- logger.log:
|
||||||
|
format: "Voice assistant TTS ended with url %s"
|
||||||
|
args: [x.c_str()]
|
||||||
|
on_end:
|
||||||
|
- logger.log: "Voice assistant ended"
|
||||||
|
on_error:
|
||||||
|
- logger.log:
|
||||||
|
format: "Voice assistant error - code %s, message: %s"
|
||||||
|
args: [code.c_str(), message.c_str()]
|
||||||
|
|
Loading…
Reference in a new issue