esphome 2024.9.1__py3-none-any.whl → 2024.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/components/aic3204/__init__.py +0 -0
- esphome/components/aic3204/aic3204.cpp +173 -0
- esphome/components/aic3204/aic3204.h +88 -0
- esphome/components/aic3204/audio_dac.py +52 -0
- esphome/components/aic3204/automation.h +23 -0
- esphome/components/alarm_control_panel/__init__.py +3 -4
- esphome/components/animation/__init__.py +16 -12
- esphome/components/api/api_connection.cpp +2 -0
- esphome/components/api/api_connection.h +3 -1
- esphome/components/api/api_frame_helper.cpp +2 -1
- esphome/components/api/api_frame_helper.h +2 -1
- esphome/components/api/api_server.cpp +2 -0
- esphome/components/api/api_server.h +3 -1
- esphome/components/api/custom_api_device.h +3 -2
- esphome/components/api/homeassistant_service.h +4 -3
- esphome/components/api/list_entities.cpp +2 -0
- esphome/components/api/list_entities.h +3 -2
- esphome/components/api/subscribe_state.cpp +2 -0
- esphome/components/api/subscribe_state.h +3 -2
- esphome/components/audio_dac/__init__.py +57 -0
- esphome/components/audio_dac/audio_dac.h +23 -0
- esphome/components/audio_dac/automation.h +43 -0
- esphome/components/bang_bang/bang_bang_climate.cpp +5 -2
- esphome/components/bedjet/bedjet_codec.cpp +4 -2
- esphome/components/binary_sensor/__init__.py +3 -4
- esphome/components/bl0906/sensor.py +3 -2
- esphome/components/button/__init__.py +3 -4
- esphome/components/ch422g/__init__.py +26 -17
- esphome/components/ch422g/ch422g.cpp +66 -49
- esphome/components/ch422g/ch422g.h +17 -19
- esphome/components/climate/__init__.py +3 -4
- esphome/components/cover/__init__.py +4 -5
- esphome/components/cse7766/cse7766.cpp +12 -1
- esphome/components/cse7766/cse7766.h +4 -0
- esphome/components/cse7766/sensor.py +13 -1
- esphome/components/cst816/touchscreen/__init__.py +7 -4
- esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +20 -19
- esphome/components/cst816/touchscreen/cst816_touchscreen.h +2 -0
- esphome/components/datetime/__init__.py +21 -14
- esphome/components/datetime/datetime_base.h +8 -1
- esphome/components/datetime/datetime_entity.cpp +2 -0
- esphome/components/datetime/datetime_entity.h +2 -0
- esphome/components/datetime/time_entity.cpp +2 -0
- esphome/components/datetime/time_entity.h +2 -0
- esphome/components/esp32/__init__.py +20 -4
- esphome/components/esp32_improv/__init__.py +82 -1
- esphome/components/esp32_improv/automation.h +72 -0
- esphome/components/esp32_improv/esp32_improv_component.cpp +13 -5
- esphome/components/esp32_improv/esp32_improv_component.h +15 -0
- esphome/components/ethernet/__init__.py +5 -0
- esphome/components/ethernet/ethernet_component.cpp +13 -0
- esphome/components/ethernet/ethernet_component.h +1 -0
- esphome/components/event/__init__.py +20 -12
- esphome/components/fan/__init__.py +3 -4
- esphome/components/gp2y1010au0f/__init__.py +0 -0
- esphome/components/gp2y1010au0f/gp2y1010au0f.cpp +67 -0
- esphome/components/gp2y1010au0f/gp2y1010au0f.h +52 -0
- esphome/components/gp2y1010au0f/sensor.py +61 -0
- esphome/components/gpio_expander/__init__.py +0 -0
- esphome/components/gpio_expander/cached_gpio.h +38 -0
- esphome/components/grove_gas_mc_v2/__init__.py +0 -0
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +88 -0
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +39 -0
- esphome/components/grove_gas_mc_v2/sensor.py +77 -0
- esphome/components/haier/climate.py +4 -3
- esphome/components/haier/haier_base.cpp +63 -8
- esphome/components/haier/haier_base.h +29 -3
- esphome/components/haier/hon_climate.cpp +122 -65
- esphome/components/haier/hon_climate.h +18 -2
- esphome/components/haier/smartair2_climate.cpp +21 -21
- esphome/components/haier/switch/__init__.py +91 -0
- esphome/components/haier/switch/beeper.cpp +14 -0
- esphome/components/haier/switch/beeper.h +18 -0
- esphome/components/haier/switch/display.cpp +14 -0
- esphome/components/haier/switch/display.h +18 -0
- esphome/components/haier/switch/health_mode.cpp +14 -0
- esphome/components/haier/switch/health_mode.h +18 -0
- esphome/components/haier/switch/quiet_mode.cpp +14 -0
- esphome/components/haier/switch/quiet_mode.h +18 -0
- esphome/components/hmac_md5/hmac_md5.cpp +2 -0
- esphome/components/hmac_md5/hmac_md5.h +2 -1
- esphome/components/i2s_audio/speaker/__init__.py +19 -0
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +2 -0
- esphome/components/ili9xxx/ili9xxx_display.h +1 -0
- esphome/components/image/__init__.py +12 -12
- esphome/components/image/image.cpp +44 -0
- esphome/components/image/image.h +17 -2
- esphome/components/inkplate6/display.py +2 -0
- esphome/components/inkplate6/inkplate.h +30 -2
- esphome/components/light/__init__.py +3 -4
- esphome/components/lock/__init__.py +3 -4
- esphome/components/lvgl/__init__.py +16 -5
- esphome/components/lvgl/defines.py +1 -0
- esphome/components/lvgl/hello_world.py +64 -0
- esphome/components/lvgl/lv_validation.py +159 -3
- esphome/components/lvgl/lvgl_esphome.cpp +0 -43
- esphome/components/lvgl/lvgl_esphome.h +0 -4
- esphome/components/lvgl/styles.py +3 -2
- esphome/components/lvgl/text/__init__.py +3 -3
- esphome/components/lvgl/widgets/__init__.py +2 -0
- esphome/components/lvgl/widgets/animimg.py +3 -4
- esphome/components/lvgl/widgets/dropdown.py +5 -1
- esphome/components/lvgl/widgets/meter.py +16 -11
- esphome/components/md5/__init__.py +6 -0
- esphome/components/md5/md5.cpp +2 -0
- esphome/components/md5/md5.h +2 -0
- esphome/components/micro_wake_word/__init__.py +7 -0
- esphome/components/mics_4514/sensor.py +11 -26
- esphome/components/modbus_controller/__init__.py +7 -5
- esphome/components/modbus_controller/binary_sensor/__init__.py +6 -6
- esphome/components/modbus_controller/number/__init__.py +5 -6
- esphome/components/modbus_controller/output/__init__.py +10 -14
- esphome/components/modbus_controller/select/__init__.py +1 -1
- esphome/components/modbus_controller/sensor/__init__.py +7 -7
- esphome/components/modbus_controller/switch/__init__.py +6 -7
- esphome/components/modbus_controller/text_sensor/__init__.py +8 -9
- esphome/components/mqtt/__init__.py +3 -0
- esphome/components/mqtt/mqtt_client.cpp +2 -0
- esphome/components/mqtt/mqtt_client.h +2 -0
- esphome/components/nau7802/__init__.py +0 -0
- esphome/components/nau7802/nau7802.cpp +323 -0
- esphome/components/nau7802/nau7802.h +121 -0
- esphome/components/nau7802/sensor.py +134 -0
- esphome/components/nextion/base_component.py +1 -0
- esphome/components/nextion/display.py +4 -0
- esphome/components/nextion/nextion.cpp +19 -4
- esphome/components/nextion/nextion.h +16 -0
- esphome/components/npi19/__init__.py +0 -0
- esphome/components/npi19/npi19.cpp +111 -0
- esphome/components/npi19/npi19.h +30 -0
- esphome/components/npi19/sensor.py +52 -0
- esphome/components/number/__init__.py +3 -5
- esphome/components/online_image/__init__.py +1 -1
- esphome/components/online_image/online_image.h +1 -2
- esphome/components/opentherm/__init__.py +57 -0
- esphome/components/opentherm/hub.cpp +277 -0
- esphome/components/opentherm/hub.h +110 -0
- esphome/components/opentherm/opentherm.cpp +568 -0
- esphome/components/opentherm/opentherm.h +347 -0
- esphome/components/pulse_counter/pulse_counter_sensor.cpp +8 -1
- esphome/components/pulse_counter/pulse_counter_sensor.h +1 -0
- esphome/components/radon_eye_ble/radon_eye_listener.cpp +10 -3
- esphome/components/remote_transmitter/__init__.py +18 -2
- esphome/components/remote_transmitter/remote_transmitter.h +6 -0
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +2 -0
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
- esphome/components/rp2040/__init__.py +13 -14
- esphome/components/select/__init__.py +3 -4
- esphome/components/sensor/__init__.py +3 -4
- esphome/components/shelly_dimmer/shelly_dimmer.cpp +32 -32
- esphome/components/shelly_dimmer/shelly_dimmer.h +2 -0
- esphome/components/st7701s/st7701s.cpp +21 -8
- esphome/components/st7701s/st7701s.h +2 -0
- esphome/components/switch/__init__.py +3 -4
- esphome/components/tca9555/__init__.py +72 -0
- esphome/components/tca9555/tca9555.cpp +140 -0
- esphome/components/tca9555/tca9555.h +64 -0
- esphome/components/tcs34725/tcs34725.cpp +62 -64
- esphome/components/tem3200/__init__.py +0 -0
- esphome/components/tem3200/sensor.py +55 -0
- esphome/components/tem3200/tem3200.cpp +151 -0
- esphome/components/tem3200/tem3200.h +30 -0
- esphome/components/template/binary_sensor/__init__.py +19 -6
- esphome/components/text/__init__.py +3 -4
- esphome/components/text_sensor/__init__.py +3 -4
- esphome/components/thermostat/climate.py +11 -9
- esphome/components/thermostat/thermostat_climate.cpp +21 -15
- esphome/components/tm1638/binary_sensor/__init__.py +3 -2
- esphome/components/tm1638/display.py +5 -5
- esphome/components/tm1638/output/__init__.py +3 -2
- esphome/components/tm1638/switch/__init__.py +3 -2
- esphome/components/touchscreen/touchscreen.cpp +2 -2
- esphome/components/update/__init__.py +3 -4
- esphome/components/valve/__init__.py +3 -4
- esphome/components/web_server/__init__.py +78 -22
- esphome/components/web_server/server_index_v3.h +3989 -3979
- esphome/components/web_server/web_server.cpp +219 -34
- esphome/components/web_server/web_server.h +10 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +4 -5
- esphome/config_validation.py +1 -0
- esphome/const.py +12 -2
- esphome/core/defines.h +4 -2
- esphome/core/helpers.cpp +46 -10
- esphome/core/helpers.h +8 -0
- esphome/core/ring_buffer.cpp +12 -2
- esphome/core/ring_buffer.h +3 -0
- esphome/voluptuous_schema.py +3 -1
- esphome/wizard.py +0 -3
- {esphome-2024.9.1.dist-info → esphome-2024.10.0.dist-info}/METADATA +5 -3
- {esphome-2024.9.1.dist-info → esphome-2024.10.0.dist-info}/RECORD +196 -147
- {esphome-2024.9.1.dist-info → esphome-2024.10.0.dist-info}/LICENSE +0 -0
- {esphome-2024.9.1.dist-info → esphome-2024.10.0.dist-info}/WHEEL +0 -0
- {esphome-2024.9.1.dist-info → esphome-2024.10.0.dist-info}/entry_points.txt +0 -0
- {esphome-2024.9.1.dist-info → esphome-2024.10.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
import esphome.codegen as cg
|
2
|
+
import esphome.config_validation as cv
|
3
|
+
import esphome.final_validate as fv
|
4
|
+
from esphome.components import switch
|
5
|
+
from esphome.const import (
|
6
|
+
CONF_BEEPER,
|
7
|
+
CONF_DISPLAY,
|
8
|
+
ENTITY_CATEGORY_CONFIG,
|
9
|
+
)
|
10
|
+
from ..climate import (
|
11
|
+
CONF_HAIER_ID,
|
12
|
+
CONF_PROTOCOL,
|
13
|
+
HaierClimateBase,
|
14
|
+
haier_ns,
|
15
|
+
PROTOCOL_HON,
|
16
|
+
)
|
17
|
+
|
18
|
+
CODEOWNERS = ["@paveldn"]
|
19
|
+
BeeperSwitch = haier_ns.class_("BeeperSwitch", switch.Switch)
|
20
|
+
HealthModeSwitch = haier_ns.class_("HealthModeSwitch", switch.Switch)
|
21
|
+
DisplaySwitch = haier_ns.class_("DisplaySwitch", switch.Switch)
|
22
|
+
QuietModeSwitch = haier_ns.class_("QuietModeSwitch", switch.Switch)
|
23
|
+
|
24
|
+
# Haier switches
|
25
|
+
CONF_HEALTH_MODE = "health_mode"
|
26
|
+
CONF_QUIET_MODE = "quiet_mode"
|
27
|
+
|
28
|
+
# Additional icons
|
29
|
+
ICON_LEAF = "mdi:leaf"
|
30
|
+
ICON_LED_ON = "mdi:led-on"
|
31
|
+
ICON_VOLUME_HIGH = "mdi:volume-high"
|
32
|
+
ICON_VOLUME_OFF = "mdi:volume-off"
|
33
|
+
|
34
|
+
CONFIG_SCHEMA = cv.Schema(
|
35
|
+
{
|
36
|
+
cv.GenerateID(CONF_HAIER_ID): cv.use_id(HaierClimateBase),
|
37
|
+
cv.Optional(CONF_DISPLAY): switch.switch_schema(
|
38
|
+
DisplaySwitch,
|
39
|
+
icon=ICON_LED_ON,
|
40
|
+
entity_category=ENTITY_CATEGORY_CONFIG,
|
41
|
+
default_restore_mode="DISABLED",
|
42
|
+
),
|
43
|
+
cv.Optional(CONF_HEALTH_MODE): switch.switch_schema(
|
44
|
+
HealthModeSwitch,
|
45
|
+
icon=ICON_LEAF,
|
46
|
+
default_restore_mode="DISABLED",
|
47
|
+
),
|
48
|
+
# Beeper switch is only supported for HonClimate
|
49
|
+
cv.Optional(CONF_BEEPER): switch.switch_schema(
|
50
|
+
BeeperSwitch,
|
51
|
+
icon=ICON_VOLUME_HIGH,
|
52
|
+
entity_category=ENTITY_CATEGORY_CONFIG,
|
53
|
+
default_restore_mode="DISABLED",
|
54
|
+
),
|
55
|
+
# Quiet mode is only supported for HonClimate
|
56
|
+
cv.Optional(CONF_QUIET_MODE): switch.switch_schema(
|
57
|
+
QuietModeSwitch,
|
58
|
+
icon=ICON_VOLUME_OFF,
|
59
|
+
entity_category=ENTITY_CATEGORY_CONFIG,
|
60
|
+
default_restore_mode="DISABLED",
|
61
|
+
),
|
62
|
+
}
|
63
|
+
)
|
64
|
+
|
65
|
+
|
66
|
+
def _final_validate(config):
|
67
|
+
full_config = fv.full_config.get()
|
68
|
+
for switch_type in [CONF_BEEPER, CONF_QUIET_MODE]:
|
69
|
+
# Check switches that are only supported for HonClimate
|
70
|
+
if config.get(switch_type):
|
71
|
+
climate_path = full_config.get_path_for_id(config[CONF_HAIER_ID])[:-1]
|
72
|
+
climate_conf = full_config.get_config_for_path(climate_path)
|
73
|
+
protocol_type = climate_conf.get(CONF_PROTOCOL)
|
74
|
+
if protocol_type.casefold() != PROTOCOL_HON.casefold():
|
75
|
+
raise cv.Invalid(
|
76
|
+
f"{switch_type} switch is only supported for hon climate"
|
77
|
+
)
|
78
|
+
return config
|
79
|
+
|
80
|
+
|
81
|
+
FINAL_VALIDATE_SCHEMA = _final_validate
|
82
|
+
|
83
|
+
|
84
|
+
async def to_code(config):
|
85
|
+
parent = await cg.get_variable(config[CONF_HAIER_ID])
|
86
|
+
|
87
|
+
for switch_type in [CONF_DISPLAY, CONF_HEALTH_MODE, CONF_BEEPER, CONF_QUIET_MODE]:
|
88
|
+
if conf := config.get(switch_type):
|
89
|
+
sw_var = await switch.new_switch(conf)
|
90
|
+
await cg.register_parented(sw_var, parent)
|
91
|
+
cg.add(getattr(parent, f"set_{switch_type}_switch")(sw_var))
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#include "beeper.h"
|
2
|
+
|
3
|
+
namespace esphome {
|
4
|
+
namespace haier {
|
5
|
+
|
6
|
+
void BeeperSwitch::write_state(bool state) {
|
7
|
+
if (this->parent_->get_beeper_state() != state) {
|
8
|
+
this->parent_->set_beeper_state(state);
|
9
|
+
}
|
10
|
+
this->publish_state(state);
|
11
|
+
}
|
12
|
+
|
13
|
+
} // namespace haier
|
14
|
+
} // namespace esphome
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/components/switch/switch.h"
|
4
|
+
#include "../hon_climate.h"
|
5
|
+
|
6
|
+
namespace esphome {
|
7
|
+
namespace haier {
|
8
|
+
|
9
|
+
class BeeperSwitch : public switch_::Switch, public Parented<HonClimate> {
|
10
|
+
public:
|
11
|
+
BeeperSwitch() = default;
|
12
|
+
|
13
|
+
protected:
|
14
|
+
void write_state(bool state) override;
|
15
|
+
};
|
16
|
+
|
17
|
+
} // namespace haier
|
18
|
+
} // namespace esphome
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#include "display.h"
|
2
|
+
|
3
|
+
namespace esphome {
|
4
|
+
namespace haier {
|
5
|
+
|
6
|
+
void DisplaySwitch::write_state(bool state) {
|
7
|
+
if (this->parent_->get_display_state() != state) {
|
8
|
+
this->parent_->set_display_state(state);
|
9
|
+
}
|
10
|
+
this->publish_state(state);
|
11
|
+
}
|
12
|
+
|
13
|
+
} // namespace haier
|
14
|
+
} // namespace esphome
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/components/switch/switch.h"
|
4
|
+
#include "../haier_base.h"
|
5
|
+
|
6
|
+
namespace esphome {
|
7
|
+
namespace haier {
|
8
|
+
|
9
|
+
class DisplaySwitch : public switch_::Switch, public Parented<HaierClimateBase> {
|
10
|
+
public:
|
11
|
+
DisplaySwitch() = default;
|
12
|
+
|
13
|
+
protected:
|
14
|
+
void write_state(bool state) override;
|
15
|
+
};
|
16
|
+
|
17
|
+
} // namespace haier
|
18
|
+
} // namespace esphome
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#include "health_mode.h"
|
2
|
+
|
3
|
+
namespace esphome {
|
4
|
+
namespace haier {
|
5
|
+
|
6
|
+
void HealthModeSwitch::write_state(bool state) {
|
7
|
+
if (this->parent_->get_health_mode() != state) {
|
8
|
+
this->parent_->set_health_mode(state);
|
9
|
+
}
|
10
|
+
this->publish_state(state);
|
11
|
+
}
|
12
|
+
|
13
|
+
} // namespace haier
|
14
|
+
} // namespace esphome
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/components/switch/switch.h"
|
4
|
+
#include "../haier_base.h"
|
5
|
+
|
6
|
+
namespace esphome {
|
7
|
+
namespace haier {
|
8
|
+
|
9
|
+
class HealthModeSwitch : public switch_::Switch, public Parented<HaierClimateBase> {
|
10
|
+
public:
|
11
|
+
HealthModeSwitch() = default;
|
12
|
+
|
13
|
+
protected:
|
14
|
+
void write_state(bool state) override;
|
15
|
+
};
|
16
|
+
|
17
|
+
} // namespace haier
|
18
|
+
} // namespace esphome
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#include "quiet_mode.h"
|
2
|
+
|
3
|
+
namespace esphome {
|
4
|
+
namespace haier {
|
5
|
+
|
6
|
+
void QuietModeSwitch::write_state(bool state) {
|
7
|
+
if (this->parent_->get_quiet_mode_state() != state) {
|
8
|
+
this->parent_->set_quiet_mode_state(state);
|
9
|
+
}
|
10
|
+
this->publish_state(state);
|
11
|
+
}
|
12
|
+
|
13
|
+
} // namespace haier
|
14
|
+
} // namespace esphome
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/components/switch/switch.h"
|
4
|
+
#include "../hon_climate.h"
|
5
|
+
|
6
|
+
namespace esphome {
|
7
|
+
namespace haier {
|
8
|
+
|
9
|
+
class QuietModeSwitch : public switch_::Switch, public Parented<HonClimate> {
|
10
|
+
public:
|
11
|
+
QuietModeSwitch() = default;
|
12
|
+
|
13
|
+
protected:
|
14
|
+
void write_state(bool state) override;
|
15
|
+
};
|
16
|
+
|
17
|
+
} // namespace haier
|
18
|
+
} // namespace esphome
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#include <cstdio>
|
2
2
|
#include <cstring>
|
3
3
|
#include "hmac_md5.h"
|
4
|
+
#ifdef USE_MD5
|
4
5
|
#include "esphome/core/helpers.h"
|
5
6
|
|
6
7
|
namespace esphome {
|
@@ -54,3 +55,4 @@ bool HmacMD5::equals_hex(const char *expected) { return this->ohash_.equals_hex(
|
|
54
55
|
|
55
56
|
} // namespace hmac_md5
|
56
57
|
} // namespace esphome
|
58
|
+
#endif
|
@@ -1,8 +1,8 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include "esphome/core/defines.h"
|
4
|
+
#ifdef USE_MD5
|
4
5
|
#include "esphome/components/md5/md5.h"
|
5
|
-
|
6
6
|
#include <string>
|
7
7
|
|
8
8
|
namespace esphome {
|
@@ -46,3 +46,4 @@ class HmacMD5 {
|
|
46
46
|
|
47
47
|
} // namespace hmac_md5
|
48
48
|
} // namespace esphome
|
49
|
+
#endif
|
@@ -25,6 +25,7 @@ I2SAudioSpeaker = i2s_audio_ns.class_(
|
|
25
25
|
|
26
26
|
|
27
27
|
CONF_DAC_TYPE = "dac_type"
|
28
|
+
CONF_I2S_COMM_FMT = "i2s_comm_fmt"
|
28
29
|
|
29
30
|
i2s_dac_mode_t = cg.global_ns.enum("i2s_dac_mode_t")
|
30
31
|
INTERNAL_DAC_OPTIONS = {
|
@@ -33,6 +34,20 @@ INTERNAL_DAC_OPTIONS = {
|
|
33
34
|
CONF_STEREO: i2s_dac_mode_t.I2S_DAC_CHANNEL_BOTH_EN,
|
34
35
|
}
|
35
36
|
|
37
|
+
i2s_comm_format_t = cg.global_ns.enum("i2s_comm_format_t")
|
38
|
+
I2C_COMM_FMT_OPTIONS = {
|
39
|
+
"stand_i2s": i2s_comm_format_t.I2S_COMM_FORMAT_STAND_I2S,
|
40
|
+
"stand_msb": i2s_comm_format_t.I2S_COMM_FORMAT_STAND_MSB,
|
41
|
+
"stand_pcm_short": i2s_comm_format_t.I2S_COMM_FORMAT_STAND_PCM_SHORT,
|
42
|
+
"stand_pcm_long": i2s_comm_format_t.I2S_COMM_FORMAT_STAND_PCM_LONG,
|
43
|
+
"stand_max": i2s_comm_format_t.I2S_COMM_FORMAT_STAND_MAX,
|
44
|
+
"i2s_msb": i2s_comm_format_t.I2S_COMM_FORMAT_I2S_MSB,
|
45
|
+
"i2s_lsb": i2s_comm_format_t.I2S_COMM_FORMAT_I2S_LSB,
|
46
|
+
"pcm": i2s_comm_format_t.I2S_COMM_FORMAT_PCM,
|
47
|
+
"pcm_short": i2s_comm_format_t.I2S_COMM_FORMAT_PCM_SHORT,
|
48
|
+
"pcm_long": i2s_comm_format_t.I2S_COMM_FORMAT_PCM_LONG,
|
49
|
+
}
|
50
|
+
|
36
51
|
NO_INTERNAL_DAC_VARIANTS = [esp32.const.VARIANT_ESP32S2]
|
37
52
|
|
38
53
|
|
@@ -77,6 +92,9 @@ CONFIG_SCHEMA = cv.All(
|
|
77
92
|
cv.Required(
|
78
93
|
CONF_I2S_DOUT_PIN
|
79
94
|
): pins.internal_gpio_output_pin_number,
|
95
|
+
cv.Optional(CONF_I2S_COMM_FMT, default="stand_i2s"): cv.enum(
|
96
|
+
I2C_COMM_FMT_OPTIONS, lower=True
|
97
|
+
),
|
80
98
|
}
|
81
99
|
),
|
82
100
|
},
|
@@ -96,4 +114,5 @@ async def to_code(config):
|
|
96
114
|
cg.add(var.set_internal_dac_mode(config[CONF_CHANNEL]))
|
97
115
|
else:
|
98
116
|
cg.add(var.set_dout_pin(config[CONF_I2S_DOUT_PIN]))
|
117
|
+
cg.add(var.set_i2s_comm_fmt(config[CONF_I2S_COMM_FMT]))
|
99
118
|
cg.add(var.set_timeout(config[CONF_TIMEOUT]))
|
@@ -83,7 +83,7 @@ void I2SAudioSpeaker::player_task(void *params) {
|
|
83
83
|
.sample_rate = this_speaker->sample_rate_,
|
84
84
|
.bits_per_sample = this_speaker->bits_per_sample_,
|
85
85
|
.channel_format = this_speaker->channel_,
|
86
|
-
.communication_format =
|
86
|
+
.communication_format = this_speaker->i2s_comm_fmt_,
|
87
87
|
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
|
88
88
|
.dma_buf_count = 8,
|
89
89
|
.dma_buf_len = 256,
|
@@ -49,6 +49,7 @@ class I2SAudioSpeaker : public I2SAudioOut, public speaker::Speaker, public Comp
|
|
49
49
|
#if SOC_I2S_SUPPORTS_DAC
|
50
50
|
void set_internal_dac_mode(i2s_dac_mode_t mode) { this->internal_dac_mode_ = mode; }
|
51
51
|
#endif
|
52
|
+
void set_i2s_comm_fmt(i2s_comm_format_t mode) { this->i2s_comm_fmt_ = mode; }
|
52
53
|
|
53
54
|
void start() override;
|
54
55
|
void stop() override;
|
@@ -76,6 +77,7 @@ class I2SAudioSpeaker : public I2SAudioOut, public speaker::Speaker, public Comp
|
|
76
77
|
#if SOC_I2S_SUPPORTS_DAC
|
77
78
|
i2s_dac_mode_t internal_dac_mode_{I2S_DAC_CHANNEL_DISABLE};
|
78
79
|
#endif
|
80
|
+
i2s_comm_format_t i2s_comm_fmt_;
|
79
81
|
};
|
80
82
|
|
81
83
|
} // namespace i2s_audio
|
@@ -89,6 +89,7 @@ class ILI9XXXDisplay : public display::DisplayBuffer,
|
|
89
89
|
|
90
90
|
void dump_config() override;
|
91
91
|
void setup() override;
|
92
|
+
void on_shutdown() override { this->command(ILI9XXX_SLPIN); }
|
92
93
|
|
93
94
|
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
|
94
95
|
void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order,
|
@@ -1,18 +1,17 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
import logging
|
4
|
-
|
5
3
|
import hashlib
|
6
4
|
import io
|
5
|
+
import logging
|
7
6
|
from pathlib import Path
|
8
7
|
import re
|
9
|
-
from magic import Magic
|
10
8
|
|
11
|
-
|
9
|
+
import puremagic
|
10
|
+
|
11
|
+
from esphome import core, external_files
|
12
|
+
import esphome.codegen as cg
|
12
13
|
from esphome.components import font
|
13
|
-
from esphome import external_files
|
14
14
|
import esphome.config_validation as cv
|
15
|
-
import esphome.codegen as cg
|
16
15
|
from esphome.const import (
|
17
16
|
CONF_DITHER,
|
18
17
|
CONF_FILE,
|
@@ -238,13 +237,12 @@ CONFIG_SCHEMA = cv.All(font.validate_pillow_installed, IMAGE_SCHEMA)
|
|
238
237
|
|
239
238
|
|
240
239
|
def load_svg_image(file: bytes, resize: tuple[int, int]):
|
241
|
-
# Local
|
242
|
-
|
243
|
-
|
244
|
-
# This import is only needed in case of SVG images; adding it
|
240
|
+
# Local imports only to allow "validate_pillow_installed" to run *before* importing it
|
241
|
+
# cairosvg is only needed in case of SVG images; adding it
|
245
242
|
# to the top would force configurations not using SVG to also have it
|
246
243
|
# installed for no reason.
|
247
244
|
from cairosvg import svg2png
|
245
|
+
from PIL import Image
|
248
246
|
|
249
247
|
if resize:
|
250
248
|
req_width, req_height = resize
|
@@ -274,14 +272,16 @@ async def to_code(config):
|
|
274
272
|
elif conf_file[CONF_SOURCE] == SOURCE_WEB:
|
275
273
|
path = compute_local_image_path(conf_file).as_posix()
|
276
274
|
|
275
|
+
else:
|
276
|
+
raise core.EsphomeError(f"Unknown image source: {conf_file[CONF_SOURCE]}")
|
277
|
+
|
277
278
|
try:
|
278
279
|
with open(path, "rb") as f:
|
279
280
|
file_contents = f.read()
|
280
281
|
except Exception as e:
|
281
282
|
raise core.EsphomeError(f"Could not load image file {path}: {e}")
|
282
283
|
|
283
|
-
|
284
|
-
file_type = mime.from_buffer(file_contents)
|
284
|
+
file_type = puremagic.from_string(file_contents, mime=True)
|
285
285
|
|
286
286
|
resize = config.get(CONF_RESIZE)
|
287
287
|
if "svg" in file_type:
|
@@ -79,6 +79,50 @@ Color Image::get_pixel(int x, int y, Color color_on, Color color_off) const {
|
|
79
79
|
return color_off;
|
80
80
|
}
|
81
81
|
}
|
82
|
+
#ifdef USE_LVGL
|
83
|
+
lv_img_dsc_t *Image::get_lv_img_dsc() {
|
84
|
+
// lazily construct lvgl image_dsc.
|
85
|
+
if (this->dsc_.data != this->data_start_) {
|
86
|
+
this->dsc_.data = this->data_start_;
|
87
|
+
this->dsc_.header.always_zero = 0;
|
88
|
+
this->dsc_.header.reserved = 0;
|
89
|
+
this->dsc_.header.w = this->width_;
|
90
|
+
this->dsc_.header.h = this->height_;
|
91
|
+
this->dsc_.data_size = image_type_to_width_stride(this->dsc_.header.w * this->dsc_.header.h, this->get_type());
|
92
|
+
switch (this->get_type()) {
|
93
|
+
case IMAGE_TYPE_BINARY:
|
94
|
+
this->dsc_.header.cf = LV_IMG_CF_ALPHA_1BIT;
|
95
|
+
break;
|
96
|
+
|
97
|
+
case IMAGE_TYPE_GRAYSCALE:
|
98
|
+
this->dsc_.header.cf = LV_IMG_CF_ALPHA_8BIT;
|
99
|
+
break;
|
100
|
+
|
101
|
+
case IMAGE_TYPE_RGB24:
|
102
|
+
this->dsc_.header.cf = LV_IMG_CF_RGB888;
|
103
|
+
break;
|
104
|
+
|
105
|
+
case IMAGE_TYPE_RGB565:
|
106
|
+
#if LV_COLOR_DEPTH == 16
|
107
|
+
this->dsc_.header.cf = this->has_transparency() ? LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED : LV_IMG_CF_TRUE_COLOR;
|
108
|
+
#else
|
109
|
+
this->dsc_.header.cf = LV_IMG_CF_RGB565;
|
110
|
+
#endif
|
111
|
+
break;
|
112
|
+
|
113
|
+
case image::IMAGE_TYPE_RGBA:
|
114
|
+
#if LV_COLOR_DEPTH == 32
|
115
|
+
this->dsc_.header.cf = LV_IMG_CF_TRUE_COLOR;
|
116
|
+
#else
|
117
|
+
this->dsc_.header.cf = LV_IMG_CF_RGBA8888;
|
118
|
+
#endif
|
119
|
+
break;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
return &this->dsc_;
|
123
|
+
}
|
124
|
+
#endif // USE_LVGL
|
125
|
+
|
82
126
|
bool Image::get_binary_pixel_(int x, int y) const {
|
83
127
|
const uint32_t width_8 = ((this->width_ + 7u) / 8u) * 8u;
|
84
128
|
const uint32_t pos = x + y * width_8;
|
esphome/components/image/image.h
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
#pragma once
|
2
2
|
#include "esphome/core/color.h"
|
3
|
-
#include "esphome/components/display/
|
3
|
+
#include "esphome/components/display/display.h"
|
4
|
+
|
5
|
+
#ifdef USE_LVGL
|
6
|
+
// required for clang-tidy
|
7
|
+
#ifndef LV_CONF_H
|
8
|
+
#define LV_CONF_SKIP 1 // NOLINT
|
9
|
+
#endif // LV_CONF_H
|
10
|
+
|
11
|
+
#include <lvgl.h>
|
12
|
+
#endif // USE_LVGL
|
4
13
|
|
5
14
|
namespace esphome {
|
6
15
|
namespace image {
|
@@ -37,7 +46,7 @@ class Image : public display::BaseImage {
|
|
37
46
|
Color get_pixel(int x, int y, Color color_on = display::COLOR_ON, Color color_off = display::COLOR_OFF) const;
|
38
47
|
int get_width() const override;
|
39
48
|
int get_height() const override;
|
40
|
-
const uint8_t *get_data_start() { return this->data_start_; }
|
49
|
+
const uint8_t *get_data_start() const { return this->data_start_; }
|
41
50
|
ImageType get_type() const;
|
42
51
|
|
43
52
|
void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override;
|
@@ -45,6 +54,9 @@ class Image : public display::BaseImage {
|
|
45
54
|
void set_transparency(bool transparent) { transparent_ = transparent; }
|
46
55
|
bool has_transparency() const { return transparent_; }
|
47
56
|
|
57
|
+
#ifdef USE_LVGL
|
58
|
+
lv_img_dsc_t *get_lv_img_dsc();
|
59
|
+
#endif
|
48
60
|
protected:
|
49
61
|
bool get_binary_pixel_(int x, int y) const;
|
50
62
|
Color get_rgb24_pixel_(int x, int y) const;
|
@@ -57,6 +69,9 @@ class Image : public display::BaseImage {
|
|
57
69
|
ImageType type_;
|
58
70
|
const uint8_t *data_start_;
|
59
71
|
bool transparent_;
|
72
|
+
#ifdef USE_LVGL
|
73
|
+
lv_img_dsc_t dsc_{};
|
74
|
+
#endif
|
60
75
|
};
|
61
76
|
|
62
77
|
} // namespace image
|
@@ -53,6 +53,8 @@ MODELS = {
|
|
53
53
|
"inkplate_10": InkplateModel.INKPLATE_10,
|
54
54
|
"inkplate_6_plus": InkplateModel.INKPLATE_6_PLUS,
|
55
55
|
"inkplate_6_v2": InkplateModel.INKPLATE_6_V2,
|
56
|
+
"inkplate_5": InkplateModel.INKPLATE_5,
|
57
|
+
"inkplate_5_v2": InkplateModel.INKPLATE_5_V2,
|
56
58
|
}
|
57
59
|
|
58
60
|
CONFIG_SCHEMA = cv.All(
|
@@ -15,6 +15,8 @@ enum InkplateModel : uint8_t {
|
|
15
15
|
INKPLATE_10 = 1,
|
16
16
|
INKPLATE_6_PLUS = 2,
|
17
17
|
INKPLATE_6_V2 = 3,
|
18
|
+
INKPLATE_5 = 4,
|
19
|
+
INKPLATE_5_V2 = 5,
|
18
20
|
};
|
19
21
|
|
20
22
|
class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
@@ -29,7 +31,7 @@ class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
|
29
31
|
const uint8_t pixelMaskLUT[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
|
30
32
|
const uint8_t pixelMaskGLUT[2] = {0x0F, 0xF0};
|
31
33
|
|
32
|
-
const uint8_t waveform3BitAll[
|
34
|
+
const uint8_t waveform3BitAll[6][8][9] = {// INKPLATE_6
|
33
35
|
{{0, 1, 1, 0, 0, 1, 1, 0, 0},
|
34
36
|
{0, 1, 2, 1, 1, 2, 1, 0, 0},
|
35
37
|
{1, 1, 1, 2, 2, 1, 0, 0, 0},
|
@@ -64,7 +66,25 @@ class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
|
64
66
|
{1, 1, 1, 1, 2, 2, 1, 0, 0},
|
65
67
|
{0, 1, 1, 1, 2, 2, 1, 0, 0},
|
66
68
|
{0, 0, 0, 0, 1, 1, 2, 0, 0},
|
67
|
-
{0, 0, 0, 0, 0, 1, 2, 0, 0}}
|
69
|
+
{0, 0, 0, 0, 0, 1, 2, 0, 0}},
|
70
|
+
// INKPLATE_5
|
71
|
+
{{0, 0, 1, 1, 0, 1, 1, 1, 0},
|
72
|
+
{0, 1, 1, 1, 1, 2, 0, 1, 0},
|
73
|
+
{1, 2, 2, 0, 2, 1, 1, 1, 0},
|
74
|
+
{1, 1, 1, 2, 0, 1, 1, 2, 0},
|
75
|
+
{0, 1, 1, 1, 2, 0, 1, 2, 0},
|
76
|
+
{0, 0, 0, 1, 1, 2, 1, 2, 0},
|
77
|
+
{1, 1, 1, 2, 0, 2, 1, 2, 0},
|
78
|
+
{0, 0, 0, 0, 0, 0, 0, 0, 0}},
|
79
|
+
// INKPLATE_5_V2
|
80
|
+
{{0, 0, 1, 1, 2, 1, 1, 1, 0},
|
81
|
+
{1, 1, 2, 2, 1, 2, 1, 1, 0},
|
82
|
+
{0, 1, 2, 2, 1, 1, 2, 1, 0},
|
83
|
+
{0, 0, 1, 1, 1, 1, 1, 2, 0},
|
84
|
+
{1, 2, 1, 2, 1, 1, 1, 2, 0},
|
85
|
+
{0, 1, 1, 1, 2, 0, 1, 2, 0},
|
86
|
+
{1, 1, 1, 2, 2, 2, 1, 2, 0},
|
87
|
+
{0, 0, 0, 0, 0, 0, 0, 0, 0}}};
|
68
88
|
|
69
89
|
void set_greyscale(bool greyscale) {
|
70
90
|
this->greyscale_ = greyscale;
|
@@ -146,6 +166,10 @@ class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
|
146
166
|
return 800;
|
147
167
|
} else if (this->model_ == INKPLATE_10) {
|
148
168
|
return 1200;
|
169
|
+
} else if (this->model_ == INKPLATE_5) {
|
170
|
+
return 960;
|
171
|
+
} else if (this->model_ == INKPLATE_5_V2) {
|
172
|
+
return 1280;
|
149
173
|
} else if (this->model_ == INKPLATE_6_PLUS) {
|
150
174
|
return 1024;
|
151
175
|
}
|
@@ -155,6 +179,10 @@ class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
|
155
179
|
int get_height_internal() override {
|
156
180
|
if (this->model_ == INKPLATE_6 || this->model_ == INKPLATE_6_V2) {
|
157
181
|
return 600;
|
182
|
+
} else if (this->model_ == INKPLATE_5) {
|
183
|
+
return 540;
|
184
|
+
} else if (this->model_ == INKPLATE_5_V2) {
|
185
|
+
return 720;
|
158
186
|
} else if (this->model_ == INKPLATE_10) {
|
159
187
|
return 825;
|
160
188
|
} else if (this->model_ == INKPLATE_6_PLUS) {
|
@@ -18,7 +18,7 @@ from esphome.const import (
|
|
18
18
|
CONF_RESTORE_MODE,
|
19
19
|
CONF_TRIGGER_ID,
|
20
20
|
CONF_WARM_WHITE_COLOR_TEMPERATURE,
|
21
|
-
|
21
|
+
CONF_WEB_SERVER,
|
22
22
|
)
|
23
23
|
from esphome.core import coroutine_with_priority
|
24
24
|
from esphome.cpp_helpers import setup_entity
|
@@ -181,9 +181,8 @@ async def setup_light_core_(light_var, output_var, config):
|
|
181
181
|
mqtt_ = cg.new_Pvariable(mqtt_id, light_var)
|
182
182
|
await mqtt.register_mqtt_component(mqtt_, config)
|
183
183
|
|
184
|
-
if
|
185
|
-
|
186
|
-
web_server.add_entity_to_sorting_list(web_server_, light_var, config)
|
184
|
+
if web_server_config := config.get(CONF_WEB_SERVER):
|
185
|
+
await web_server.add_entity_config(light_var, web_server_config)
|
187
186
|
|
188
187
|
|
189
188
|
async def register_light(output_var, config):
|
@@ -9,7 +9,7 @@ from esphome.const import (
|
|
9
9
|
CONF_ON_LOCK,
|
10
10
|
CONF_ON_UNLOCK,
|
11
11
|
CONF_TRIGGER_ID,
|
12
|
-
|
12
|
+
CONF_WEB_SERVER,
|
13
13
|
)
|
14
14
|
from esphome.core import CORE, coroutine_with_priority
|
15
15
|
from esphome.cpp_helpers import setup_entity
|
@@ -66,9 +66,8 @@ async def setup_lock_core_(var, config):
|
|
66
66
|
mqtt_ = cg.new_Pvariable(mqtt_id, var)
|
67
67
|
await mqtt.register_mqtt_component(mqtt_, config)
|
68
68
|
|
69
|
-
if
|
70
|
-
|
71
|
-
web_server.add_entity_to_sorting_list(web_server_, var, config)
|
69
|
+
if web_server_config := config.get(CONF_WEB_SERVER):
|
70
|
+
await web_server.add_entity_config(var, web_server_config)
|
72
71
|
|
73
72
|
|
74
73
|
async def register_lock(var, config):
|