mirror of
https://github.com/esphome/esphome.git
synced 2025-11-06 10:01:51 +00:00
Compare commits
23 Commits
2024.5.0b1
...
2024.5.0b5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd8afa51cd | ||
|
|
db4aa0b679 | ||
|
|
28a09cc0d0 | ||
|
|
128fad57b3 | ||
|
|
142c4a87d2 | ||
|
|
1e4d6ee344 | ||
|
|
5afe0e5ec2 | ||
|
|
ba3fc4c5d0 | ||
|
|
694f75117e | ||
|
|
4ec2ef27a8 | ||
|
|
448b4f5cb6 | ||
|
|
8ae8cd1168 | ||
|
|
bd776baf8d | ||
|
|
819bb9f8bc | ||
|
|
26048d18ef | ||
|
|
0883f0efd7 | ||
|
|
0ca395e8d0 | ||
|
|
98dc9fde6c | ||
|
|
ed1344edd2 | ||
|
|
2fbe80c1f7 | ||
|
|
879f404b48 | ||
|
|
34585a6f15 | ||
|
|
054587c0e4 |
16
.github/actions/build-image/action.yaml
vendored
16
.github/actions/build-image/action.yaml
vendored
@@ -57,14 +57,6 @@ runs:
|
|||||||
digest="${{ steps.build-ghcr.outputs.digest }}"
|
digest="${{ steps.build-ghcr.outputs.digest }}"
|
||||||
touch "/tmp/digests/${{ inputs.target }}/ghcr/${digest#sha256:}"
|
touch "/tmp/digests/${{ inputs.target }}/ghcr/${digest#sha256:}"
|
||||||
|
|
||||||
- name: Upload ghcr digest
|
|
||||||
uses: actions/upload-artifact@v3.1.3
|
|
||||||
with:
|
|
||||||
name: digests-${{ inputs.target }}-ghcr
|
|
||||||
path: /tmp/digests/${{ inputs.target }}/ghcr/*
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
- name: Build and push to dockerhub by digest
|
- name: Build and push to dockerhub by digest
|
||||||
id: build-dockerhub
|
id: build-dockerhub
|
||||||
uses: docker/build-push-action@v5.3.0
|
uses: docker/build-push-action@v5.3.0
|
||||||
@@ -87,11 +79,3 @@ runs:
|
|||||||
mkdir -p /tmp/digests/${{ inputs.target }}/dockerhub
|
mkdir -p /tmp/digests/${{ inputs.target }}/dockerhub
|
||||||
digest="${{ steps.build-dockerhub.outputs.digest }}"
|
digest="${{ steps.build-dockerhub.outputs.digest }}"
|
||||||
touch "/tmp/digests/${{ inputs.target }}/dockerhub/${digest#sha256:}"
|
touch "/tmp/digests/${{ inputs.target }}/dockerhub/${digest#sha256:}"
|
||||||
|
|
||||||
- name: Upload dockerhub digest
|
|
||||||
uses: actions/upload-artifact@v3.1.3
|
|
||||||
with:
|
|
||||||
name: digests-${{ inputs.target }}-dockerhub
|
|
||||||
path: /tmp/digests/${{ inputs.target }}/dockerhub/*
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 1
|
|
||||||
|
|||||||
22
.github/workflows/release.yml
vendored
22
.github/workflows/release.yml
vendored
@@ -132,6 +132,19 @@ jobs:
|
|||||||
suffix: lint
|
suffix: lint
|
||||||
version: ${{ needs.init.outputs.tag }}
|
version: ${{ needs.init.outputs.tag }}
|
||||||
|
|
||||||
|
- name: Sanitize platform name
|
||||||
|
id: sanitize
|
||||||
|
run: |
|
||||||
|
echo "${{ matrix.platform }}" | sed 's|/|-|g' > /tmp/platform
|
||||||
|
echo name=$(cat /tmp/platform) >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Upload digests
|
||||||
|
uses: actions/upload-artifact@v4.3.3
|
||||||
|
with:
|
||||||
|
name: digests-${{ steps.sanitize.outputs.name }}
|
||||||
|
path: /tmp/digests
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
deploy-manifest:
|
deploy-manifest:
|
||||||
name: Publish ESPHome ${{ matrix.image.title }} to ${{ matrix.registry }}
|
name: Publish ESPHome ${{ matrix.image.title }} to ${{ matrix.registry }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -160,11 +173,14 @@ jobs:
|
|||||||
- dockerhub
|
- dockerhub
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.5
|
- uses: actions/checkout@v4.1.5
|
||||||
|
|
||||||
- name: Download digests
|
- name: Download digests
|
||||||
uses: actions/download-artifact@v3.0.2
|
uses: actions/download-artifact@v4.1.7
|
||||||
with:
|
with:
|
||||||
name: digests-${{ matrix.image.target }}-${{ matrix.registry }}
|
pattern: digests-*
|
||||||
path: /tmp/digests
|
path: /tmp/digests
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.3.0
|
uses: docker/setup-buildx-action@v3.3.0
|
||||||
|
|
||||||
@@ -195,7 +211,7 @@ jobs:
|
|||||||
done
|
done
|
||||||
|
|
||||||
- name: Create manifest list and push
|
- name: Create manifest list and push
|
||||||
working-directory: /tmp/digests
|
working-directory: /tmp/digests/${{ matrix.image.target }}/${{ matrix.registry }}
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools create $(jq -Rcnr 'inputs | . / "," | map("-t " + .) | join(" ")' <<< "${{ steps.tags.outputs.tags}}") \
|
docker buildx imagetools create $(jq -Rcnr 'inputs | . / "," | map("-t " + .) | join(" ")' <<< "${{ steps.tags.outputs.tags}}") \
|
||||||
$(printf '${{ steps.tags.outputs.image }}@sha256:%s ' *)
|
$(printf '${{ steps.tags.outputs.image }}@sha256:%s ' *)
|
||||||
|
|||||||
@@ -1147,6 +1147,9 @@ message MediaPlayerCommandRequest {
|
|||||||
|
|
||||||
bool has_media_url = 6;
|
bool has_media_url = 6;
|
||||||
string media_url = 7;
|
string media_url = 7;
|
||||||
|
|
||||||
|
bool has_announcement = 8;
|
||||||
|
bool announcement = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== BLUETOOTH ====================
|
// ==================== BLUETOOTH ====================
|
||||||
|
|||||||
@@ -1002,7 +1002,11 @@ bool APIConnection::send_media_player_state(media_player::MediaPlayer *media_pla
|
|||||||
|
|
||||||
MediaPlayerStateResponse resp{};
|
MediaPlayerStateResponse resp{};
|
||||||
resp.key = media_player->get_object_id_hash();
|
resp.key = media_player->get_object_id_hash();
|
||||||
resp.state = static_cast<enums::MediaPlayerState>(media_player->state);
|
|
||||||
|
media_player::MediaPlayerState report_state = media_player->state == media_player::MEDIA_PLAYER_STATE_ANNOUNCING
|
||||||
|
? media_player::MEDIA_PLAYER_STATE_PLAYING
|
||||||
|
: media_player->state;
|
||||||
|
resp.state = static_cast<enums::MediaPlayerState>(report_state);
|
||||||
resp.volume = media_player->volume;
|
resp.volume = media_player->volume;
|
||||||
resp.muted = media_player->is_muted();
|
resp.muted = media_player->is_muted();
|
||||||
return this->send_media_player_state_response(resp);
|
return this->send_media_player_state_response(resp);
|
||||||
@@ -1038,6 +1042,9 @@ void APIConnection::media_player_command(const MediaPlayerCommandRequest &msg) {
|
|||||||
if (msg.has_media_url) {
|
if (msg.has_media_url) {
|
||||||
call.set_media_url(msg.media_url);
|
call.set_media_url(msg.media_url);
|
||||||
}
|
}
|
||||||
|
if (msg.has_announcement) {
|
||||||
|
call.set_announcement(msg.announcement);
|
||||||
|
}
|
||||||
call.perform();
|
call.perform();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5253,6 +5253,14 @@ bool MediaPlayerCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt val
|
|||||||
this->has_media_url = value.as_bool();
|
this->has_media_url = value.as_bool();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case 8: {
|
||||||
|
this->has_announcement = value.as_bool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 9: {
|
||||||
|
this->announcement = value.as_bool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -5289,6 +5297,8 @@ void MediaPlayerCommandRequest::encode(ProtoWriteBuffer buffer) const {
|
|||||||
buffer.encode_float(5, this->volume);
|
buffer.encode_float(5, this->volume);
|
||||||
buffer.encode_bool(6, this->has_media_url);
|
buffer.encode_bool(6, this->has_media_url);
|
||||||
buffer.encode_string(7, this->media_url);
|
buffer.encode_string(7, this->media_url);
|
||||||
|
buffer.encode_bool(8, this->has_announcement);
|
||||||
|
buffer.encode_bool(9, this->announcement);
|
||||||
}
|
}
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
void MediaPlayerCommandRequest::dump_to(std::string &out) const {
|
void MediaPlayerCommandRequest::dump_to(std::string &out) const {
|
||||||
@@ -5323,6 +5333,14 @@ void MediaPlayerCommandRequest::dump_to(std::string &out) const {
|
|||||||
out.append(" media_url: ");
|
out.append(" media_url: ");
|
||||||
out.append("'").append(this->media_url).append("'");
|
out.append("'").append(this->media_url).append("'");
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" has_announcement: ");
|
||||||
|
out.append(YESNO(this->has_announcement));
|
||||||
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" announcement: ");
|
||||||
|
out.append(YESNO(this->announcement));
|
||||||
|
out.append("\n");
|
||||||
out.append("}");
|
out.append("}");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1298,6 +1298,8 @@ class MediaPlayerCommandRequest : public ProtoMessage {
|
|||||||
float volume{0.0f};
|
float volume{0.0f};
|
||||||
bool has_media_url{false};
|
bool has_media_url{false};
|
||||||
std::string media_url{};
|
std::string media_url{};
|
||||||
|
bool has_announcement{false};
|
||||||
|
bool announcement{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
void dump_to(std::string &out) const override;
|
void dump_to(std::string &out) const override;
|
||||||
|
|||||||
@@ -14,15 +14,41 @@ CONF_HEX = "hex"
|
|||||||
|
|
||||||
|
|
||||||
def hex_color(value):
|
def hex_color(value):
|
||||||
|
if isinstance(value, int):
|
||||||
|
value = str(value)
|
||||||
|
if not isinstance(value, str):
|
||||||
|
raise cv.Invalid("Invalid value for hex color")
|
||||||
if len(value) != 6:
|
if len(value) != 6:
|
||||||
raise cv.Invalid("Color must have six digits")
|
raise cv.Invalid("Hex color must have six digits")
|
||||||
try:
|
try:
|
||||||
return (int(value[0:2], 16), int(value[2:4], 16), int(value[4:6], 16))
|
return int(value[0:2], 16), int(value[2:4], 16), int(value[4:6], 16)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise cv.Invalid("Color must be hexadecimal") from exc
|
raise cv.Invalid("Color must be hexadecimal") from exc
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.Any(
|
components = {
|
||||||
|
CONF_RED,
|
||||||
|
CONF_RED_INT,
|
||||||
|
CONF_GREEN,
|
||||||
|
CONF_GREEN_INT,
|
||||||
|
CONF_BLUE,
|
||||||
|
CONF_BLUE_INT,
|
||||||
|
CONF_WHITE,
|
||||||
|
CONF_WHITE_INT,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_color(config):
|
||||||
|
has_components = set(config) & components
|
||||||
|
has_hex = CONF_HEX in config
|
||||||
|
if has_hex and has_components:
|
||||||
|
raise cv.Invalid("Hex color value may not be combined with component values")
|
||||||
|
if not has_hex and not has_components:
|
||||||
|
raise cv.Invalid("Must provide at least one color option")
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
cv.Required(CONF_ID): cv.declare_id(ColorStruct),
|
cv.Required(CONF_ID): cv.declare_id(ColorStruct),
|
||||||
@@ -34,14 +60,10 @@ CONFIG_SCHEMA = cv.Any(
|
|||||||
cv.Exclusive(CONF_BLUE_INT, "blue"): cv.uint8_t,
|
cv.Exclusive(CONF_BLUE_INT, "blue"): cv.uint8_t,
|
||||||
cv.Exclusive(CONF_WHITE, "white"): cv.percentage,
|
cv.Exclusive(CONF_WHITE, "white"): cv.percentage,
|
||||||
cv.Exclusive(CONF_WHITE_INT, "white"): cv.uint8_t,
|
cv.Exclusive(CONF_WHITE_INT, "white"): cv.uint8_t,
|
||||||
|
cv.Optional(CONF_HEX): hex_color,
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA),
|
).extend(cv.COMPONENT_SCHEMA),
|
||||||
cv.Schema(
|
validate_color,
|
||||||
{
|
|
||||||
cv.Required(CONF_ID): cv.declare_id(ColorStruct),
|
|
||||||
cv.Required(CONF_HEX): hex_color,
|
|
||||||
}
|
|
||||||
).extend(cv.COMPONENT_SCHEMA),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ ARDUINO_PLATFORM_VERSION = cv.Version(5, 4, 0)
|
|||||||
# The default/recommended esp-idf framework version
|
# The default/recommended esp-idf framework version
|
||||||
# - https://github.com/espressif/esp-idf/releases
|
# - https://github.com/espressif/esp-idf/releases
|
||||||
# - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
|
# - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
|
||||||
RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 4, 6)
|
RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 4, 7)
|
||||||
# The platformio/espressif32 version to use for esp-idf frameworks
|
# The platformio/espressif32 version to use for esp-idf frameworks
|
||||||
# - https://github.com/platformio/platform-espressif32/releases
|
# - https://github.com/platformio/platform-espressif32/releases
|
||||||
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
|
# - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#include "ethernet_component.h"
|
#include "ethernet_component.h"
|
||||||
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/core/util.h"
|
#include "esphome/core/util.h"
|
||||||
#include "esphome/core/application.h"
|
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
#include <cinttypes>
|
|
||||||
#include <lwip/dns.h>
|
#include <lwip/dns.h>
|
||||||
|
#include <cinttypes>
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
|
||||||
#ifdef USE_ETHERNET_SPI
|
#ifdef USE_ETHERNET_SPI
|
||||||
@@ -184,6 +184,10 @@ void EthernetComponent::setup() {
|
|||||||
// KSZ8081RNA default is incorrect. It expects a 25MHz clock instead of the 50MHz we provide.
|
// KSZ8081RNA default is incorrect. It expects a 25MHz clock instead of the 50MHz we provide.
|
||||||
this->ksz8081_set_clock_reference_(mac);
|
this->ksz8081_set_clock_reference_(mac);
|
||||||
}
|
}
|
||||||
|
if (this->type_ == ETHERNET_TYPE_RTL8201 && this->clk_mode_ == EMAC_CLK_EXT_IN) {
|
||||||
|
// Change in default behavior of RTL8201FI may require register setting to enable external clock
|
||||||
|
this->rtl8201_set_rmii_mode_(mac);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// use ESP internal eth mac
|
// use ESP internal eth mac
|
||||||
@@ -554,9 +558,10 @@ bool EthernetComponent::powerdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_ETHERNET_SPI
|
#ifndef USE_ETHERNET_SPI
|
||||||
void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) {
|
|
||||||
#define KSZ80XX_PC2R_REG_ADDR (0x1F)
|
|
||||||
|
|
||||||
|
constexpr uint8_t KSZ80XX_PC2R_REG_ADDR = 0x1F;
|
||||||
|
|
||||||
|
void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) {
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
|
|
||||||
uint32_t phy_control_2;
|
uint32_t phy_control_2;
|
||||||
@@ -581,9 +586,47 @@ void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) {
|
|||||||
ESPHL_ERROR_CHECK(err, "Read PHY Control 2 failed");
|
ESPHL_ERROR_CHECK(err, "Read PHY Control 2 failed");
|
||||||
ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty((u_int8_t *) &phy_control_2, 2).c_str());
|
ESP_LOGVV(TAG, "KSZ8081 PHY Control 2: %s", format_hex_pretty((u_int8_t *) &phy_control_2, 2).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef KSZ80XX_PC2R_REG_ADDR
|
|
||||||
}
|
}
|
||||||
|
constexpr uint8_t RTL8201_RMSR_REG_ADDR = 0x10;
|
||||||
|
void EthernetComponent::rtl8201_set_rmii_mode_(esp_eth_mac_t *mac) {
|
||||||
|
esp_err_t err;
|
||||||
|
uint32_t phy_rmii_mode;
|
||||||
|
err = mac->write_phy_reg(mac, this->phy_addr_, 0x1f, 0x07);
|
||||||
|
ESPHL_ERROR_CHECK(err, "Setting Page 7 failed");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RTL8201 RMII Mode Setting Register (RMSR)
|
||||||
|
* Page 7 Register 16
|
||||||
|
*
|
||||||
|
* bit 0 Reserved 0
|
||||||
|
* bit 1 Rg_rmii_rxdsel 1 (default)
|
||||||
|
* bit 2 Rg_rmii_rxdv_sel: 0 (default)
|
||||||
|
* bit 3 RMII Mode: 1 (RMII Mode)
|
||||||
|
* bit 4~7 Rg_rmii_rx_offset: 1111 (default)
|
||||||
|
* bit 8~11 Rg_rmii_tx_offset: 1111 (default)
|
||||||
|
* bit 12 Rg_rmii_clkdir: 1 (Input)
|
||||||
|
* bit 13~15 Reserved 000
|
||||||
|
*
|
||||||
|
* Binary: 0001 1111 1111 1010
|
||||||
|
* Hex: 0x1FFA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
err = mac->read_phy_reg(mac, this->phy_addr_, RTL8201_RMSR_REG_ADDR, &(phy_rmii_mode));
|
||||||
|
ESPHL_ERROR_CHECK(err, "Read PHY RMSR Register failed");
|
||||||
|
ESP_LOGV(TAG, "Hardware default RTL8201 RMII Mode Register is: 0x%04X", phy_rmii_mode);
|
||||||
|
|
||||||
|
err = mac->write_phy_reg(mac, this->phy_addr_, RTL8201_RMSR_REG_ADDR, 0x1FFA);
|
||||||
|
ESPHL_ERROR_CHECK(err, "Setting Register 16 RMII Mode Setting failed");
|
||||||
|
|
||||||
|
err = mac->read_phy_reg(mac, this->phy_addr_, RTL8201_RMSR_REG_ADDR, &(phy_rmii_mode));
|
||||||
|
ESPHL_ERROR_CHECK(err, "Read PHY RMSR Register failed");
|
||||||
|
ESP_LOGV(TAG, "Setting RTL8201 RMII Mode Register to: 0x%04X", phy_rmii_mode);
|
||||||
|
|
||||||
|
err = mac->write_phy_reg(mac, this->phy_addr_, 0x1f, 0x0);
|
||||||
|
ESPHL_ERROR_CHECK(err, "Setting Page 0 failed");
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace ethernet
|
} // namespace ethernet
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ class EthernetComponent : public Component {
|
|||||||
void dump_connect_params_();
|
void dump_connect_params_();
|
||||||
/// @brief Set `RMII Reference Clock Select` bit for KSZ8081.
|
/// @brief Set `RMII Reference Clock Select` bit for KSZ8081.
|
||||||
void ksz8081_set_clock_reference_(esp_eth_mac_t *mac);
|
void ksz8081_set_clock_reference_(esp_eth_mac_t *mac);
|
||||||
|
/// @brief Set `RMII Mode Setting Register` for RTL8201.
|
||||||
|
void rtl8201_set_rmii_mode_(esp_eth_mac_t *mac);
|
||||||
|
|
||||||
std::string use_address_;
|
std::string use_address_;
|
||||||
#ifdef USE_ETHERNET_SPI
|
#ifdef USE_ETHERNET_SPI
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ namespace i2s_audio {
|
|||||||
static const char *const TAG = "audio";
|
static const char *const TAG = "audio";
|
||||||
|
|
||||||
void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) {
|
void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) {
|
||||||
|
media_player::MediaPlayerState play_state = media_player::MEDIA_PLAYER_STATE_PLAYING;
|
||||||
|
if (call.get_announcement().has_value()) {
|
||||||
|
play_state = call.get_announcement().value() ? media_player::MEDIA_PLAYER_STATE_ANNOUNCING
|
||||||
|
: media_player::MEDIA_PLAYER_STATE_PLAYING;
|
||||||
|
}
|
||||||
if (call.get_media_url().has_value()) {
|
if (call.get_media_url().has_value()) {
|
||||||
this->current_url_ = call.get_media_url();
|
this->current_url_ = call.get_media_url();
|
||||||
if (this->i2s_state_ != I2S_STATE_STOPPED && this->audio_ != nullptr) {
|
if (this->i2s_state_ != I2S_STATE_STOPPED && this->audio_ != nullptr) {
|
||||||
@@ -17,7 +22,7 @@ void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) {
|
|||||||
this->audio_->stopSong();
|
this->audio_->stopSong();
|
||||||
}
|
}
|
||||||
this->audio_->connecttohost(this->current_url_.value().c_str());
|
this->audio_->connecttohost(this->current_url_.value().c_str());
|
||||||
this->state = media_player::MEDIA_PLAYER_STATE_PLAYING;
|
this->state = play_state;
|
||||||
} else {
|
} else {
|
||||||
this->start();
|
this->start();
|
||||||
}
|
}
|
||||||
@@ -35,7 +40,7 @@ void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) {
|
|||||||
case media_player::MEDIA_PLAYER_COMMAND_PLAY:
|
case media_player::MEDIA_PLAYER_COMMAND_PLAY:
|
||||||
if (!this->audio_->isRunning())
|
if (!this->audio_->isRunning())
|
||||||
this->audio_->pauseResume();
|
this->audio_->pauseResume();
|
||||||
this->state = media_player::MEDIA_PLAYER_STATE_PLAYING;
|
this->state = play_state;
|
||||||
break;
|
break;
|
||||||
case media_player::MEDIA_PLAYER_COMMAND_PAUSE:
|
case media_player::MEDIA_PLAYER_COMMAND_PAUSE:
|
||||||
if (this->audio_->isRunning())
|
if (this->audio_->isRunning())
|
||||||
@@ -126,7 +131,9 @@ void I2SAudioMediaPlayer::loop() {
|
|||||||
|
|
||||||
void I2SAudioMediaPlayer::play_() {
|
void I2SAudioMediaPlayer::play_() {
|
||||||
this->audio_->loop();
|
this->audio_->loop();
|
||||||
if (this->state == media_player::MEDIA_PLAYER_STATE_PLAYING && !this->audio_->isRunning()) {
|
if ((this->state == media_player::MEDIA_PLAYER_STATE_PLAYING ||
|
||||||
|
this->state == media_player::MEDIA_PLAYER_STATE_ANNOUNCING) &&
|
||||||
|
!this->audio_->isRunning()) {
|
||||||
this->stop();
|
this->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,6 +171,10 @@ void I2SAudioMediaPlayer::start_() {
|
|||||||
if (this->current_url_.has_value()) {
|
if (this->current_url_.has_value()) {
|
||||||
this->audio_->connecttohost(this->current_url_.value().c_str());
|
this->audio_->connecttohost(this->current_url_.value().c_str());
|
||||||
this->state = media_player::MEDIA_PLAYER_STATE_PLAYING;
|
this->state = media_player::MEDIA_PLAYER_STATE_PLAYING;
|
||||||
|
if (this->is_announcement_.has_value()) {
|
||||||
|
this->state = this->is_announcement_.value() ? media_player::MEDIA_PLAYER_STATE_ANNOUNCING
|
||||||
|
: media_player::MEDIA_PLAYER_STATE_PLAYING;
|
||||||
|
}
|
||||||
this->publish_state();
|
this->publish_state();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class I2SAudioMediaPlayer : public Component, public media_player::MediaPlayer,
|
|||||||
HighFrequencyLoopRequester high_freq_;
|
HighFrequencyLoopRequester high_freq_;
|
||||||
|
|
||||||
optional<std::string> current_url_{};
|
optional<std::string> current_url_{};
|
||||||
|
optional<bool> is_announcement_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace i2s_audio
|
} // namespace i2s_audio
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ namespace ltr390 {
|
|||||||
|
|
||||||
static const char *const TAG = "ltr390";
|
static const char *const TAG = "ltr390";
|
||||||
|
|
||||||
|
static const uint8_t LTR390_WAKEUP_TIME = 10;
|
||||||
|
static const uint8_t LTR390_SETTLE_TIME = 5;
|
||||||
|
|
||||||
static const uint8_t LTR390_MAIN_CTRL = 0x00;
|
static const uint8_t LTR390_MAIN_CTRL = 0x00;
|
||||||
static const uint8_t LTR390_MEAS_RATE = 0x04;
|
static const uint8_t LTR390_MEAS_RATE = 0x04;
|
||||||
static const uint8_t LTR390_GAIN = 0x05;
|
static const uint8_t LTR390_GAIN = 0x05;
|
||||||
@@ -101,10 +104,12 @@ void LTR390Component::read_mode_(int mode_index) {
|
|||||||
|
|
||||||
std::bitset<8> ctrl = this->reg(LTR390_MAIN_CTRL).get();
|
std::bitset<8> ctrl = this->reg(LTR390_MAIN_CTRL).get();
|
||||||
ctrl[LTR390_CTRL_MODE] = mode;
|
ctrl[LTR390_CTRL_MODE] = mode;
|
||||||
|
ctrl[LTR390_CTRL_EN] = true;
|
||||||
this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
|
this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
|
||||||
|
|
||||||
// After the sensor integration time do the following
|
// After the sensor integration time do the following
|
||||||
this->set_timeout(((uint32_t) RESOLUTIONVALUE[this->res_]) * 100, [this, mode_index]() {
|
this->set_timeout(((uint32_t) RESOLUTIONVALUE[this->res_]) * 100 + LTR390_WAKEUP_TIME + LTR390_SETTLE_TIME,
|
||||||
|
[this, mode_index]() {
|
||||||
// Read from the sensor
|
// Read from the sensor
|
||||||
std::get<1>(this->mode_funcs_[mode_index])();
|
std::get<1>(this->mode_funcs_[mode_index])();
|
||||||
|
|
||||||
@@ -113,6 +118,10 @@ void LTR390Component::read_mode_(int mode_index) {
|
|||||||
if (mode_index + 1 < (int) this->mode_funcs_.size()) {
|
if (mode_index + 1 < (int) this->mode_funcs_.size()) {
|
||||||
this->read_mode_(mode_index + 1);
|
this->read_mode_(mode_index + 1);
|
||||||
} else {
|
} else {
|
||||||
|
// put sensor in standby
|
||||||
|
std::bitset<8> ctrl = this->reg(LTR390_MAIN_CTRL).get();
|
||||||
|
ctrl[LTR390_CTRL_EN] = false;
|
||||||
|
this->reg(LTR390_MAIN_CTRL) = ctrl.to_ulong();
|
||||||
this->reading_ = false;
|
this->reading_ = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -51,12 +51,16 @@ VolumeSetAction = media_player_ns.class_(
|
|||||||
|
|
||||||
CONF_ON_PLAY = "on_play"
|
CONF_ON_PLAY = "on_play"
|
||||||
CONF_ON_PAUSE = "on_pause"
|
CONF_ON_PAUSE = "on_pause"
|
||||||
|
CONF_ON_ANNOUNCEMENT = "on_announcement"
|
||||||
CONF_MEDIA_URL = "media_url"
|
CONF_MEDIA_URL = "media_url"
|
||||||
|
|
||||||
StateTrigger = media_player_ns.class_("StateTrigger", automation.Trigger.template())
|
StateTrigger = media_player_ns.class_("StateTrigger", automation.Trigger.template())
|
||||||
IdleTrigger = media_player_ns.class_("IdleTrigger", automation.Trigger.template())
|
IdleTrigger = media_player_ns.class_("IdleTrigger", automation.Trigger.template())
|
||||||
PlayTrigger = media_player_ns.class_("PlayTrigger", automation.Trigger.template())
|
PlayTrigger = media_player_ns.class_("PlayTrigger", automation.Trigger.template())
|
||||||
PauseTrigger = media_player_ns.class_("PauseTrigger", automation.Trigger.template())
|
PauseTrigger = media_player_ns.class_("PauseTrigger", automation.Trigger.template())
|
||||||
|
AnnoucementTrigger = media_player_ns.class_(
|
||||||
|
"AnnouncementTrigger", automation.Trigger.template()
|
||||||
|
)
|
||||||
IsIdleCondition = media_player_ns.class_("IsIdleCondition", automation.Condition)
|
IsIdleCondition = media_player_ns.class_("IsIdleCondition", automation.Condition)
|
||||||
IsPlayingCondition = media_player_ns.class_("IsPlayingCondition", automation.Condition)
|
IsPlayingCondition = media_player_ns.class_("IsPlayingCondition", automation.Condition)
|
||||||
|
|
||||||
@@ -75,6 +79,9 @@ async def setup_media_player_core_(var, config):
|
|||||||
for conf in config.get(CONF_ON_PAUSE, []):
|
for conf in config.get(CONF_ON_PAUSE, []):
|
||||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
await automation.build_automation(trigger, [], conf)
|
await automation.build_automation(trigger, [], conf)
|
||||||
|
for conf in config.get(CONF_ON_ANNOUNCEMENT, []):
|
||||||
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
|
await automation.build_automation(trigger, [], conf)
|
||||||
|
|
||||||
|
|
||||||
async def register_media_player(var, config):
|
async def register_media_player(var, config):
|
||||||
@@ -106,6 +113,11 @@ MEDIA_PLAYER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
|
|||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PauseTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PauseTrigger),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_ON_ANNOUNCEMENT): automation.validate_automation(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(AnnoucementTrigger),
|
||||||
|
}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class StateTrigger : public Trigger<> {
|
|||||||
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(IdleTrigger, IDLE)
|
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(IdleTrigger, IDLE)
|
||||||
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(PlayTrigger, PLAYING)
|
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(PlayTrigger, PLAYING)
|
||||||
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(PauseTrigger, PAUSED)
|
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(PauseTrigger, PAUSED)
|
||||||
|
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(AnnouncementTrigger, ANNOUNCING)
|
||||||
|
|
||||||
template<typename... Ts> class IsIdleCondition : public Condition<Ts...>, public Parented<MediaPlayer> {
|
template<typename... Ts> class IsIdleCondition : public Condition<Ts...>, public Parented<MediaPlayer> {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ const char *media_player_state_to_string(MediaPlayerState state) {
|
|||||||
return "PLAYING";
|
return "PLAYING";
|
||||||
case MEDIA_PLAYER_STATE_PAUSED:
|
case MEDIA_PLAYER_STATE_PAUSED:
|
||||||
return "PAUSED";
|
return "PAUSED";
|
||||||
|
case MEDIA_PLAYER_STATE_ANNOUNCING:
|
||||||
|
return "ANNOUNCING";
|
||||||
case MEDIA_PLAYER_STATE_NONE:
|
case MEDIA_PLAYER_STATE_NONE:
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
@@ -68,6 +70,9 @@ void MediaPlayerCall::perform() {
|
|||||||
if (this->volume_.has_value()) {
|
if (this->volume_.has_value()) {
|
||||||
ESP_LOGD(TAG, " Volume: %.2f", this->volume_.value());
|
ESP_LOGD(TAG, " Volume: %.2f", this->volume_.value());
|
||||||
}
|
}
|
||||||
|
if (this->announcement_.has_value()) {
|
||||||
|
ESP_LOGD(TAG, " Announcement: %s", this->announcement_.value() ? "yes" : "no");
|
||||||
|
}
|
||||||
this->parent_->control(*this);
|
this->parent_->control(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +113,11 @@ MediaPlayerCall &MediaPlayerCall::set_volume(float volume) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaPlayerCall &MediaPlayerCall::set_announcement(bool announce) {
|
||||||
|
this->announcement_ = announce;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void MediaPlayer::add_on_state_callback(std::function<void()> &&callback) {
|
void MediaPlayer::add_on_state_callback(std::function<void()> &&callback) {
|
||||||
this->state_callback_.add(std::move(callback));
|
this->state_callback_.add(std::move(callback));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ enum MediaPlayerState : uint8_t {
|
|||||||
MEDIA_PLAYER_STATE_NONE = 0,
|
MEDIA_PLAYER_STATE_NONE = 0,
|
||||||
MEDIA_PLAYER_STATE_IDLE = 1,
|
MEDIA_PLAYER_STATE_IDLE = 1,
|
||||||
MEDIA_PLAYER_STATE_PLAYING = 2,
|
MEDIA_PLAYER_STATE_PLAYING = 2,
|
||||||
MEDIA_PLAYER_STATE_PAUSED = 3
|
MEDIA_PLAYER_STATE_PAUSED = 3,
|
||||||
|
MEDIA_PLAYER_STATE_ANNOUNCING = 4
|
||||||
};
|
};
|
||||||
const char *media_player_state_to_string(MediaPlayerState state);
|
const char *media_player_state_to_string(MediaPlayerState state);
|
||||||
|
|
||||||
@@ -51,12 +52,14 @@ class MediaPlayerCall {
|
|||||||
MediaPlayerCall &set_media_url(const std::string &url);
|
MediaPlayerCall &set_media_url(const std::string &url);
|
||||||
|
|
||||||
MediaPlayerCall &set_volume(float volume);
|
MediaPlayerCall &set_volume(float volume);
|
||||||
|
MediaPlayerCall &set_announcement(bool announce);
|
||||||
|
|
||||||
void perform();
|
void perform();
|
||||||
|
|
||||||
const optional<MediaPlayerCommand> &get_command() const { return command_; }
|
const optional<MediaPlayerCommand> &get_command() const { return command_; }
|
||||||
const optional<std::string> &get_media_url() const { return media_url_; }
|
const optional<std::string> &get_media_url() const { return media_url_; }
|
||||||
const optional<float> &get_volume() const { return volume_; }
|
const optional<float> &get_volume() const { return volume_; }
|
||||||
|
const optional<bool> &get_announcement() const { return announcement_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void validate_();
|
void validate_();
|
||||||
@@ -64,6 +67,7 @@ class MediaPlayerCall {
|
|||||||
optional<MediaPlayerCommand> command_;
|
optional<MediaPlayerCommand> command_;
|
||||||
optional<std::string> media_url_;
|
optional<std::string> media_url_;
|
||||||
optional<float> volume_;
|
optional<float> volume_;
|
||||||
|
optional<bool> announcement_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MediaPlayer : public EntityBase {
|
class MediaPlayer : public EntityBase {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "esphome/components/display/display_color_utils.h"
|
#include "esphome/components/display/display_color_utils.h"
|
||||||
|
|
||||||
#ifdef USE_NEXTION_TFT_UPLOAD
|
#ifdef USE_NEXTION_TFT_UPLOAD
|
||||||
#ifdef ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#endif // USE_ESP32
|
#endif // USE_ESP32
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
#endif // USE_ESP8266
|
#endif // USE_ESP8266
|
||||||
#elif defined(USE_ESP_IDF)
|
#elif defined(USE_ESP_IDF)
|
||||||
#include <esp_http_client.h>
|
#include <esp_http_client.h>
|
||||||
#endif // ARDUINO vs ESP-IDF
|
#endif // ARDUINO vs USE_ESP_IDF
|
||||||
#endif // USE_NEXTION_TFT_UPLOAD
|
#endif // USE_NEXTION_TFT_UPLOAD
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
@@ -987,7 +987,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
|
|||||||
|
|
||||||
#ifdef USE_NEXTION_TFT_UPLOAD
|
#ifdef USE_NEXTION_TFT_UPLOAD
|
||||||
/**
|
/**
|
||||||
* Set the tft file URL. https seems problematic with arduino..
|
* Set the tft file URL. https seems problematic with Arduino..
|
||||||
*/
|
*/
|
||||||
void set_tft_url(const std::string &tft_url) { this->tft_url_ = tft_url; }
|
void set_tft_url(const std::string &tft_url) { this->tft_url_ = tft_url; }
|
||||||
|
|
||||||
@@ -1190,7 +1190,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
|
|||||||
uint32_t original_baud_rate_ = 0;
|
uint32_t original_baud_rate_ = 0;
|
||||||
bool upload_first_chunk_sent_ = false;
|
bool upload_first_chunk_sent_ = false;
|
||||||
|
|
||||||
#ifdef ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
/**
|
/**
|
||||||
* will request chunk_size chunks from the web server
|
* will request chunk_size chunks from the web server
|
||||||
* and send each to the nextion
|
* and send each to the nextion
|
||||||
@@ -1208,7 +1208,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
|
|||||||
* @return position of last byte transferred, -1 for failure.
|
* @return position of last byte transferred, -1 for failure.
|
||||||
*/
|
*/
|
||||||
int upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &range_start);
|
int upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &range_start);
|
||||||
#endif // ARDUINO vs USE_ESP_IDF
|
#endif // USE_ARDUINO vs USE_ESP_IDF
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ends the upload process, restart Nextion and, if successful,
|
* Ends the upload process, restart Nextion and, if successful,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "nextion.h"
|
#include "nextion.h"
|
||||||
|
|
||||||
#ifdef USE_NEXTION_TFT_UPLOAD
|
#ifdef USE_NEXTION_TFT_UPLOAD
|
||||||
#ifdef ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/defines.h"
|
#include "esphome/core/defines.h"
|
||||||
@@ -383,5 +383,5 @@ WiFiClient *Nextion::get_wifi_client_() {
|
|||||||
} // namespace nextion
|
} // namespace nextion
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
#endif // ARDUINO
|
#endif // USE_ARDUINO
|
||||||
#endif // USE_NEXTION_TFT_UPLOAD
|
#endif // USE_NEXTION_TFT_UPLOAD
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
|
|||||||
void decode_rmt_(rmt_item32_t *item, size_t len);
|
void decode_rmt_(rmt_item32_t *item, size_t len);
|
||||||
RingbufHandle_t ringbuf_;
|
RingbufHandle_t ringbuf_;
|
||||||
esp_err_t error_code_{ESP_OK};
|
esp_err_t error_code_{ESP_OK};
|
||||||
|
std::string error_string_{""};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_ESP8266) || defined(USE_LIBRETINY)
|
#if defined(USE_ESP8266) || defined(USE_LIBRETINY)
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ void RemoteReceiverComponent::setup() {
|
|||||||
esp_err_t error = rmt_config(&rmt);
|
esp_err_t error = rmt_config(&rmt);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_config";
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -36,18 +37,25 @@ void RemoteReceiverComponent::setup() {
|
|||||||
error = rmt_driver_install(this->channel_, this->buffer_size_, 0);
|
error = rmt_driver_install(this->channel_, this->buffer_size_, 0);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
if (error == ESP_ERR_INVALID_STATE) {
|
||||||
|
this->error_string_ = str_sprintf("RMT channel %i is already in use by another component", this->channel_);
|
||||||
|
} else {
|
||||||
|
this->error_string_ = "in rmt_driver_install";
|
||||||
|
}
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
error = rmt_get_ringbuf_handle(this->channel_, &this->ringbuf_);
|
error = rmt_get_ringbuf_handle(this->channel_, &this->ringbuf_);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_get_ringbuf_handle";
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
error = rmt_rx_start(this->channel_, true);
|
error = rmt_rx_start(this->channel_, true);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_rx_start";
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -67,7 +75,8 @@ void RemoteReceiverComponent::dump_config() {
|
|||||||
ESP_LOGCONFIG(TAG, " Filter out pulses shorter than: %" PRIu32 " us", this->filter_us_);
|
ESP_LOGCONFIG(TAG, " Filter out pulses shorter than: %" PRIu32 " us", this->filter_us_);
|
||||||
ESP_LOGCONFIG(TAG, " Signal is done after %" PRIu32 " us of no changes", this->idle_us_);
|
ESP_LOGCONFIG(TAG, " Signal is done after %" PRIu32 " us of no changes", this->idle_us_);
|
||||||
if (this->is_failed()) {
|
if (this->is_failed()) {
|
||||||
ESP_LOGE(TAG, "Configuring RMT driver failed: %s", esp_err_to_name(this->error_code_));
|
ESP_LOGE(TAG, "Configuring RMT driver failed: %s (%s)", esp_err_to_name(this->error_code_),
|
||||||
|
this->error_string_.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
|
|||||||
bool initialized_{false};
|
bool initialized_{false};
|
||||||
std::vector<rmt_item32_t> rmt_temp_;
|
std::vector<rmt_item32_t> rmt_temp_;
|
||||||
esp_err_t error_code_{ESP_OK};
|
esp_err_t error_code_{ESP_OK};
|
||||||
|
std::string error_string_{""};
|
||||||
bool inverted_{false};
|
bool inverted_{false};
|
||||||
#endif
|
#endif
|
||||||
uint8_t carrier_duty_percent_;
|
uint8_t carrier_duty_percent_;
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ void RemoteTransmitterComponent::dump_config() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->is_failed()) {
|
if (this->is_failed()) {
|
||||||
ESP_LOGE(TAG, "Configuring RMT driver failed: %s", esp_err_to_name(this->error_code_));
|
ESP_LOGE(TAG, "Configuring RMT driver failed: %s (%s)", esp_err_to_name(this->error_code_),
|
||||||
|
this->error_string_.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ void RemoteTransmitterComponent::configure_rmt_() {
|
|||||||
esp_err_t error = rmt_config(&c);
|
esp_err_t error = rmt_config(&c);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
this->error_string_ = "in rmt_config";
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -64,6 +66,11 @@ void RemoteTransmitterComponent::configure_rmt_() {
|
|||||||
error = rmt_driver_install(this->channel_, 0, 0);
|
error = rmt_driver_install(this->channel_, 0, 0);
|
||||||
if (error != ESP_OK) {
|
if (error != ESP_OK) {
|
||||||
this->error_code_ = error;
|
this->error_code_ = error;
|
||||||
|
if (error == ESP_ERR_INVALID_STATE) {
|
||||||
|
this->error_string_ = str_sprintf("RMT channel %i is already in use by another component", this->channel_);
|
||||||
|
} else {
|
||||||
|
this->error_string_ = "in rmt_driver_install";
|
||||||
|
}
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ void VoiceAssistant::loop() {
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
this->set_state_(State::START_PIPELINE, State::START_MICROPHONE);
|
this->set_state_(State::START_MICROPHONE, State::START_PIPELINE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->high_freq_.stop();
|
this->high_freq_.stop();
|
||||||
@@ -318,7 +318,7 @@ void VoiceAssistant::loop() {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
if (this->media_player_ != nullptr) {
|
if (this->media_player_ != nullptr) {
|
||||||
playing = (this->media_player_->state == media_player::MediaPlayerState::MEDIA_PLAYER_STATE_PLAYING);
|
playing = (this->media_player_->state == media_player::MediaPlayerState::MEDIA_PLAYER_STATE_ANNOUNCING);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (playing) {
|
if (playing) {
|
||||||
@@ -514,7 +514,7 @@ void VoiceAssistant::request_start(bool continuous, bool silence_detection) {
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
this->set_state_(State::START_PIPELINE, State::START_MICROPHONE);
|
this->set_state_(State::START_MICROPHONE, State::START_PIPELINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -640,7 +640,7 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
|
|||||||
this->defer([this, url]() {
|
this->defer([this, url]() {
|
||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
if (this->media_player_ != nullptr) {
|
if (this->media_player_ != nullptr) {
|
||||||
this->media_player_->make_call().set_media_url(url).perform();
|
this->media_player_->make_call().set_media_url(url).set_announcement(true).perform();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
this->tts_end_trigger_->trigger(url);
|
this->tts_end_trigger_->trigger(url);
|
||||||
|
|||||||
@@ -94,10 +94,10 @@ class VoiceAssistant : public Component {
|
|||||||
uint32_t get_feature_flags() const {
|
uint32_t get_feature_flags() const {
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
flags |= VoiceAssistantFeature::FEATURE_VOICE_ASSISTANT;
|
flags |= VoiceAssistantFeature::FEATURE_VOICE_ASSISTANT;
|
||||||
|
flags |= VoiceAssistantFeature::FEATURE_API_AUDIO;
|
||||||
#ifdef USE_SPEAKER
|
#ifdef USE_SPEAKER
|
||||||
if (this->speaker_ != nullptr) {
|
if (this->speaker_ != nullptr) {
|
||||||
flags |= VoiceAssistantFeature::FEATURE_SPEAKER;
|
flags |= VoiceAssistantFeature::FEATURE_SPEAKER;
|
||||||
flags |= VoiceAssistantFeature::FEATURE_API_AUDIO;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return flags;
|
return flags;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2024.5.0b1"
|
__version__ = "2024.5.0b5"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS = (
|
VALID_SUBSTITUTIONS_CHARACTERS = (
|
||||||
|
|||||||
@@ -340,6 +340,8 @@ class ID:
|
|||||||
|
|
||||||
if self.id is None:
|
if self.id is None:
|
||||||
base = str(self.type).replace("::", "_").lower()
|
base = str(self.type).replace("::", "_").lower()
|
||||||
|
if base == self.type:
|
||||||
|
base = base + "_id"
|
||||||
name = "".join(c for c in base if c.isalnum() or c == "_")
|
name = "".join(c for c in base if c.isalnum() or c == "_")
|
||||||
used = set(registered_ids) | set(RESERVED_IDS) | CORE.loaded_integrations
|
used = set(registered_ids) | set(RESERVED_IDS) | CORE.loaded_integrations
|
||||||
self.id = ensure_unique_string(name, used)
|
self.id = ensure_unique_string(name, used)
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ async def to_code(config):
|
|||||||
if project_conf := config.get(CONF_PROJECT):
|
if project_conf := config.get(CONF_PROJECT):
|
||||||
cg.add_define("ESPHOME_PROJECT_NAME", project_conf[CONF_NAME])
|
cg.add_define("ESPHOME_PROJECT_NAME", project_conf[CONF_NAME])
|
||||||
cg.add_define("ESPHOME_PROJECT_VERSION", project_conf[CONF_VERSION])
|
cg.add_define("ESPHOME_PROJECT_VERSION", project_conf[CONF_VERSION])
|
||||||
cg.add_define("ESPHOME_PROJECT_VERSION_30", project_conf[CONF_VERSION][:30])
|
cg.add_define("ESPHOME_PROJECT_VERSION_30", project_conf[CONF_VERSION][:29])
|
||||||
for conf in project_conf.get(CONF_ON_UPDATE, []):
|
for conf in project_conf.get(CONF_ON_UPDATE, []):
|
||||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
|
||||||
await cg.register_component(trigger, conf)
|
await cg.register_component(trigger, conf)
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ extra_scripts = post:esphome/components/esp32/post_build.py.script
|
|||||||
extends = common:idf
|
extends = common:idf
|
||||||
platform = platformio/espressif32@5.4.0
|
platform = platformio/espressif32@5.4.0
|
||||||
platform_packages =
|
platform_packages =
|
||||||
platformio/framework-espidf@~3.40406.0
|
platformio/framework-espidf@~3.40407.0
|
||||||
|
|
||||||
framework = espidf
|
framework = espidf
|
||||||
lib_deps =
|
lib_deps =
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ tornado==6.4
|
|||||||
tzlocal==5.2 # from time
|
tzlocal==5.2 # from time
|
||||||
tzdata>=2021.1 # from time
|
tzdata>=2021.1 # from time
|
||||||
pyserial==3.5
|
pyserial==3.5
|
||||||
platformio==6.1.13 # When updating platformio, also update Dockerfile
|
platformio==6.1.15 # When updating platformio, also update Dockerfile
|
||||||
esptool==4.7.0
|
esptool==4.7.0
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
esphome-dashboard==20240412.0
|
esphome-dashboard==20240412.0
|
||||||
|
|||||||
@@ -9,3 +9,12 @@ color:
|
|||||||
blue: 100%
|
blue: 100%
|
||||||
- id: kbx_green
|
- id: kbx_green
|
||||||
hex: "3DEC55"
|
hex: "3DEC55"
|
||||||
|
- id: kbx_green_1
|
||||||
|
hex: 3DEC55
|
||||||
|
- id: cps_red
|
||||||
|
hex: 800000
|
||||||
|
- id: cps_green
|
||||||
|
hex: 008000
|
||||||
|
- id: cps_blue
|
||||||
|
hex: 000080
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user