esphome 2024.9.2__py3-none-any.whl → 2024.10.0b1__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/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 +11 -0
- 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/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/select/__init__.py +3 -4
- esphome/components/sensor/__init__.py +3 -4
- 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/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 +212 -33
- 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-2024.9.2.dist-info → esphome-2024.10.0b1.dist-info}/METADATA +5 -3
- {esphome-2024.9.2.dist-info → esphome-2024.10.0b1.dist-info}/RECORD +188 -139
- {esphome-2024.9.2.dist-info → esphome-2024.10.0b1.dist-info}/LICENSE +0 -0
- {esphome-2024.9.2.dist-info → esphome-2024.10.0b1.dist-info}/WHEEL +0 -0
- {esphome-2024.9.2.dist-info → esphome-2024.10.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2024.9.2.dist-info → esphome-2024.10.0b1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
from esphome import automation
|
2
|
+
from esphome.automation import maybe_simple_id
|
3
|
+
import esphome.codegen as cg
|
4
|
+
import esphome.config_validation as cv
|
5
|
+
from esphome.const import CONF_ID, CONF_VOLUME
|
6
|
+
from esphome.core import coroutine_with_priority
|
7
|
+
|
8
|
+
CODEOWNERS = ["@kbx81"]
|
9
|
+
IS_PLATFORM_COMPONENT = True
|
10
|
+
|
11
|
+
audio_dac_ns = cg.esphome_ns.namespace("audio_dac")
|
12
|
+
AudioDac = audio_dac_ns.class_("AudioDac")
|
13
|
+
|
14
|
+
MuteOffAction = audio_dac_ns.class_("MuteOffAction", automation.Action)
|
15
|
+
MuteOnAction = audio_dac_ns.class_("MuteOnAction", automation.Action)
|
16
|
+
SetVolumeAction = audio_dac_ns.class_("SetVolumeAction", automation.Action)
|
17
|
+
|
18
|
+
|
19
|
+
MUTE_ACTION_SCHEMA = maybe_simple_id(
|
20
|
+
{
|
21
|
+
cv.GenerateID(): cv.use_id(AudioDac),
|
22
|
+
}
|
23
|
+
)
|
24
|
+
|
25
|
+
SET_VOLUME_ACTION_SCHEMA = cv.maybe_simple_value(
|
26
|
+
{
|
27
|
+
cv.GenerateID(): cv.use_id(AudioDac),
|
28
|
+
cv.Required(CONF_VOLUME): cv.templatable(cv.percentage),
|
29
|
+
},
|
30
|
+
key=CONF_VOLUME,
|
31
|
+
)
|
32
|
+
|
33
|
+
|
34
|
+
@automation.register_action("audio_dac.mute_off", MuteOffAction, MUTE_ACTION_SCHEMA)
|
35
|
+
@automation.register_action("audio_dac.mute_on", MuteOnAction, MUTE_ACTION_SCHEMA)
|
36
|
+
async def audio_dac_mute_action_to_code(config, action_id, template_arg, args):
|
37
|
+
paren = await cg.get_variable(config[CONF_ID])
|
38
|
+
return cg.new_Pvariable(action_id, template_arg, paren)
|
39
|
+
|
40
|
+
|
41
|
+
@automation.register_action(
|
42
|
+
"audio_dac.set_volume", SetVolumeAction, SET_VOLUME_ACTION_SCHEMA
|
43
|
+
)
|
44
|
+
async def audio_dac_set_volume_to_code(config, action_id, template_arg, args):
|
45
|
+
paren = await cg.get_variable(config[CONF_ID])
|
46
|
+
var = cg.new_Pvariable(action_id, template_arg, paren)
|
47
|
+
|
48
|
+
template_ = await cg.templatable(config.get(CONF_VOLUME), args, float)
|
49
|
+
cg.add(var.set_volume(template_))
|
50
|
+
|
51
|
+
return var
|
52
|
+
|
53
|
+
|
54
|
+
@coroutine_with_priority(100.0)
|
55
|
+
async def to_code(config):
|
56
|
+
cg.add_define("USE_AUDIO_DAC")
|
57
|
+
cg.add_global(audio_dac_ns.using)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/core/defines.h"
|
4
|
+
#include "esphome/core/hal.h"
|
5
|
+
|
6
|
+
namespace esphome {
|
7
|
+
namespace audio_dac {
|
8
|
+
|
9
|
+
class AudioDac {
|
10
|
+
public:
|
11
|
+
virtual bool set_mute_off() = 0;
|
12
|
+
virtual bool set_mute_on() = 0;
|
13
|
+
virtual bool set_volume(float volume) = 0;
|
14
|
+
|
15
|
+
virtual bool is_muted() = 0;
|
16
|
+
virtual float volume() = 0;
|
17
|
+
|
18
|
+
protected:
|
19
|
+
bool is_muted_{false};
|
20
|
+
};
|
21
|
+
|
22
|
+
} // namespace audio_dac
|
23
|
+
} // namespace esphome
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/core/automation.h"
|
4
|
+
#include "esphome/core/component.h"
|
5
|
+
#include "audio_dac.h"
|
6
|
+
|
7
|
+
namespace esphome {
|
8
|
+
namespace audio_dac {
|
9
|
+
|
10
|
+
template<typename... Ts> class MuteOffAction : public Action<Ts...> {
|
11
|
+
public:
|
12
|
+
explicit MuteOffAction(AudioDac *audio_dac) : audio_dac_(audio_dac) {}
|
13
|
+
|
14
|
+
void play(Ts... x) override { this->audio_dac_->set_mute_off(); }
|
15
|
+
|
16
|
+
protected:
|
17
|
+
AudioDac *audio_dac_;
|
18
|
+
};
|
19
|
+
|
20
|
+
template<typename... Ts> class MuteOnAction : public Action<Ts...> {
|
21
|
+
public:
|
22
|
+
explicit MuteOnAction(AudioDac *audio_dac) : audio_dac_(audio_dac) {}
|
23
|
+
|
24
|
+
void play(Ts... x) override { this->audio_dac_->set_mute_on(); }
|
25
|
+
|
26
|
+
protected:
|
27
|
+
AudioDac *audio_dac_;
|
28
|
+
};
|
29
|
+
|
30
|
+
template<typename... Ts> class SetVolumeAction : public Action<Ts...> {
|
31
|
+
public:
|
32
|
+
explicit SetVolumeAction(AudioDac *audio_dac) : audio_dac_(audio_dac) {}
|
33
|
+
|
34
|
+
TEMPLATABLE_VALUE(float, volume)
|
35
|
+
|
36
|
+
void play(Ts... x) override { this->audio_dac_->set_volume(this->volume_.value(x...)); }
|
37
|
+
|
38
|
+
protected:
|
39
|
+
AudioDac *audio_dac_;
|
40
|
+
};
|
41
|
+
|
42
|
+
} // namespace audio_dac
|
43
|
+
} // namespace esphome
|
@@ -157,8 +157,11 @@ void BangBangClimate::switch_to_action_(climate::ClimateAction action) {
|
|
157
157
|
default:
|
158
158
|
trig = nullptr;
|
159
159
|
}
|
160
|
-
|
161
|
-
|
160
|
+
if (trig != nullptr) {
|
161
|
+
trig->trigger();
|
162
|
+
} else {
|
163
|
+
ESP_LOGW(TAG, "trig not set - unsupported action");
|
164
|
+
}
|
162
165
|
this->action = action;
|
163
166
|
this->prev_trigger_ = trig;
|
164
167
|
this->publish_state();
|
@@ -13,8 +13,10 @@ float bedjet_temp_to_f(const uint8_t temp) {
|
|
13
13
|
|
14
14
|
/** Cleans up the packet before sending. */
|
15
15
|
BedjetPacket *BedjetCodec::clean_packet_() {
|
16
|
-
// So far no commands require more than 2 bytes of data
|
17
|
-
|
16
|
+
// So far no commands require more than 2 bytes of data
|
17
|
+
if (this->packet_.data_length > 2) {
|
18
|
+
ESP_LOGW(TAG, "Packet may be malformed");
|
19
|
+
}
|
18
20
|
for (int i = this->packet_.data_length; i < 2; i++) {
|
19
21
|
this->packet_.data[i] = '\0';
|
20
22
|
}
|
@@ -25,7 +25,7 @@ from esphome.const import (
|
|
25
25
|
CONF_STATE,
|
26
26
|
CONF_TIMING,
|
27
27
|
CONF_TRIGGER_ID,
|
28
|
-
|
28
|
+
CONF_WEB_SERVER,
|
29
29
|
DEVICE_CLASS_BATTERY,
|
30
30
|
DEVICE_CLASS_BATTERY_CHARGING,
|
31
31
|
DEVICE_CLASS_CARBON_MONOXIDE,
|
@@ -543,9 +543,8 @@ async def setup_binary_sensor_core_(var, config):
|
|
543
543
|
mqtt_ = cg.new_Pvariable(mqtt_id, var)
|
544
544
|
await mqtt.register_mqtt_component(mqtt_, config)
|
545
545
|
|
546
|
-
if
|
547
|
-
|
548
|
-
web_server.add_entity_to_sorting_list(web_server_, var, config)
|
546
|
+
if web_server_config := config.get(CONF_WEB_SERVER):
|
547
|
+
await web_server.add_entity_config(var, web_server_config)
|
549
548
|
|
550
549
|
|
551
550
|
async def register_binary_sensor(var, config):
|
@@ -11,7 +11,7 @@ from esphome.const import (
|
|
11
11
|
CONF_MQTT_ID,
|
12
12
|
CONF_ON_PRESS,
|
13
13
|
CONF_TRIGGER_ID,
|
14
|
-
|
14
|
+
CONF_WEB_SERVER,
|
15
15
|
DEVICE_CLASS_EMPTY,
|
16
16
|
DEVICE_CLASS_IDENTIFY,
|
17
17
|
DEVICE_CLASS_RESTART,
|
@@ -97,9 +97,8 @@ async def setup_button_core_(var, config):
|
|
97
97
|
mqtt_ = cg.new_Pvariable(mqtt_id, var)
|
98
98
|
await mqtt.register_mqtt_component(mqtt_, config)
|
99
99
|
|
100
|
-
if
|
101
|
-
|
102
|
-
web_server.add_entity_to_sorting_list(web_server_, var, config)
|
100
|
+
if web_server_config := config.get(CONF_WEB_SERVER):
|
101
|
+
await web_server.add_entity_config(var, web_server_config)
|
103
102
|
|
104
103
|
|
105
104
|
async def register_button(var, config):
|
@@ -1,18 +1,20 @@
|
|
1
1
|
from esphome import pins
|
2
2
|
import esphome.codegen as cg
|
3
3
|
from esphome.components import i2c
|
4
|
+
from esphome.components.i2c import I2CBus
|
4
5
|
import esphome.config_validation as cv
|
5
6
|
from esphome.const import (
|
7
|
+
CONF_I2C_ID,
|
6
8
|
CONF_ID,
|
7
9
|
CONF_INPUT,
|
8
10
|
CONF_INVERTED,
|
9
11
|
CONF_MODE,
|
10
12
|
CONF_NUMBER,
|
13
|
+
CONF_OPEN_DRAIN,
|
11
14
|
CONF_OUTPUT,
|
12
|
-
CONF_RESTORE_VALUE,
|
13
15
|
)
|
14
16
|
|
15
|
-
CODEOWNERS = ["@jesterret"]
|
17
|
+
CODEOWNERS = ["@jesterret", "@clydebarrow"]
|
16
18
|
DEPENDENCIES = ["i2c"]
|
17
19
|
MULTI_CONF = True
|
18
20
|
ch422g_ns = cg.esphome_ns.namespace("ch422g")
|
@@ -23,29 +25,36 @@ CH422GGPIOPin = ch422g_ns.class_(
|
|
23
25
|
)
|
24
26
|
|
25
27
|
CONF_CH422G = "ch422g"
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
.extend(i2c.i2c_device_schema(0x24))
|
35
|
-
)
|
28
|
+
|
29
|
+
# Note that no address is configurable - each register in the CH422G has a dedicated i2c address
|
30
|
+
CONFIG_SCHEMA = cv.Schema(
|
31
|
+
{
|
32
|
+
cv.GenerateID(CONF_ID): cv.declare_id(CH422GComponent),
|
33
|
+
cv.GenerateID(CONF_I2C_ID): cv.use_id(I2CBus),
|
34
|
+
}
|
35
|
+
).extend(cv.COMPONENT_SCHEMA)
|
36
36
|
|
37
37
|
|
38
38
|
async def to_code(config):
|
39
39
|
var = cg.new_Pvariable(config[CONF_ID])
|
40
|
-
cg.add(var.set_restore_value(config[CONF_RESTORE_VALUE]))
|
41
40
|
await cg.register_component(var, config)
|
42
|
-
|
41
|
+
# Can't use register_i2c_device because there is no CONF_ADDRESS
|
42
|
+
parent = await cg.get_variable(config[CONF_I2C_ID])
|
43
|
+
cg.add(var.set_i2c_bus(parent))
|
44
|
+
|
45
|
+
|
46
|
+
# This is used as a final validation step so that modes have been fully transformed.
|
47
|
+
def pin_mode_check(pin_config, _):
|
48
|
+
if pin_config[CONF_MODE][CONF_INPUT] and pin_config[CONF_NUMBER] >= 8:
|
49
|
+
raise cv.Invalid("CH422G only supports input on pins 0-7")
|
50
|
+
if pin_config[CONF_MODE][CONF_OPEN_DRAIN] and pin_config[CONF_NUMBER] < 8:
|
51
|
+
raise cv.Invalid("CH422G only supports open drain output on pins 8-11")
|
43
52
|
|
44
53
|
|
45
54
|
CH422G_PIN_SCHEMA = pins.gpio_base_schema(
|
46
55
|
CH422GGPIOPin,
|
47
|
-
cv.int_range(min=0, max=
|
48
|
-
modes=[CONF_INPUT, CONF_OUTPUT],
|
56
|
+
cv.int_range(min=0, max=11),
|
57
|
+
modes=[CONF_INPUT, CONF_OUTPUT, CONF_OPEN_DRAIN],
|
49
58
|
).extend(
|
50
59
|
{
|
51
60
|
cv.Required(CONF_CH422G): cv.use_id(CH422GComponent),
|
@@ -53,7 +62,7 @@ CH422G_PIN_SCHEMA = pins.gpio_base_schema(
|
|
53
62
|
)
|
54
63
|
|
55
64
|
|
56
|
-
@pins.PIN_SCHEMA_REGISTRY.register(CONF_CH422G, CH422G_PIN_SCHEMA)
|
65
|
+
@pins.PIN_SCHEMA_REGISTRY.register(CONF_CH422G, CH422G_PIN_SCHEMA, pin_mode_check)
|
57
66
|
async def ch422g_pin_to_code(config):
|
58
67
|
var = cg.new_Pvariable(config[CONF_ID])
|
59
68
|
parent = await cg.get_variable(config[CONF_CH422G])
|
@@ -4,33 +4,33 @@
|
|
4
4
|
namespace esphome {
|
5
5
|
namespace ch422g {
|
6
6
|
|
7
|
-
const uint8_t
|
8
|
-
const uint8_t
|
9
|
-
const uint8_t
|
7
|
+
static const uint8_t CH422G_REG_MODE = 0x24;
|
8
|
+
static const uint8_t CH422G_MODE_OUTPUT = 0x01; // enables output mode on 0-7
|
9
|
+
static const uint8_t CH422G_MODE_OPEN_DRAIN = 0x04; // enables open drain mode on 8-11
|
10
|
+
static const uint8_t CH422G_REG_IN = 0x26; // read reg for input bits
|
11
|
+
static const uint8_t CH422G_REG_OUT = 0x38; // write reg for output bits 0-7
|
12
|
+
static const uint8_t CH422G_REG_OUT_UPPER = 0x23; // write reg for output bits 8-11
|
10
13
|
|
11
14
|
static const char *const TAG = "ch422g";
|
12
15
|
|
13
16
|
void CH422GComponent::setup() {
|
14
17
|
ESP_LOGCONFIG(TAG, "Setting up CH422G...");
|
15
|
-
//
|
16
|
-
|
18
|
+
// set outputs before mode
|
19
|
+
this->write_outputs_();
|
20
|
+
// Set mode and check for errors
|
21
|
+
if (!this->set_mode_(this->mode_value_) || !this->read_inputs_()) {
|
17
22
|
ESP_LOGE(TAG, "CH422G not detected at 0x%02X", this->address_);
|
18
23
|
this->mark_failed();
|
19
24
|
return;
|
20
25
|
}
|
21
26
|
|
22
|
-
|
23
|
-
|
24
|
-
this->write_output_(OUT_REG_DEFAULT_VAL);
|
25
|
-
}
|
26
|
-
|
27
|
-
ESP_LOGD(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
|
28
|
-
this->status_has_error());
|
27
|
+
ESP_LOGCONFIG(TAG, "Initialization complete. Warning: %d, Error: %d", this->status_has_warning(),
|
28
|
+
this->status_has_error());
|
29
29
|
}
|
30
30
|
|
31
31
|
void CH422GComponent::loop() {
|
32
32
|
// Clear all the previously read flags.
|
33
|
-
this->
|
33
|
+
this->pin_read_flags_ = 0x00;
|
34
34
|
}
|
35
35
|
|
36
36
|
void CH422GComponent::dump_config() {
|
@@ -41,68 +41,82 @@ void CH422GComponent::dump_config() {
|
|
41
41
|
}
|
42
42
|
}
|
43
43
|
|
44
|
-
|
45
|
-
|
44
|
+
void CH422GComponent::pin_mode(uint8_t pin, gpio::Flags flags) {
|
45
|
+
if (pin < 8) {
|
46
|
+
if (flags & gpio::FLAG_OUTPUT) {
|
47
|
+
this->mode_value_ |= CH422G_MODE_OUTPUT;
|
48
|
+
}
|
49
|
+
} else {
|
50
|
+
if (flags & gpio::FLAG_OPEN_DRAIN) {
|
51
|
+
this->mode_value_ |= CH422G_MODE_OPEN_DRAIN;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
46
55
|
|
47
56
|
bool CH422GComponent::digital_read(uint8_t pin) {
|
48
|
-
if (this->
|
57
|
+
if (this->pin_read_flags_ == 0 || this->pin_read_flags_ & (1 << pin)) {
|
49
58
|
// Read values on first access or in case it's being read again in the same loop
|
50
59
|
this->read_inputs_();
|
51
60
|
}
|
52
61
|
|
53
|
-
this->
|
54
|
-
return this->
|
62
|
+
this->pin_read_flags_ |= (1 << pin);
|
63
|
+
return (this->input_bits_ & (1 << pin)) != 0;
|
55
64
|
}
|
56
65
|
|
57
66
|
void CH422GComponent::digital_write(uint8_t pin, bool value) {
|
58
67
|
if (value) {
|
59
|
-
this->
|
68
|
+
this->output_bits_ |= (1 << pin);
|
60
69
|
} else {
|
61
|
-
this->
|
70
|
+
this->output_bits_ &= ~(1 << pin);
|
62
71
|
}
|
72
|
+
this->write_outputs_();
|
63
73
|
}
|
64
74
|
|
65
75
|
bool CH422GComponent::read_inputs_() {
|
66
76
|
if (this->is_failed()) {
|
67
77
|
return false;
|
68
78
|
}
|
69
|
-
|
70
|
-
|
71
|
-
if (
|
72
|
-
this->
|
73
|
-
|
79
|
+
uint8_t result;
|
80
|
+
// reading inputs requires the chip to be in input mode, possibly temporarily.
|
81
|
+
if (this->mode_value_ & CH422G_MODE_OUTPUT) {
|
82
|
+
this->set_mode_(this->mode_value_ & ~CH422G_MODE_OUTPUT);
|
83
|
+
result = this->read_reg_(CH422G_REG_IN);
|
84
|
+
this->set_mode_(this->mode_value_);
|
85
|
+
} else {
|
86
|
+
result = this->read_reg_(CH422G_REG_IN);
|
74
87
|
}
|
88
|
+
this->input_bits_ = result;
|
89
|
+
this->status_clear_warning();
|
90
|
+
return true;
|
91
|
+
}
|
75
92
|
|
76
|
-
|
77
|
-
|
78
|
-
|
93
|
+
// Write a register. Can't use the standard write_byte() method because there is no single pre-configured i2c address.
|
94
|
+
bool CH422GComponent::write_reg_(uint8_t reg, uint8_t value) {
|
95
|
+
auto err = this->bus_->write(reg, &value, 1);
|
96
|
+
if (err != i2c::ERROR_OK) {
|
97
|
+
this->status_set_warning(str_sprintf("write failed for register 0x%X, error %d", reg, err).c_str());
|
79
98
|
return false;
|
80
99
|
}
|
81
|
-
|
82
|
-
this->state_mask_ = output;
|
83
100
|
this->status_clear_warning();
|
84
|
-
|
85
101
|
return true;
|
86
102
|
}
|
87
103
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
104
|
+
uint8_t CH422GComponent::read_reg_(uint8_t reg) {
|
105
|
+
uint8_t value;
|
106
|
+
auto err = this->bus_->read(reg, &value, 1);
|
107
|
+
if (err != i2c::ERROR_OK) {
|
108
|
+
this->status_set_warning(str_sprintf("read failed for register 0x%X, error %d", reg, err).c_str());
|
109
|
+
return 0;
|
93
110
|
}
|
111
|
+
this->status_clear_warning();
|
112
|
+
return value;
|
113
|
+
}
|
94
114
|
|
95
|
-
|
96
|
-
if ((this->last_error_ = this->bus_->write(CH422G_REG_OUT, &write_mask, 1)) != esphome::i2c::ERROR_OK) {
|
97
|
-
this->status_set_warning(
|
98
|
-
str_sprintf("write_output_(): I2C I/O error: %d for write_mask: %d", (int) this->last_error_, (int) write_mask)
|
99
|
-
.c_str());
|
100
|
-
return false;
|
101
|
-
}
|
115
|
+
bool CH422GComponent::set_mode_(uint8_t mode) { return this->write_reg_(CH422G_REG_MODE, mode); }
|
102
116
|
|
103
|
-
|
104
|
-
this->
|
105
|
-
|
117
|
+
bool CH422GComponent::write_outputs_() {
|
118
|
+
return this->write_reg_(CH422G_REG_OUT, static_cast<uint8_t>(this->output_bits_)) &&
|
119
|
+
this->write_reg_(CH422G_REG_OUT_UPPER, static_cast<uint8_t>(this->output_bits_ >> 8));
|
106
120
|
}
|
107
121
|
|
108
122
|
float CH422GComponent::get_setup_priority() const { return setup_priority::IO; }
|
@@ -111,12 +125,15 @@ float CH422GComponent::get_setup_priority() const { return setup_priority::IO; }
|
|
111
125
|
// before other components call our digital_read() method.
|
112
126
|
float CH422GComponent::get_loop_priority() const { return 9.0f; } // Just after WIFI
|
113
127
|
|
114
|
-
void CH422GGPIOPin::setup() { pin_mode(flags_); }
|
115
128
|
void CH422GGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
|
116
|
-
bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_)
|
129
|
+
bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }
|
117
130
|
|
118
|
-
void CH422GGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value
|
131
|
+
void CH422GGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value ^ this->inverted_); }
|
119
132
|
std::string CH422GGPIOPin::dump_summary() const { return str_sprintf("EXIO%u via CH422G", pin_); }
|
133
|
+
void CH422GGPIOPin::set_flags(gpio::Flags flags) {
|
134
|
+
flags_ = flags;
|
135
|
+
this->parent_->pin_mode(this->pin_, flags);
|
136
|
+
}
|
120
137
|
|
121
138
|
} // namespace ch422g
|
122
139
|
} // namespace esphome
|
@@ -23,32 +23,30 @@ class CH422GComponent : public Component, public i2c::I2CDevice {
|
|
23
23
|
void pin_mode(uint8_t pin, gpio::Flags flags);
|
24
24
|
|
25
25
|
float get_setup_priority() const override;
|
26
|
-
|
27
26
|
float get_loop_priority() const override;
|
28
|
-
|
29
27
|
void dump_config() override;
|
30
28
|
|
31
|
-
void set_restore_value(bool restore_value) { this->restore_value_ = restore_value; }
|
32
|
-
|
33
29
|
protected:
|
30
|
+
bool write_reg_(uint8_t reg, uint8_t value);
|
31
|
+
uint8_t read_reg_(uint8_t reg);
|
32
|
+
bool set_mode_(uint8_t mode);
|
34
33
|
bool read_inputs_();
|
35
|
-
|
36
|
-
bool write_output_(uint8_t value);
|
34
|
+
bool write_outputs_();
|
37
35
|
|
38
36
|
/// The mask to write as output state - 1 means HIGH, 0 means LOW
|
39
|
-
|
37
|
+
uint16_t output_bits_{0x00};
|
40
38
|
/// Flags to check if read previously during this loop
|
41
|
-
uint8_t
|
42
|
-
///
|
43
|
-
|
44
|
-
///
|
45
|
-
|
39
|
+
uint8_t pin_read_flags_ = {0x00};
|
40
|
+
/// Copy of last read values
|
41
|
+
uint8_t input_bits_ = {0x00};
|
42
|
+
/// Copy of the mode value
|
43
|
+
uint8_t mode_value_{};
|
46
44
|
};
|
47
45
|
|
48
|
-
/// Helper class to expose a CH422G pin as
|
46
|
+
/// Helper class to expose a CH422G pin as a GPIO pin.
|
49
47
|
class CH422GGPIOPin : public GPIOPin {
|
50
48
|
public:
|
51
|
-
void setup() override;
|
49
|
+
void setup() override{};
|
52
50
|
void pin_mode(gpio::Flags flags) override;
|
53
51
|
bool digital_read() override;
|
54
52
|
void digital_write(bool value) override;
|
@@ -57,13 +55,13 @@ class CH422GGPIOPin : public GPIOPin {
|
|
57
55
|
void set_parent(CH422GComponent *parent) { parent_ = parent; }
|
58
56
|
void set_pin(uint8_t pin) { pin_ = pin; }
|
59
57
|
void set_inverted(bool inverted) { inverted_ = inverted; }
|
60
|
-
void set_flags(gpio::Flags flags)
|
58
|
+
void set_flags(gpio::Flags flags);
|
61
59
|
|
62
60
|
protected:
|
63
|
-
CH422GComponent *parent_;
|
64
|
-
uint8_t pin_;
|
65
|
-
bool inverted_;
|
66
|
-
gpio::Flags flags_;
|
61
|
+
CH422GComponent *parent_{};
|
62
|
+
uint8_t pin_{};
|
63
|
+
bool inverted_{};
|
64
|
+
gpio::Flags flags_{};
|
67
65
|
};
|
68
66
|
|
69
67
|
} // namespace ch422g
|
@@ -43,7 +43,7 @@ from esphome.const import (
|
|
43
43
|
CONF_TEMPERATURE_STEP,
|
44
44
|
CONF_TRIGGER_ID,
|
45
45
|
CONF_VISUAL,
|
46
|
-
|
46
|
+
CONF_WEB_SERVER,
|
47
47
|
)
|
48
48
|
from esphome.core import CORE, coroutine_with_priority
|
49
49
|
from esphome.cpp_helpers import setup_entity
|
@@ -408,9 +408,8 @@ async def setup_climate_core_(var, config):
|
|
408
408
|
trigger, [(ClimateCall.operator("ref"), "x")], conf
|
409
409
|
)
|
410
410
|
|
411
|
-
if
|
412
|
-
|
413
|
-
web_server.add_entity_to_sorting_list(web_server_, var, config)
|
411
|
+
if web_server_config := config.get(CONF_WEB_SERVER):
|
412
|
+
await web_server.add_entity_config(var, web_server_config)
|
414
413
|
|
415
414
|
|
416
415
|
async def register_climate(var, config):
|
@@ -17,7 +17,7 @@ from esphome.const import (
|
|
17
17
|
CONF_TILT_COMMAND_TOPIC,
|
18
18
|
CONF_TILT_STATE_TOPIC,
|
19
19
|
CONF_TRIGGER_ID,
|
20
|
-
|
20
|
+
CONF_WEB_SERVER,
|
21
21
|
DEVICE_CLASS_AWNING,
|
22
22
|
DEVICE_CLASS_BLIND,
|
23
23
|
DEVICE_CLASS_CURTAIN,
|
@@ -137,10 +137,6 @@ async def setup_cover_core_(var, config):
|
|
137
137
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
138
138
|
await automation.build_automation(trigger, [], conf)
|
139
139
|
|
140
|
-
if (webserver_id := config.get(CONF_WEB_SERVER_ID)) is not None:
|
141
|
-
web_server_ = await cg.get_variable(webserver_id)
|
142
|
-
web_server.add_entity_to_sorting_list(web_server_, var, config)
|
143
|
-
|
144
140
|
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
|
145
141
|
mqtt_ = cg.new_Pvariable(mqtt_id, var)
|
146
142
|
await mqtt.register_mqtt_component(mqtt_, config)
|
@@ -156,6 +152,9 @@ async def setup_cover_core_(var, config):
|
|
156
152
|
if (tilt_command_topic := config.get(CONF_TILT_COMMAND_TOPIC)) is not None:
|
157
153
|
cg.add(mqtt_.set_custom_tilt_command_topic(tilt_command_topic))
|
158
154
|
|
155
|
+
if web_server_config := config.get(CONF_WEB_SERVER):
|
156
|
+
await web_server.add_entity_config(var, web_server_config)
|
157
|
+
|
159
158
|
|
160
159
|
async def register_cover(var, config):
|
161
160
|
if not CORE.has_id(config[CONF_ID]):
|
@@ -147,6 +147,7 @@ void CSE7766Component::parse_data_() {
|
|
147
147
|
float power = 0.0f;
|
148
148
|
if (power_cycle_exceeds_range) {
|
149
149
|
// Datasheet: power cycle exceeding range means active power is 0
|
150
|
+
have_power = true;
|
150
151
|
if (this->power_sensor_ != nullptr) {
|
151
152
|
this->power_sensor_->publish_state(0.0f);
|
152
153
|
}
|
@@ -178,6 +179,15 @@ void CSE7766Component::parse_data_() {
|
|
178
179
|
if (this->apparent_power_sensor_ != nullptr) {
|
179
180
|
this->apparent_power_sensor_->publish_state(apparent_power);
|
180
181
|
}
|
182
|
+
if (have_power && this->reactive_power_sensor_ != nullptr) {
|
183
|
+
const float reactive_power = apparent_power - power;
|
184
|
+
if (reactive_power < 0.0f) {
|
185
|
+
ESP_LOGD(TAG, "Impossible reactive power: %.4f is negative", reactive_power);
|
186
|
+
this->reactive_power_sensor_->publish_state(0.0f);
|
187
|
+
} else {
|
188
|
+
this->reactive_power_sensor_->publish_state(reactive_power);
|
189
|
+
}
|
190
|
+
}
|
181
191
|
if (this->power_factor_sensor_ != nullptr && (have_power || power_cycle_exceeds_range)) {
|
182
192
|
float pf = NAN;
|
183
193
|
if (apparent_power > 0) {
|
@@ -232,6 +242,7 @@ void CSE7766Component::dump_config() {
|
|
232
242
|
LOG_SENSOR(" ", "Power", this->power_sensor_);
|
233
243
|
LOG_SENSOR(" ", "Energy", this->energy_sensor_);
|
234
244
|
LOG_SENSOR(" ", "Apparent Power", this->apparent_power_sensor_);
|
245
|
+
LOG_SENSOR(" ", "Reactive Power", this->reactive_power_sensor_);
|
235
246
|
LOG_SENSOR(" ", "Power Factor", this->power_factor_sensor_);
|
236
247
|
this->check_uart_settings(4800);
|
237
248
|
}
|
@@ -16,6 +16,9 @@ class CSE7766Component : public Component, public uart::UARTDevice {
|
|
16
16
|
void set_apparent_power_sensor(sensor::Sensor *apparent_power_sensor) {
|
17
17
|
apparent_power_sensor_ = apparent_power_sensor;
|
18
18
|
}
|
19
|
+
void set_reactive_power_sensor(sensor::Sensor *reactive_power_sensor) {
|
20
|
+
reactive_power_sensor_ = reactive_power_sensor;
|
21
|
+
}
|
19
22
|
void set_power_factor_sensor(sensor::Sensor *power_factor_sensor) { power_factor_sensor_ = power_factor_sensor; }
|
20
23
|
|
21
24
|
void loop() override;
|
@@ -35,6 +38,7 @@ class CSE7766Component : public Component, public uart::UARTDevice {
|
|
35
38
|
sensor::Sensor *power_sensor_{nullptr};
|
36
39
|
sensor::Sensor *energy_sensor_{nullptr};
|
37
40
|
sensor::Sensor *apparent_power_sensor_{nullptr};
|
41
|
+
sensor::Sensor *reactive_power_sensor_{nullptr};
|
38
42
|
sensor::Sensor *power_factor_sensor_{nullptr};
|
39
43
|
uint32_t cf_pulses_total_{0};
|
40
44
|
uint16_t cf_pulses_last_{0};
|