mirror of
https://github.com/esphome/esphome.git
synced 2025-11-05 01:21:50 +00:00
Compare commits
97 Commits
2022.6.0b2
...
2022.6.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab86ddcf02 | ||
|
|
bf8eddb13b | ||
|
|
e5eaf7a3fe | ||
|
|
50f32a3aa5 | ||
|
|
eb878710c1 | ||
|
|
311980e0e4 | ||
|
|
df73170e5a | ||
|
|
ccc13cc9e1 | ||
|
|
020b2c05c8 | ||
|
|
4c37c17df1 | ||
|
|
8f67acadd8 | ||
|
|
ca13c4c1a6 | ||
|
|
d0c646c721 | ||
|
|
8a055675af | ||
|
|
f329c74a15 | ||
|
|
7c86f3fa9e | ||
|
|
203b8b01bf | ||
|
|
8a1034a92f | ||
|
|
aa0c2dedd9 | ||
|
|
8c9948bb56 | ||
|
|
2d1abaa68e | ||
|
|
664a3df0b4 | ||
|
|
9ff893881c | ||
|
|
94f6c6861a | ||
|
|
b1d614e6c4 | ||
|
|
7fceb070e5 | ||
|
|
5c7c0834c0 | ||
|
|
f3a25de11d | ||
|
|
041bef8bcd | ||
|
|
77f322166e | ||
|
|
f3f6e54818 | ||
|
|
fb0fec1f25 | ||
|
|
b66af9fb4d | ||
|
|
6617d576a7 | ||
|
|
420dacb22d | ||
|
|
ae2f6ad4d1 | ||
|
|
2c28d79bf8 | ||
|
|
993044c870 | ||
|
|
a8c1b63edb | ||
|
|
db7d946e1b | ||
|
|
fc7348d46d | ||
|
|
8be2456c7e | ||
|
|
bb5f7249a6 | ||
|
|
fc94a5d0ee | ||
|
|
24029cc918 | ||
|
|
9a9d5964ee | ||
|
|
4e4a512107 | ||
|
|
0729ed538e | ||
|
|
24b75b7ed6 | ||
|
|
ec3618ecb8 | ||
|
|
792a24f38d | ||
|
|
652e8a015b | ||
|
|
1ef6fd8fb0 | ||
|
|
942b0de7fd | ||
|
|
859cca49d1 | ||
|
|
8f7ff25624 | ||
|
|
97aca8e54c | ||
|
|
95acf19067 | ||
|
|
3d0899aa58 | ||
|
|
138d6e505b | ||
|
|
2748e6ba29 | ||
|
|
dbd4e927d8 | ||
|
|
e73d47918f | ||
|
|
b881bc071e | ||
|
|
1d0395d1c7 | ||
|
|
616c787e37 | ||
|
|
0c4de2bc97 | ||
|
|
c2f5ac9eba | ||
|
|
5764c988af | ||
|
|
ccc2fbfd67 | ||
|
|
10b4adb8e6 | ||
|
|
83b7181bcb | ||
|
|
8886b7e141 | ||
|
|
7dcc4d030b | ||
|
|
b9398897c1 | ||
|
|
657b1c60ae | ||
|
|
dc54b17778 | ||
|
|
1fb214165b | ||
|
|
81b2fd78f5 | ||
|
|
69002fb1e6 | ||
|
|
75332a752d | ||
|
|
09ed1aed93 | ||
|
|
53d3718028 | ||
|
|
2b5dce5232 | ||
|
|
9ad84150aa | ||
|
|
c0523590b4 | ||
|
|
c7f091ab10 | ||
|
|
7479e0aada | ||
|
|
5bbee1a1fe | ||
|
|
bdb9546ca3 | ||
|
|
46af4cad6e | ||
|
|
76a238912b | ||
|
|
909a526967 | ||
|
|
cd6f4fb93f | ||
|
|
c19458696e | ||
|
|
318b930e9f | ||
|
|
9296a078a7 |
@@ -29,6 +29,7 @@ from esphome.const import (
|
|||||||
DEVICE_CLASS_EMPTY,
|
DEVICE_CLASS_EMPTY,
|
||||||
DEVICE_CLASS_BATTERY,
|
DEVICE_CLASS_BATTERY,
|
||||||
DEVICE_CLASS_BATTERY_CHARGING,
|
DEVICE_CLASS_BATTERY_CHARGING,
|
||||||
|
DEVICE_CLASS_CARBON_MONOXIDE,
|
||||||
DEVICE_CLASS_COLD,
|
DEVICE_CLASS_COLD,
|
||||||
DEVICE_CLASS_CONNECTIVITY,
|
DEVICE_CLASS_CONNECTIVITY,
|
||||||
DEVICE_CLASS_DOOR,
|
DEVICE_CLASS_DOOR,
|
||||||
@@ -63,6 +64,7 @@ DEVICE_CLASSES = [
|
|||||||
DEVICE_CLASS_EMPTY,
|
DEVICE_CLASS_EMPTY,
|
||||||
DEVICE_CLASS_BATTERY,
|
DEVICE_CLASS_BATTERY,
|
||||||
DEVICE_CLASS_BATTERY_CHARGING,
|
DEVICE_CLASS_BATTERY_CHARGING,
|
||||||
|
DEVICE_CLASS_CARBON_MONOXIDE,
|
||||||
DEVICE_CLASS_COLD,
|
DEVICE_CLASS_COLD,
|
||||||
DEVICE_CLASS_CONNECTIVITY,
|
DEVICE_CLASS_CONNECTIVITY,
|
||||||
DEVICE_CLASS_DOOR,
|
DEVICE_CLASS_DOOR,
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ void BLEClient::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t es
|
|||||||
}
|
}
|
||||||
case ESP_GATTC_OPEN_EVT: {
|
case ESP_GATTC_OPEN_EVT: {
|
||||||
ESP_LOGV(TAG, "[%s] ESP_GATTC_OPEN_EVT", this->address_str().c_str());
|
ESP_LOGV(TAG, "[%s] ESP_GATTC_OPEN_EVT", this->address_str().c_str());
|
||||||
|
this->conn_id = param->open.conn_id;
|
||||||
if (param->open.status != ESP_GATT_OK) {
|
if (param->open.status != ESP_GATT_OK) {
|
||||||
ESP_LOGW(TAG, "connect to %s failed, status=%d", this->address_str().c_str(), param->open.status);
|
ESP_LOGW(TAG, "connect to %s failed, status=%d", this->address_str().c_str(), param->open.status);
|
||||||
this->set_states_(espbt::ClientState::IDLE);
|
this->set_states_(espbt::ClientState::IDLE);
|
||||||
@@ -122,7 +123,10 @@ void BLEClient::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t es
|
|||||||
}
|
}
|
||||||
case ESP_GATTC_CONNECT_EVT: {
|
case ESP_GATTC_CONNECT_EVT: {
|
||||||
ESP_LOGV(TAG, "[%s] ESP_GATTC_CONNECT_EVT", this->address_str().c_str());
|
ESP_LOGV(TAG, "[%s] ESP_GATTC_CONNECT_EVT", this->address_str().c_str());
|
||||||
this->conn_id = param->connect.conn_id;
|
if (this->conn_id != param->connect.conn_id) {
|
||||||
|
ESP_LOGD(TAG, "[%s] Unexpected conn_id in CONNECT_EVT: param conn=%d, open conn=%d",
|
||||||
|
this->address_str().c_str(), param->connect.conn_id, this->conn_id);
|
||||||
|
}
|
||||||
auto ret = esp_ble_gattc_send_mtu_req(this->gattc_if, param->connect.conn_id);
|
auto ret = esp_ble_gattc_send_mtu_req(this->gattc_if, param->connect.conn_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ESP_LOGW(TAG, "esp_ble_gattc_send_mtu_req failed, status=%x", ret);
|
ESP_LOGW(TAG, "esp_ble_gattc_send_mtu_req failed, status=%x", ret);
|
||||||
@@ -183,9 +187,10 @@ void BLEClient::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t es
|
|||||||
descr->uuid.to_string().c_str());
|
descr->uuid.to_string().c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint8_t notify_en = 1;
|
uint16_t notify_en = 1;
|
||||||
auto status = esp_ble_gattc_write_char_descr(this->gattc_if, this->conn_id, descr->handle, sizeof(notify_en),
|
auto status =
|
||||||
¬ify_en, ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE);
|
esp_ble_gattc_write_char_descr(this->gattc_if, this->conn_id, descr->handle, sizeof(notify_en),
|
||||||
|
(uint8_t *) ¬ify_en, ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||||
if (status) {
|
if (status) {
|
||||||
ESP_LOGW(TAG, "esp_ble_gattc_write_char_descr error, status=%d", status);
|
ESP_LOGW(TAG, "esp_ble_gattc_write_char_descr error, status=%d", status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ OVERSAMPLING_OPTIONS = {
|
|||||||
"4X": Oversampling.OVERSAMPLING_X4,
|
"4X": Oversampling.OVERSAMPLING_X4,
|
||||||
"8X": Oversampling.OVERSAMPLING_X8,
|
"8X": Oversampling.OVERSAMPLING_X8,
|
||||||
"16X": Oversampling.OVERSAMPLING_X16,
|
"16X": Oversampling.OVERSAMPLING_X16,
|
||||||
"32x": Oversampling.OVERSAMPLING_X32,
|
"32X": Oversampling.OVERSAMPLING_X32,
|
||||||
}
|
}
|
||||||
|
|
||||||
IIRFilter = bmp3xx_ns.enum("IIRFilter")
|
IIRFilter = bmp3xx_ns.enum("IIRFilter")
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ async def to_code(config):
|
|||||||
cg.add(var.set_request_interval(config[CONF_REQUEST_INTERVAL].total_milliseconds))
|
cg.add(var.set_request_interval(config[CONF_REQUEST_INTERVAL].total_milliseconds))
|
||||||
cg.add(var.set_receive_timeout(config[CONF_RECEIVE_TIMEOUT].total_milliseconds))
|
cg.add(var.set_receive_timeout(config[CONF_RECEIVE_TIMEOUT].total_milliseconds))
|
||||||
|
|
||||||
cg.add_define("DSMR_GAS_MBUS_ID", config[CONF_GAS_MBUS_ID])
|
cg.add_build_flag("-DDSMR_GAS_MBUS_ID=" + str(config[CONF_GAS_MBUS_ID]))
|
||||||
|
|
||||||
# DSMR Parser
|
# DSMR Parser
|
||||||
cg.add_library("glmnet/Dsmr", "0.5")
|
cg.add_library("glmnet/Dsmr", "0.5")
|
||||||
|
|||||||
@@ -51,6 +51,22 @@ void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) {
|
|||||||
this->state = media_player::MEDIA_PLAYER_STATE_PAUSED;
|
this->state = media_player::MEDIA_PLAYER_STATE_PAUSED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case media_player::MEDIA_PLAYER_COMMAND_VOLUME_UP: {
|
||||||
|
float new_volume = this->volume + 0.1f;
|
||||||
|
if (new_volume > 1.0f)
|
||||||
|
new_volume = 1.0f;
|
||||||
|
this->set_volume_(new_volume);
|
||||||
|
this->unmute_();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case media_player::MEDIA_PLAYER_COMMAND_VOLUME_DOWN: {
|
||||||
|
float new_volume = this->volume - 0.1f;
|
||||||
|
if (new_volume < 0.0f)
|
||||||
|
new_volume = 0.0f;
|
||||||
|
this->set_volume_(new_volume);
|
||||||
|
this->unmute_();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->publish_state();
|
this->publish_state();
|
||||||
@@ -93,6 +109,10 @@ void I2SAudioMediaPlayer::setup() {
|
|||||||
this->audio_ = make_unique<Audio>(false);
|
this->audio_ = make_unique<Audio>(false);
|
||||||
this->audio_->setPinout(this->bclk_pin_, this->lrclk_pin_, this->dout_pin_);
|
this->audio_->setPinout(this->bclk_pin_, this->lrclk_pin_, this->dout_pin_);
|
||||||
this->audio_->forceMono(this->external_dac_channels_ == 1);
|
this->audio_->forceMono(this->external_dac_channels_ == 1);
|
||||||
|
if (this->mute_pin_ != nullptr) {
|
||||||
|
this->mute_pin_->setup();
|
||||||
|
this->mute_pin_->digital_write(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->state = media_player::MEDIA_PLAYER_STATE_IDLE;
|
this->state = media_player::MEDIA_PLAYER_STATE_IDLE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ bool InkbirdIbstH1Mini::parse_device(const esp32_ble_tracker::ESPBTDevice &devic
|
|||||||
ESP_LOGVV(TAG, "parse_device(): manufacturer data element length is expected to be of length 7");
|
ESP_LOGVV(TAG, "parse_device(): manufacturer data element length is expected to be of length 7");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mnf_data.data[6] != 8) {
|
if ((mnf_data.data[6] != 8) && (mnf_data.data[6] != 6)) {
|
||||||
ESP_LOGVV(TAG, "parse_device(): unexpected data");
|
ESP_LOGVV(TAG, "parse_device(): unexpected data");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,7 +178,8 @@ void Logger::pre_setup() {
|
|||||||
Serial1.setDebugOutput(ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE);
|
Serial1.setDebugOutput(ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2)
|
#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2) && \
|
||||||
|
!defined(USE_ESP32_VARIANT_ESP32S3)
|
||||||
case UART_SELECTION_UART2:
|
case UART_SELECTION_UART2:
|
||||||
this->hw_serial_ = &Serial2;
|
this->hw_serial_ = &Serial2;
|
||||||
Serial2.begin(this->baud_rate_);
|
Serial2.begin(this->baud_rate_);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import esphome.config_validation as cv
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
|
||||||
from esphome.automation import maybe_simple_id
|
from esphome.automation import maybe_simple_id
|
||||||
from esphome.const import CONF_ID
|
from esphome.const import CONF_ID, CONF_ON_STATE, CONF_TRIGGER_ID
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
from esphome.coroutine import coroutine_with_priority
|
from esphome.coroutine import coroutine_with_priority
|
||||||
from esphome.cpp_helpers import setup_entity
|
from esphome.cpp_helpers import setup_entity
|
||||||
@@ -20,6 +20,9 @@ MediaPlayer = media_player_ns.class_("MediaPlayer")
|
|||||||
PlayAction = media_player_ns.class_(
|
PlayAction = media_player_ns.class_(
|
||||||
"PlayAction", automation.Action, cg.Parented.template(MediaPlayer)
|
"PlayAction", automation.Action, cg.Parented.template(MediaPlayer)
|
||||||
)
|
)
|
||||||
|
PlayMediaAction = media_player_ns.class_(
|
||||||
|
"PlayMediaAction", automation.Action, cg.Parented.template(MediaPlayer)
|
||||||
|
)
|
||||||
ToggleAction = media_player_ns.class_(
|
ToggleAction = media_player_ns.class_(
|
||||||
"ToggleAction", automation.Action, cg.Parented.template(MediaPlayer)
|
"ToggleAction", automation.Action, cg.Parented.template(MediaPlayer)
|
||||||
)
|
)
|
||||||
@@ -29,10 +32,45 @@ PauseAction = media_player_ns.class_(
|
|||||||
StopAction = media_player_ns.class_(
|
StopAction = media_player_ns.class_(
|
||||||
"StopAction", automation.Action, cg.Parented.template(MediaPlayer)
|
"StopAction", automation.Action, cg.Parented.template(MediaPlayer)
|
||||||
)
|
)
|
||||||
|
VolumeUpAction = media_player_ns.class_(
|
||||||
|
"VolumeUpAction", automation.Action, cg.Parented.template(MediaPlayer)
|
||||||
|
)
|
||||||
|
VolumeDownAction = media_player_ns.class_(
|
||||||
|
"VolumeDownAction", automation.Action, cg.Parented.template(MediaPlayer)
|
||||||
|
)
|
||||||
|
VolumeSetAction = media_player_ns.class_(
|
||||||
|
"VolumeSetAction", automation.Action, cg.Parented.template(MediaPlayer)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
CONF_VOLUME = "volume"
|
||||||
|
CONF_ON_IDLE = "on_idle"
|
||||||
|
CONF_ON_PLAY = "on_play"
|
||||||
|
CONF_ON_PAUSE = "on_pause"
|
||||||
|
CONF_MEDIA_URL = "media_url"
|
||||||
|
|
||||||
|
StateTrigger = media_player_ns.class_("StateTrigger", automation.Trigger.template())
|
||||||
|
IdleTrigger = media_player_ns.class_("IdleTrigger", automation.Trigger.template())
|
||||||
|
PlayTrigger = media_player_ns.class_("PlayTrigger", automation.Trigger.template())
|
||||||
|
PauseTrigger = media_player_ns.class_("PauseTrigger", automation.Trigger.template())
|
||||||
|
IsIdleCondition = media_player_ns.class_("IsIdleCondition", automation.Condition)
|
||||||
|
IsPlayingCondition = media_player_ns.class_("IsPlayingCondition", automation.Condition)
|
||||||
|
|
||||||
|
|
||||||
async def setup_media_player_core_(var, config):
|
async def setup_media_player_core_(var, config):
|
||||||
await setup_entity(var, config)
|
await setup_entity(var, config)
|
||||||
|
for conf in config.get(CONF_ON_STATE, []):
|
||||||
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
|
await automation.build_automation(trigger, [], conf)
|
||||||
|
for conf in config.get(CONF_ON_IDLE, []):
|
||||||
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
|
await automation.build_automation(trigger, [], conf)
|
||||||
|
for conf in config.get(CONF_ON_PLAY, []):
|
||||||
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
|
await automation.build_automation(trigger, [], conf)
|
||||||
|
for conf in config.get(CONF_ON_PAUSE, []):
|
||||||
|
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):
|
||||||
@@ -42,14 +80,54 @@ async def register_media_player(var, config):
|
|||||||
await setup_media_player_core_(var, config)
|
await setup_media_player_core_(var, config)
|
||||||
|
|
||||||
|
|
||||||
MEDIA_PLAYER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.Schema({}))
|
MEDIA_PLAYER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ON_STATE): automation.validate_automation(
|
||||||
MEDIA_PLAYER_ACTION_SCHEMA = maybe_simple_id(
|
{
|
||||||
{cv.Required(CONF_ID): cv.use_id(MediaPlayer)}
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateTrigger),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_ON_IDLE): automation.validate_automation(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(IdleTrigger),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_ON_PLAY): automation.validate_automation(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PlayTrigger),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_ON_PAUSE): automation.validate_automation(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PauseTrigger),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
MEDIA_PLAYER_ACTION_SCHEMA = maybe_simple_id({cv.GenerateID(): cv.use_id(MediaPlayer)})
|
||||||
|
|
||||||
|
|
||||||
|
@automation.register_action(
|
||||||
|
"media_player.play_media",
|
||||||
|
PlayMediaAction,
|
||||||
|
cv.maybe_simple_value(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.use_id(MediaPlayer),
|
||||||
|
cv.Required(CONF_MEDIA_URL): cv.templatable(cv.url),
|
||||||
|
},
|
||||||
|
key=CONF_MEDIA_URL,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
async def media_player_play_media_action(config, action_id, template_arg, args):
|
||||||
|
var = cg.new_Pvariable(action_id, template_arg)
|
||||||
|
await cg.register_parented(var, config[CONF_ID])
|
||||||
|
media_url = await cg.templatable(config[CONF_MEDIA_URL], args, cg.std_string)
|
||||||
|
cg.add(var.set_media_url(media_url))
|
||||||
|
return var
|
||||||
|
|
||||||
|
|
||||||
@automation.register_action("media_player.play", PlayAction, MEDIA_PLAYER_ACTION_SCHEMA)
|
@automation.register_action("media_player.play", PlayAction, MEDIA_PLAYER_ACTION_SCHEMA)
|
||||||
@automation.register_action(
|
@automation.register_action(
|
||||||
"media_player.toggle", ToggleAction, MEDIA_PLAYER_ACTION_SCHEMA
|
"media_player.toggle", ToggleAction, MEDIA_PLAYER_ACTION_SCHEMA
|
||||||
@@ -58,12 +136,43 @@ MEDIA_PLAYER_ACTION_SCHEMA = maybe_simple_id(
|
|||||||
"media_player.pause", PauseAction, MEDIA_PLAYER_ACTION_SCHEMA
|
"media_player.pause", PauseAction, MEDIA_PLAYER_ACTION_SCHEMA
|
||||||
)
|
)
|
||||||
@automation.register_action("media_player.stop", StopAction, MEDIA_PLAYER_ACTION_SCHEMA)
|
@automation.register_action("media_player.stop", StopAction, MEDIA_PLAYER_ACTION_SCHEMA)
|
||||||
|
@automation.register_action(
|
||||||
|
"media_player.volume_up", VolumeUpAction, MEDIA_PLAYER_ACTION_SCHEMA
|
||||||
|
)
|
||||||
|
@automation.register_action(
|
||||||
|
"media_player.volume_down", VolumeDownAction, MEDIA_PLAYER_ACTION_SCHEMA
|
||||||
|
)
|
||||||
|
@automation.register_condition(
|
||||||
|
"media_player.is_idle", IsIdleCondition, MEDIA_PLAYER_ACTION_SCHEMA
|
||||||
|
)
|
||||||
|
@automation.register_condition(
|
||||||
|
"media_player.is_playing", IsPlayingCondition, MEDIA_PLAYER_ACTION_SCHEMA
|
||||||
|
)
|
||||||
async def media_player_action(config, action_id, template_arg, args):
|
async def media_player_action(config, action_id, template_arg, args):
|
||||||
var = cg.new_Pvariable(action_id, template_arg)
|
var = cg.new_Pvariable(action_id, template_arg)
|
||||||
await cg.register_parented(var, config[CONF_ID])
|
await cg.register_parented(var, config[CONF_ID])
|
||||||
return var
|
return var
|
||||||
|
|
||||||
|
|
||||||
|
@automation.register_action(
|
||||||
|
"media_player.volume_set",
|
||||||
|
VolumeSetAction,
|
||||||
|
cv.maybe_simple_value(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.use_id(MediaPlayer),
|
||||||
|
cv.Required(CONF_VOLUME): cv.templatable(cv.percentage),
|
||||||
|
},
|
||||||
|
key=CONF_VOLUME,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
async def media_player_volume_set_action(config, action_id, template_arg, args):
|
||||||
|
var = cg.new_Pvariable(action_id, template_arg)
|
||||||
|
await cg.register_parented(var, config[CONF_ID])
|
||||||
|
volume = await cg.templatable(config[CONF_VOLUME], args, float)
|
||||||
|
cg.add(var.set_volume(volume))
|
||||||
|
return var
|
||||||
|
|
||||||
|
|
||||||
@coroutine_with_priority(100.0)
|
@coroutine_with_priority(100.0)
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
cg.add_global(media_player_ns.using)
|
cg.add_global(media_player_ns.using)
|
||||||
|
|||||||
@@ -7,28 +7,60 @@ namespace esphome {
|
|||||||
|
|
||||||
namespace media_player {
|
namespace media_player {
|
||||||
|
|
||||||
template<typename... Ts> class PlayAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
#define MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(ACTION_CLASS, ACTION_COMMAND) \
|
||||||
void play(Ts... x) override {
|
template<typename... Ts> class ACTION_CLASS : public Action<Ts...>, public Parented<MediaPlayer> { \
|
||||||
this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_PLAY).perform();
|
void play(Ts... x) override { \
|
||||||
|
this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_##ACTION_COMMAND).perform(); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(TRIGGER_CLASS, TRIGGER_STATE) \
|
||||||
|
class TRIGGER_CLASS : public Trigger<> { \
|
||||||
|
public: \
|
||||||
|
explicit TRIGGER_CLASS(MediaPlayer *player) { \
|
||||||
|
player->add_on_state_callback([this, player]() { \
|
||||||
|
if (player->state == MediaPlayerState::MEDIA_PLAYER_STATE_##TRIGGER_STATE) \
|
||||||
|
this->trigger(); \
|
||||||
|
}); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(PlayAction, PLAY)
|
||||||
|
MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(PauseAction, PAUSE)
|
||||||
|
MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(StopAction, STOP)
|
||||||
|
MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(ToggleAction, TOGGLE)
|
||||||
|
MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(VolumeUpAction, VOLUME_UP)
|
||||||
|
MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(VolumeDownAction, VOLUME_DOWN)
|
||||||
|
|
||||||
|
template<typename... Ts> class PlayMediaAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
||||||
|
TEMPLATABLE_VALUE(std::string, media_url)
|
||||||
|
void play(Ts... x) override { this->parent_->make_call().set_media_url(this->media_url_.value(x...)).perform(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Ts> class VolumeSetAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
||||||
|
TEMPLATABLE_VALUE(float, volume)
|
||||||
|
void play(Ts... x) override { this->parent_->make_call().set_volume(this->volume_.value(x...)).perform(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class StateTrigger : public Trigger<> {
|
||||||
|
public:
|
||||||
|
explicit StateTrigger(MediaPlayer *player) {
|
||||||
|
player->add_on_state_callback([this]() { this->trigger(); });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Ts> class ToggleAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(IdleTrigger, IDLE)
|
||||||
void play(Ts... x) override {
|
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(PlayTrigger, PLAYING)
|
||||||
this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_TOGGLE).perform();
|
MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(PauseTrigger, PAUSED)
|
||||||
}
|
|
||||||
|
template<typename... Ts> class IsIdleCondition : public Condition<Ts...>, public Parented<MediaPlayer> {
|
||||||
|
public:
|
||||||
|
bool check(Ts... x) override { return this->parent_->state == MediaPlayerState::MEDIA_PLAYER_STATE_IDLE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Ts> class PauseAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
template<typename... Ts> class IsPlayingCondition : public Condition<Ts...>, public Parented<MediaPlayer> {
|
||||||
void play(Ts... x) override {
|
public:
|
||||||
this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_PAUSE).perform();
|
bool check(Ts... x) override { return this->parent_->state == MediaPlayerState::MEDIA_PLAYER_STATE_PLAYING; }
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Ts> class StopAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
|
||||||
void play(Ts... x) override {
|
|
||||||
this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_STOP).perform();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace media_player
|
} // namespace media_player
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ enum MediaPlayerCommand : uint8_t {
|
|||||||
MEDIA_PLAYER_COMMAND_STOP = 2,
|
MEDIA_PLAYER_COMMAND_STOP = 2,
|
||||||
MEDIA_PLAYER_COMMAND_MUTE = 3,
|
MEDIA_PLAYER_COMMAND_MUTE = 3,
|
||||||
MEDIA_PLAYER_COMMAND_UNMUTE = 4,
|
MEDIA_PLAYER_COMMAND_UNMUTE = 4,
|
||||||
MEDIA_PLAYER_COMMAND_TOGGLE = 5
|
MEDIA_PLAYER_COMMAND_TOGGLE = 5,
|
||||||
|
MEDIA_PLAYER_COMMAND_VOLUME_UP = 6,
|
||||||
|
MEDIA_PLAYER_COMMAND_VOLUME_DOWN = 7,
|
||||||
};
|
};
|
||||||
const char *media_player_command_to_string(MediaPlayerCommand command);
|
const char *media_player_command_to_string(MediaPlayerCommand command);
|
||||||
|
|
||||||
|
|||||||
@@ -108,8 +108,7 @@ void ModbusController::queue_command(const ModbusCommandItem &command) {
|
|||||||
// check if this commmand is already qeued.
|
// check if this commmand is already qeued.
|
||||||
// not very effective but the queue is never really large
|
// not very effective but the queue is never really large
|
||||||
for (auto &item : command_queue_) {
|
for (auto &item : command_queue_) {
|
||||||
if (item->register_address == command.register_address && item->register_count == command.register_count &&
|
if (item->is_equal(command)) {
|
||||||
item->register_type == command.register_type && item->function_code == command.function_code) {
|
|
||||||
ESP_LOGW(TAG, "Duplicate modbus command found: type=0x%x address=%u count=%u",
|
ESP_LOGW(TAG, "Duplicate modbus command found: type=0x%x address=%u count=%u",
|
||||||
static_cast<uint8_t>(command.register_type), command.register_address, command.register_count);
|
static_cast<uint8_t>(command.register_type), command.register_address, command.register_count);
|
||||||
// update the payload of the queued command
|
// update the payload of the queued command
|
||||||
@@ -489,6 +488,15 @@ bool ModbusCommandItem::send() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ModbusCommandItem::is_equal(const ModbusCommandItem &other) {
|
||||||
|
// for custom commands we have to check for identical payloads, since
|
||||||
|
// address/count/type fields will be set to zero
|
||||||
|
return this->function_code == ModbusFunctionCode::CUSTOM
|
||||||
|
? this->payload == other.payload
|
||||||
|
: other.register_address == this->register_address && other.register_count == this->register_count &&
|
||||||
|
other.register_type == this->register_type && other.function_code == this->function_code;
|
||||||
|
}
|
||||||
|
|
||||||
void number_to_payload(std::vector<uint16_t> &data, int64_t value, SensorValueType value_type) {
|
void number_to_payload(std::vector<uint16_t> &data, int64_t value, SensorValueType value_type) {
|
||||||
switch (value_type) {
|
switch (value_type) {
|
||||||
case SensorValueType::U_WORD:
|
case SensorValueType::U_WORD:
|
||||||
|
|||||||
@@ -395,6 +395,8 @@ class ModbusCommandItem {
|
|||||||
ModbusController *modbusdevice, const std::vector<uint16_t> &values,
|
ModbusController *modbusdevice, const std::vector<uint16_t> &values,
|
||||||
std::function<void(ModbusRegisterType register_type, uint16_t start_address, const std::vector<uint8_t> &data)>
|
std::function<void(ModbusRegisterType register_type, uint16_t start_address, const std::vector<uint8_t> &data)>
|
||||||
&&handler = nullptr);
|
&&handler = nullptr);
|
||||||
|
|
||||||
|
bool is_equal(const ModbusCommandItem &other);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Modbus controller class.
|
/** Modbus controller class.
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ void MQTTClientComponent::start_connect_() {
|
|||||||
|
|
||||||
this->mqtt_backend_.set_credentials(username, password);
|
this->mqtt_backend_.set_credentials(username, password);
|
||||||
|
|
||||||
this->mqtt_backend_.set_server((uint32_t) this->ip_, this->credentials_.port);
|
this->mqtt_backend_.set_server(this->credentials_.address.c_str(), this->credentials_.port);
|
||||||
if (!this->last_will_.topic.empty()) {
|
if (!this->last_will_.topic.empty()) {
|
||||||
this->mqtt_backend_.set_will(this->last_will_.topic.c_str(), this->last_will_.qos, this->last_will_.retain,
|
this->mqtt_backend_.set_will(this->last_will_.topic.c_str(), this->last_will_.qos, this->last_will_.retain,
|
||||||
this->last_will_.payload.c_str());
|
this->last_will_.payload.c_str());
|
||||||
|
|||||||
@@ -744,7 +744,8 @@ def rc6_binary_sensor(var, config):
|
|||||||
var.set_data(
|
var.set_data(
|
||||||
cg.StructInitializer(
|
cg.StructInitializer(
|
||||||
RC6Data,
|
RC6Data,
|
||||||
("device", config[CONF_DEVICE]),
|
("mode", 0),
|
||||||
|
("toggle", 0),
|
||||||
("address", config[CONF_ADDRESS]),
|
("address", config[CONF_ADDRESS]),
|
||||||
("command", config[CONF_COMMAND]),
|
("command", config[CONF_COMMAND]),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -140,5 +140,7 @@ async def to_code(config):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
cg.add_library(
|
cg.add_library(
|
||||||
None, None, "https://github.com/Sensirion/arduino-gas-index-algorithm.git"
|
None,
|
||||||
|
None,
|
||||||
|
"https://github.com/Sensirion/arduino-gas-index-algorithm.git#3.2.1",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -170,8 +170,8 @@ bool SGP4xComponent::measure_gas_indices_(int32_t &voc, int32_t &nox) {
|
|||||||
// much
|
// much
|
||||||
if (this->store_baseline_ && this->seconds_since_last_store_ > SHORTEST_BASELINE_STORE_INTERVAL) {
|
if (this->store_baseline_ && this->seconds_since_last_store_ > SHORTEST_BASELINE_STORE_INTERVAL) {
|
||||||
voc_algorithm_.get_states(this->voc_state0_, this->voc_state1_);
|
voc_algorithm_.get_states(this->voc_state0_, this->voc_state1_);
|
||||||
if ((uint32_t) abs(this->voc_baselines_storage_.state0 - this->voc_state0_) > MAXIMUM_STORAGE_DIFF ||
|
if (std::abs(this->voc_baselines_storage_.state0 - this->voc_state0_) > MAXIMUM_STORAGE_DIFF ||
|
||||||
(uint32_t) abs(this->voc_baselines_storage_.state1 - this->voc_state1_) > MAXIMUM_STORAGE_DIFF) {
|
std::abs(this->voc_baselines_storage_.state1 - this->voc_state1_) > MAXIMUM_STORAGE_DIFF) {
|
||||||
this->seconds_since_last_store_ = 0;
|
this->seconds_since_last_store_ = 0;
|
||||||
this->voc_baselines_storage_.state0 = this->voc_state0_;
|
this->voc_baselines_storage_.state0 = this->voc_state0_;
|
||||||
this->voc_baselines_storage_.state1 = this->voc_state1_;
|
this->voc_baselines_storage_.state1 = this->voc_state1_;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ static const uint16_t SPG41_SELFTEST_TIME = 320; // 320 ms for self test
|
|||||||
static const uint16_t SGP40_MEASURE_TIME = 30;
|
static const uint16_t SGP40_MEASURE_TIME = 30;
|
||||||
static const uint16_t SGP41_MEASURE_TIME = 55;
|
static const uint16_t SGP41_MEASURE_TIME = 55;
|
||||||
// Store anyway if the baseline difference exceeds the max storage diff value
|
// Store anyway if the baseline difference exceeds the max storage diff value
|
||||||
const uint32_t MAXIMUM_STORAGE_DIFF = 50;
|
const float MAXIMUM_STORAGE_DIFF = 50.0f;
|
||||||
|
|
||||||
class SGP4xComponent;
|
class SGP4xComponent;
|
||||||
|
|
||||||
@@ -120,8 +120,8 @@ class SGP4xComponent : public PollingComponent, public sensor::Sensor, public se
|
|||||||
sensor::Sensor *voc_sensor_{nullptr};
|
sensor::Sensor *voc_sensor_{nullptr};
|
||||||
VOCGasIndexAlgorithm voc_algorithm_;
|
VOCGasIndexAlgorithm voc_algorithm_;
|
||||||
optional<GasTuning> voc_tuning_params_;
|
optional<GasTuning> voc_tuning_params_;
|
||||||
int32_t voc_state0_;
|
float voc_state0_;
|
||||||
int32_t voc_state1_;
|
float voc_state1_;
|
||||||
int32_t voc_index_ = 0;
|
int32_t voc_index_ = 0;
|
||||||
|
|
||||||
sensor::Sensor *nox_sensor_{nullptr};
|
sensor::Sensor *nox_sensor_{nullptr};
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ void WebServer::handle_sensor_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
if (obj->get_object_id() != match.id)
|
if (obj->get_object_id() != match.id)
|
||||||
continue;
|
continue;
|
||||||
std::string data = this->sensor_json(obj, obj->state, DETAIL_STATE);
|
std::string data = this->sensor_json(obj, obj->state, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request->send(404);
|
request->send(404);
|
||||||
@@ -377,7 +377,7 @@ void WebServer::handle_text_sensor_request(AsyncWebServerRequest *request, const
|
|||||||
if (obj->get_object_id() != match.id)
|
if (obj->get_object_id() != match.id)
|
||||||
continue;
|
continue;
|
||||||
std::string data = this->text_sensor_json(obj, obj->state, DETAIL_STATE);
|
std::string data = this->text_sensor_json(obj, obj->state, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request->send(404);
|
request->send(404);
|
||||||
@@ -406,7 +406,7 @@ void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
|
|
||||||
if (request->method() == HTTP_GET) {
|
if (request->method() == HTTP_GET) {
|
||||||
std::string data = this->switch_json(obj, obj->state, DETAIL_STATE);
|
std::string data = this->switch_json(obj, obj->state, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "toggle") {
|
} else if (match.method == "toggle") {
|
||||||
this->defer([obj]() { obj->toggle(); });
|
this->defer([obj]() { obj->toggle(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -462,7 +462,7 @@ void WebServer::handle_binary_sensor_request(AsyncWebServerRequest *request, con
|
|||||||
if (obj->get_object_id() != match.id)
|
if (obj->get_object_id() != match.id)
|
||||||
continue;
|
continue;
|
||||||
std::string data = this->binary_sensor_json(obj, obj->state, DETAIL_STATE);
|
std::string data = this->binary_sensor_json(obj, obj->state, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request->send(404);
|
request->send(404);
|
||||||
@@ -490,7 +490,7 @@ void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatc
|
|||||||
|
|
||||||
if (request->method() == HTTP_GET) {
|
if (request->method() == HTTP_GET) {
|
||||||
std::string data = this->fan_json(obj, DETAIL_STATE);
|
std::string data = this->fan_json(obj, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "toggle") {
|
} else if (match.method == "toggle") {
|
||||||
this->defer([obj]() { obj->toggle().perform(); });
|
this->defer([obj]() { obj->toggle().perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -551,7 +551,7 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
|
|
||||||
if (request->method() == HTTP_GET) {
|
if (request->method() == HTTP_GET) {
|
||||||
std::string data = this->light_json(obj, DETAIL_STATE);
|
std::string data = this->light_json(obj, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "toggle") {
|
} else if (match.method == "toggle") {
|
||||||
this->defer([obj]() { obj->toggle().perform(); });
|
this->defer([obj]() { obj->toggle().perform(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
@@ -630,7 +630,7 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
|
|
||||||
if (request->method() == HTTP_GET) {
|
if (request->method() == HTTP_GET) {
|
||||||
std::string data = this->cover_json(obj, DETAIL_STATE);
|
std::string data = this->cover_json(obj, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,7 +687,7 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
|
|
||||||
if (request->method() == HTTP_GET) {
|
if (request->method() == HTTP_GET) {
|
||||||
std::string data = this->number_json(obj, obj->state, DETAIL_STATE);
|
std::string data = this->number_json(obj, obj->state, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (match.method != "set") {
|
if (match.method != "set") {
|
||||||
@@ -741,7 +741,7 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM
|
|||||||
|
|
||||||
if (request->method() == HTTP_GET) {
|
if (request->method() == HTTP_GET) {
|
||||||
std::string data = this->select_json(obj, obj->state, DETAIL_STATE);
|
std::string data = this->select_json(obj, obj->state, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,7 +788,7 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url
|
|||||||
|
|
||||||
if (request->method() == HTTP_GET) {
|
if (request->method() == HTTP_GET) {
|
||||||
std::string data = this->climate_json(obj, DETAIL_STATE);
|
std::string data = this->climate_json(obj, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -926,7 +926,7 @@ void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMat
|
|||||||
|
|
||||||
if (request->method() == HTTP_GET) {
|
if (request->method() == HTTP_GET) {
|
||||||
std::string data = this->lock_json(obj, obj->state, DETAIL_STATE);
|
std::string data = this->lock_json(obj, obj->state, DETAIL_STATE);
|
||||||
request->send(200, "text/json", data.c_str());
|
request->send(200, "application/json", data.c_str());
|
||||||
} else if (match.method == "lock") {
|
} else if (match.method == "lock") {
|
||||||
this->defer([obj]() { obj->lock(); });
|
this->defer([obj]() { obj->lock(); });
|
||||||
request->send(200);
|
request->send(200);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
__version__ = "2022.6.0b2"
|
__version__ = "2022.6.3"
|
||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
|
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ template<class T> class ExternalRAMAllocator {
|
|||||||
|
|
||||||
ExternalRAMAllocator() = default;
|
ExternalRAMAllocator() = default;
|
||||||
ExternalRAMAllocator(Flags flags) : flags_{flags} {}
|
ExternalRAMAllocator(Flags flags) : flags_{flags} {}
|
||||||
template<class U> constexpr ExternalRAMAllocator(const ExternalRAMAllocator<U> &other) : flags_{other.flags} {}
|
template<class U> constexpr ExternalRAMAllocator(const ExternalRAMAllocator<U> &other) : flags_{other.flags_} {}
|
||||||
|
|
||||||
T *allocate(size_t n) {
|
T *allocate(size_t n) {
|
||||||
size_t size = n * sizeof(T);
|
size_t size = n * sizeof(T);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ lib_deps =
|
|||||||
wjtje/qr-code-generator-library@1.7.0 ; qr_code
|
wjtje/qr-code-generator-library@1.7.0 ; qr_code
|
||||||
functionpointer/arduino-MLX90393@1.0.0 ; mlx90393
|
functionpointer/arduino-MLX90393@1.0.0 ; mlx90393
|
||||||
; This is using the repository until a new release is published to PlatformIO
|
; This is using the repository until a new release is published to PlatformIO
|
||||||
https://github.com/Sensirion/arduino-gas-index-algorithm.git ; Sensirion Gas Index Algorithm Arduino Library
|
https://github.com/Sensirion/arduino-gas-index-algorithm.git#3.2.1 ; Sensirion Gas Index Algorithm Arduino Library
|
||||||
build_flags =
|
build_flags =
|
||||||
-DESPHOME_LOG_LEVEL=ESPHOME_LOG_LEVEL_VERY_VERBOSE
|
-DESPHOME_LOG_LEVEL=ESPHOME_LOG_LEVEL_VERY_VERBOSE
|
||||||
src_filter =
|
src_filter =
|
||||||
|
|||||||
@@ -613,3 +613,20 @@ media_player:
|
|||||||
i2s_dout_pin: GPIO25
|
i2s_dout_pin: GPIO25
|
||||||
i2s_bclk_pin: GPIO27
|
i2s_bclk_pin: GPIO27
|
||||||
mute_pin: GPIO14
|
mute_pin: GPIO14
|
||||||
|
on_state:
|
||||||
|
- media_player.play:
|
||||||
|
- media_player.play_media: http://localhost/media.mp3
|
||||||
|
- media_player.play_media: !lambda 'return "http://localhost/media.mp3";'
|
||||||
|
on_idle:
|
||||||
|
- media_player.pause:
|
||||||
|
on_play:
|
||||||
|
- media_player.stop:
|
||||||
|
on_pause:
|
||||||
|
- media_player.toggle:
|
||||||
|
- wait_until:
|
||||||
|
media_player.is_idle:
|
||||||
|
- wait_until:
|
||||||
|
media_player.is_playing:
|
||||||
|
- media_player.volume_up:
|
||||||
|
- media_player.volume_down:
|
||||||
|
- media_player.volume_set: 50%
|
||||||
|
|||||||
Reference in New Issue
Block a user