esphome 2024.12.3__py3-none-any.whl → 2025.2.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/__main__.py +16 -3
- esphome/components/adc/__init__.py +17 -11
- esphome/components/adc/adc_sensor.h +17 -0
- esphome/components/adc/adc_sensor_common.cpp +55 -0
- esphome/components/adc/adc_sensor_esp32.cpp +8 -5
- esphome/components/adc/adc_sensor_esp8266.cpp +10 -6
- esphome/components/adc/adc_sensor_libretiny.cpp +11 -6
- esphome/components/adc/adc_sensor_rp2040.cpp +13 -10
- esphome/components/adc/sensor.py +9 -3
- esphome/components/ads1115/ads1115.cpp +56 -7
- esphome/components/ads1115/ads1115.h +13 -1
- esphome/components/ads1115/sensor/__init__.py +16 -0
- esphome/components/ads1115/sensor/ads1115_sensor.cpp +2 -1
- esphome/components/ads1115/sensor/ads1115_sensor.h +2 -0
- esphome/components/animation/__init__.py +23 -261
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/animation/animation.h +2 -1
- esphome/components/api/api_pb2.cpp +14 -0
- esphome/components/api/api_pb2.h +1 -0
- esphome/components/audio/__init__.py +112 -0
- esphome/components/audio/audio.cpp +67 -0
- esphome/components/audio/audio.h +125 -7
- esphome/components/audio/audio_decoder.cpp +361 -0
- esphome/components/audio/audio_decoder.h +135 -0
- esphome/components/audio/audio_reader.cpp +308 -0
- esphome/components/audio/audio_reader.h +85 -0
- esphome/components/audio/audio_resampler.cpp +159 -0
- esphome/components/audio/audio_resampler.h +101 -0
- esphome/components/audio/audio_transfer_buffer.cpp +165 -0
- esphome/components/audio/audio_transfer_buffer.h +139 -0
- esphome/components/audio_adc/__init__.py +41 -0
- esphome/components/audio_adc/audio_adc.h +17 -0
- esphome/components/audio_adc/automation.h +23 -0
- esphome/components/bk72xx/__init__.py +1 -0
- esphome/components/ble_client/ble_client.cpp +1 -2
- esphome/components/ble_client/sensor/__init__.py +1 -1
- esphome/components/ble_client/text_sensor/__init__.py +1 -1
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -0
- esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -0
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
- esphome/components/ch422g/ch422g.h +2 -0
- esphome/components/climate/__init__.py +1 -1
- esphome/components/climate_ir/climate_ir.cpp +2 -1
- esphome/components/coolix/coolix.cpp +2 -1
- esphome/components/custom/__init__.py +0 -3
- esphome/components/custom/binary_sensor/__init__.py +2 -28
- esphome/components/custom/climate/__init__.py +2 -27
- esphome/components/custom/cover/__init__.py +2 -27
- esphome/components/custom/light/__init__.py +2 -27
- esphome/components/custom/output/__init__.py +2 -58
- esphome/components/custom/sensor/__init__.py +2 -24
- esphome/components/custom/switch/__init__.py +2 -24
- esphome/components/custom/text_sensor/__init__.py +2 -29
- esphome/components/custom_component/__init__.py +3 -27
- esphome/components/daly_bms/daly_bms.cpp +6 -0
- esphome/components/daly_bms/daly_bms.h +2 -0
- esphome/components/daly_bms/sensor.py +6 -0
- esphome/components/debug/debug_component.cpp +4 -0
- esphome/components/debug/debug_component.h +14 -0
- esphome/components/debug/debug_esp32.cpp +154 -74
- esphome/components/dfplayer/dfplayer.cpp +15 -2
- esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp +2 -1
- esphome/components/dht/dht.cpp +2 -1
- esphome/components/display/__init__.py +18 -5
- esphome/components/display/display.cpp +2 -1
- esphome/components/display/rect.cpp +2 -1
- esphome/components/es7210/__init__.py +0 -0
- esphome/components/es7210/audio_adc.py +51 -0
- esphome/components/es7210/es7210.cpp +228 -0
- esphome/components/es7210/es7210.h +62 -0
- esphome/components/es7210/es7210_const.h +129 -0
- esphome/components/es7243e/__init__.py +0 -0
- esphome/components/es7243e/audio_adc.py +34 -0
- esphome/components/es7243e/es7243e.cpp +125 -0
- esphome/components/es7243e/es7243e.h +37 -0
- esphome/components/es7243e/es7243e_const.h +54 -0
- esphome/components/es8156/__init__.py +0 -0
- esphome/components/es8156/audio_dac.py +27 -0
- esphome/components/es8156/es8156.cpp +87 -0
- esphome/components/es8156/es8156.h +51 -0
- esphome/components/es8156/es8156_const.h +68 -0
- esphome/components/es8311/audio_dac.py +1 -2
- esphome/components/esp32/__init__.py +1 -0
- esphome/components/esp32/core.cpp +5 -1
- esphome/components/esp32/gpio.h +2 -0
- esphome/components/esp32_ble/__init__.py +39 -0
- esphome/components/esp32_ble/queue.h +4 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +46 -0
- esphome/components/esp32_ble_client/ble_client_base.h +2 -0
- esphome/components/esp32_ble_server/__init__.py +582 -12
- esphome/components/esp32_ble_server/ble_characteristic.cpp +48 -60
- esphome/components/esp32_ble_server/ble_characteristic.h +24 -17
- esphome/components/esp32_ble_server/ble_descriptor.cpp +21 -9
- esphome/components/esp32_ble_server/ble_descriptor.h +17 -6
- esphome/components/esp32_ble_server/ble_server.cpp +62 -67
- esphome/components/esp32_ble_server/ble_server.h +28 -32
- esphome/components/esp32_ble_server/ble_server_automations.cpp +77 -0
- esphome/components/esp32_ble_server/ble_server_automations.h +115 -0
- esphome/components/esp32_ble_server/ble_service.cpp +17 -15
- esphome/components/esp32_ble_server/ble_service.h +10 -14
- esphome/components/esp32_ble_tracker/__init__.py +6 -39
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +33 -10
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +8 -4
- esphome/components/esp32_improv/__init__.py +2 -8
- esphome/components/esp32_improv/esp32_improv_component.cpp +21 -20
- esphome/components/esp32_improv/esp32_improv_component.h +3 -4
- esphome/components/esp32_rmt/__init__.py +28 -3
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +73 -6
- esphome/components/esp32_rmt_led_strip/led_strip.h +21 -3
- esphome/components/esp32_rmt_led_strip/light.py +72 -7
- esphome/components/esp32_touch/esp32_touch.cpp +5 -0
- esphome/components/esp8266/__init__.py +1 -0
- esphome/components/esp8266/gpio.h +1 -0
- esphome/components/ethernet/__init__.py +10 -10
- esphome/components/event/event.cpp +4 -2
- esphome/components/event/event.h +2 -0
- esphome/components/event_emitter/__init__.py +5 -0
- esphome/components/event_emitter/event_emitter.cpp +14 -0
- esphome/components/event_emitter/event_emitter.h +63 -0
- esphome/components/gcja5/gcja5.cpp +2 -1
- esphome/components/haier/haier_base.cpp +2 -1
- esphome/components/haier/hon_climate.cpp +2 -1
- esphome/components/heatpumpir/heatpumpir.cpp +2 -1
- esphome/components/host/__init__.py +1 -0
- esphome/components/host/gpio.h +1 -0
- esphome/components/http_request/http_request.h +2 -2
- esphome/components/http_request/http_request_arduino.cpp +1 -1
- esphome/components/http_request/http_request_idf.cpp +1 -1
- esphome/components/i2c/i2c_bus_esp_idf.cpp +4 -0
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +7 -5
- esphome/components/i2s_audio/speaker/__init__.py +53 -6
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +92 -46
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -0
- esphome/components/ili9xxx/display.py +29 -11
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -5
- esphome/components/ili9xxx/ili9xxx_display.h +2 -1
- esphome/components/image/__init__.py +443 -255
- esphome/components/image/image.cpp +115 -61
- esphome/components/image/image.h +15 -24
- esphome/components/json/json_util.cpp +8 -34
- esphome/components/libretiny/__init__.py +1 -0
- esphome/components/libretiny/gpio_arduino.h +1 -0
- esphome/components/light/light_color_values.h +1 -1
- esphome/components/logger/__init__.py +43 -7
- esphome/components/logger/logger.cpp +16 -11
- esphome/components/logger/logger.h +11 -7
- esphome/components/logger/select/__init__.py +29 -0
- esphome/components/logger/select/logger_level_select.cpp +27 -0
- esphome/components/logger/select/logger_level_select.h +15 -0
- esphome/components/lvgl/__init__.py +96 -73
- esphome/components/lvgl/automation.py +39 -7
- esphome/components/lvgl/defines.py +8 -2
- esphome/components/lvgl/lvgl_esphome.cpp +8 -15
- esphome/components/lvgl/lvgl_esphome.h +20 -5
- esphome/components/lvgl/schemas.py +25 -14
- esphome/components/lvgl/trigger.py +27 -3
- esphome/components/lvgl/widgets/dropdown.py +1 -1
- esphome/components/lvgl/widgets/keyboard.py +8 -1
- esphome/components/lvgl/widgets/meter.py +2 -1
- esphome/components/lvgl/widgets/msgbox.py +1 -1
- esphome/components/lvgl/widgets/obj.py +1 -12
- esphome/components/lvgl/widgets/page.py +37 -2
- esphome/components/lvgl/widgets/tabview.py +1 -1
- esphome/components/max6956/max6956.h +2 -0
- esphome/components/mcp23016/mcp23016.h +2 -0
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +2 -0
- esphome/components/mdns/__init__.py +1 -1
- esphome/components/media_player/__init__.py +37 -8
- esphome/components/media_player/automation.h +11 -2
- esphome/components/media_player/media_player.cpp +8 -0
- esphome/components/media_player/media_player.h +8 -4
- esphome/components/micronova/switch/micronova_switch.cpp +4 -2
- esphome/components/midea/ac_automations.h +3 -1
- esphome/components/midea/air_conditioner.cpp +7 -5
- esphome/components/midea/air_conditioner.h +1 -1
- esphome/components/midea/climate.py +4 -2
- esphome/components/midea/ir_transmitter.h +36 -5
- esphome/components/mixer/__init__.py +0 -0
- esphome/components/mixer/speaker/__init__.py +172 -0
- esphome/components/mixer/speaker/automation.h +19 -0
- esphome/components/mixer/speaker/mixer_speaker.cpp +624 -0
- esphome/components/mixer/speaker/mixer_speaker.h +207 -0
- esphome/components/mpr121/mpr121.h +2 -0
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +7 -1
- esphome/components/mqtt/mqtt_client.h +1 -1
- esphome/components/mqtt/mqtt_climate.cpp +2 -2
- esphome/components/network/ip_address.h +2 -0
- esphome/components/nextion/automation.h +17 -0
- esphome/components/nextion/display.py +42 -17
- esphome/components/nextion/nextion.cpp +4 -10
- esphome/components/nextion/nextion.h +89 -82
- esphome/components/nextion/nextion_commands.cpp +10 -10
- esphome/components/ntc/sensor.py +2 -4
- esphome/components/online_image/__init__.py +98 -46
- esphome/components/online_image/bmp_image.cpp +101 -0
- esphome/components/online_image/bmp_image.h +40 -0
- esphome/components/online_image/image_decoder.cpp +28 -2
- esphome/components/online_image/image_decoder.h +24 -15
- esphome/components/online_image/jpeg_image.cpp +90 -0
- esphome/components/online_image/jpeg_image.h +34 -0
- esphome/components/online_image/online_image.cpp +112 -53
- esphome/components/online_image/online_image.h +24 -7
- esphome/components/online_image/png_image.cpp +7 -3
- esphome/components/online_image/png_image.h +2 -1
- esphome/components/opentherm/__init__.py +73 -7
- esphome/components/opentherm/automation.h +25 -0
- esphome/components/opentherm/const.py +1 -0
- esphome/components/opentherm/generate.py +39 -6
- esphome/components/opentherm/hub.cpp +117 -79
- esphome/components/opentherm/hub.h +31 -15
- esphome/components/opentherm/opentherm.cpp +47 -23
- esphome/components/opentherm/opentherm.h +27 -6
- esphome/components/opentherm/opentherm_macros.h +11 -0
- esphome/components/opentherm/schema.py +78 -1
- esphome/components/opentherm/validate.py +7 -2
- esphome/components/pca6416a/pca6416a.h +2 -0
- esphome/components/pca9554/pca9554.h +2 -0
- esphome/components/pcf8574/pcf8574.h +2 -0
- esphome/components/preferences/__init__.py +2 -4
- esphome/components/preferences/syncer.h +10 -3
- esphome/components/prometheus/prometheus_handler.cpp +313 -0
- esphome/components/prometheus/prometheus_handler.h +48 -7
- esphome/components/psram/psram.cpp +8 -1
- esphome/components/pulse_counter/pulse_counter_sensor.cpp +14 -9
- esphome/components/pulse_counter/pulse_counter_sensor.h +4 -4
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +2 -0
- esphome/components/qspi_dbi/__init__.py +3 -0
- esphome/components/qspi_dbi/display.py +74 -47
- esphome/components/qspi_dbi/models.py +245 -2
- esphome/components/qspi_dbi/qspi_dbi.cpp +9 -16
- esphome/components/qspi_dbi/qspi_dbi.h +2 -2
- esphome/components/remote_base/__init__.py +77 -25
- esphome/components/remote_base/remote_base.cpp +1 -1
- esphome/components/remote_base/remote_base.h +20 -2
- esphome/components/remote_base/toto_protocol.cpp +100 -0
- esphome/components/remote_base/toto_protocol.h +45 -0
- esphome/components/remote_receiver/__init__.py +55 -10
- esphome/components/remote_receiver/remote_receiver.h +36 -3
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +145 -6
- esphome/components/remote_transmitter/__init__.py +62 -4
- esphome/components/remote_transmitter/remote_transmitter.h +21 -2
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +140 -4
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +3 -3
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +3 -3
- esphome/components/resampler/__init__.py +0 -0
- esphome/components/resampler/speaker/__init__.py +103 -0
- esphome/components/resampler/speaker/resampler_speaker.cpp +318 -0
- esphome/components/resampler/speaker/resampler_speaker.h +107 -0
- esphome/components/resistance/resistance_sensor.h +2 -3
- esphome/components/resistance/sensor.py +2 -9
- esphome/components/rotary_encoder/rotary_encoder.cpp +8 -4
- esphome/components/rp2040/__init__.py +1 -0
- esphome/components/rp2040/gpio.h +1 -0
- esphome/components/rtl87xx/__init__.py +2 -0
- esphome/components/sdl/binary_sensor.py +270 -0
- esphome/components/sdl/sdl_esphome.cpp +16 -0
- esphome/components/sdl/sdl_esphome.h +9 -0
- esphome/components/seeed_mr60bha2/binary_sensor.py +25 -0
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +26 -2
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +9 -20
- esphome/components/seeed_mr60bha2/sensor.py +9 -1
- esphome/components/sn74hc165/sn74hc165.h +3 -0
- esphome/components/sn74hc595/sn74hc595.h +3 -0
- esphome/components/speaker/__init__.py +5 -4
- esphome/components/speaker/media_player/__init__.py +458 -0
- esphome/components/speaker/media_player/audio_pipeline.cpp +568 -0
- esphome/components/speaker/media_player/audio_pipeline.h +159 -0
- esphome/components/speaker/media_player/automation.h +26 -0
- esphome/components/speaker/media_player/speaker_media_player.cpp +577 -0
- esphome/components/speaker/media_player/speaker_media_player.h +160 -0
- esphome/components/speaker/speaker.h +20 -0
- esphome/components/spi/__init__.py +1 -5
- esphome/components/spi/spi.cpp +7 -1
- esphome/components/spi/spi.h +21 -2
- esphome/components/spi_led_strip/light.py +3 -5
- esphome/components/spi_led_strip/spi_led_strip.cpp +67 -0
- esphome/components/spi_led_strip/spi_led_strip.h +8 -60
- esphome/components/sprinkler/sprinkler.cpp +3 -1
- esphome/components/sx1509/sx1509_gpio_pin.h +2 -0
- esphome/components/tca9555/tca9555.h +2 -0
- esphome/components/toshiba/toshiba.cpp +2 -1
- esphome/components/tuya/light/tuya_light.cpp +4 -2
- esphome/components/uart/uart_component_esp32_arduino.cpp +2 -2
- esphome/components/uart/uart_component_esp_idf.cpp +2 -2
- esphome/components/udp/__init__.py +8 -2
- esphome/components/udp/udp_component.cpp +25 -56
- esphome/components/udp/udp_component.h +3 -0
- esphome/components/uponor_smatrix/sensor/__init__.py +14 -4
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +5 -0
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.h +1 -0
- esphome/components/uptime/text_sensor/__init__.py +19 -0
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +63 -0
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +25 -0
- esphome/components/voice_assistant/voice_assistant.cpp +24 -14
- esphome/components/voice_assistant/voice_assistant.h +8 -0
- esphome/components/waveshare_epaper/display.py +22 -1
- esphome/components/waveshare_epaper/waveshare_213v3.cpp +9 -3
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +1155 -44
- esphome/components/waveshare_epaper/waveshare_epaper.h +208 -7
- esphome/components/web_server/web_server.cpp +28 -6
- esphome/components/weikai/weikai.h +2 -0
- esphome/components/wifi/__init__.py +6 -6
- esphome/components/wifi/wifi_component.cpp +1 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -1
- esphome/components/wireguard/__init__.py +2 -2
- esphome/components/xl9535/xl9535.h +2 -0
- esphome/components/xxtea/__init__.py +3 -0
- esphome/components/xxtea/xxtea.cpp +46 -0
- esphome/components/xxtea/xxtea.h +26 -0
- esphome/components/yashima/yashima.cpp +2 -1
- esphome/config.py +9 -5
- esphome/config_validation.py +55 -17
- esphome/const.py +7 -10
- esphome/core/__init__.py +6 -13
- esphome/core/base_automation.h +1 -0
- esphome/core/config.py +57 -72
- esphome/core/defines.h +9 -1
- esphome/core/gpio.h +7 -0
- esphome/core/helpers.cpp +19 -15
- esphome/core/helpers.h +57 -8
- esphome/core/log.h +9 -7
- esphome/cpp_generator.py +2 -2
- esphome/espota2.py +3 -2
- esphome/loader.py +12 -4
- esphome/log.py +5 -7
- esphome/yaml_util.py +2 -2
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/METADATA +12 -7
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/RECORD +338 -289
- esphome/components/custom/binary_sensor/custom_binary_sensor.cpp +0 -16
- esphome/components/custom/binary_sensor/custom_binary_sensor.h +0 -26
- esphome/components/custom/climate/custom_climate.h +0 -22
- esphome/components/custom/cover/custom_cover.h +0 -21
- esphome/components/custom/light/custom_light_output.h +0 -24
- esphome/components/custom/output/custom_output.h +0 -37
- esphome/components/custom/sensor/custom_sensor.cpp +0 -16
- esphome/components/custom/sensor/custom_sensor.h +0 -24
- esphome/components/custom/switch/custom_switch.cpp +0 -16
- esphome/components/custom/switch/custom_switch.h +0 -24
- esphome/components/custom/text_sensor/custom_text_sensor.cpp +0 -16
- esphome/components/custom/text_sensor/custom_text_sensor.h +0 -26
- esphome/components/custom_component/custom_component.h +0 -28
- esphome/components/esp32_ble_server/ble_2901.cpp +0 -18
- esphome/components/esp32_ble_server/ble_2901.h +0 -19
- esphome/components/resistance_sampler/__init__.py +0 -6
- esphome/components/resistance_sampler/resistance_sampler.h +0 -10
- esphome/components/uptime/{sensor.py → sensor/__init__.py} +3 -3
- /esphome/components/uptime/{uptime_seconds_sensor.cpp → sensor/uptime_seconds_sensor.cpp} +0 -0
- /esphome/components/uptime/{uptime_seconds_sensor.h → sensor/uptime_seconds_sensor.h} +0 -0
- /esphome/components/uptime/{uptime_timestamp_sensor.cpp → sensor/uptime_timestamp_sensor.cpp} +0 -0
- /esphome/components/uptime/{uptime_timestamp_sensor.h → sensor/uptime_timestamp_sensor.h} +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/LICENSE +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/WHEEL +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/top_level.txt +0 -0
@@ -63,7 +63,7 @@ void write_f88(const float value, OpenthermData &data) { data.f88(value); }
|
|
63
63
|
OpenthermData OpenthermHub::build_request_(MessageId request_id) const {
|
64
64
|
OpenthermData data;
|
65
65
|
data.type = 0;
|
66
|
-
data.id =
|
66
|
+
data.id = request_id;
|
67
67
|
data.valueHB = 0;
|
68
68
|
data.valueLB = 0;
|
69
69
|
|
@@ -82,28 +82,13 @@ OpenthermData OpenthermHub::build_request_(MessageId request_id) const {
|
|
82
82
|
// NOLINTEND
|
83
83
|
|
84
84
|
data.type = MessageType::READ_DATA;
|
85
|
-
data.id = MessageId::STATUS;
|
86
85
|
data.valueHB = ch_enabled | (dhw_enabled << 1) | (cooling_enabled << 2) | (otc_enabled << 3) | (ch2_enabled << 4) |
|
87
86
|
(summer_mode_is_active << 5) | (dhw_blocked << 6);
|
88
87
|
|
89
88
|
return data;
|
90
89
|
}
|
91
90
|
|
92
|
-
//
|
93
|
-
if (request_id == MessageId::OT_VERSION_CONTROLLER) {
|
94
|
-
data.type = MessageType::WRITE_DATA;
|
95
|
-
data.id = MessageId::OT_VERSION_CONTROLLER;
|
96
|
-
data.f88(this->opentherm_version_);
|
97
|
-
|
98
|
-
return data;
|
99
|
-
}
|
100
|
-
|
101
|
-
// Disable incomplete switch statement warnings, because the cases in each
|
102
|
-
// switch are generated based on the configured sensors and inputs.
|
103
|
-
#pragma GCC diagnostic push
|
104
|
-
#pragma GCC diagnostic ignored "-Wswitch"
|
105
|
-
|
106
|
-
// Next, we start with the write requests from switches and other inputs,
|
91
|
+
// Next, we start with write requests from switches and other inputs,
|
107
92
|
// because we would want to write that data if it is available, rather than
|
108
93
|
// request a read for that type (in the case that both read and write are
|
109
94
|
// supported).
|
@@ -116,14 +101,23 @@ OpenthermData OpenthermHub::build_request_(MessageId request_id) const {
|
|
116
101
|
OPENTHERM_MESSAGE_WRITE_POSTSCRIPT, )
|
117
102
|
OPENTHERM_INPUT_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_WRITE_MESSAGE, OPENTHERM_MESSAGE_WRITE_ENTITY, ,
|
118
103
|
OPENTHERM_MESSAGE_WRITE_POSTSCRIPT, )
|
104
|
+
OPENTHERM_SETTING_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_WRITE_MESSAGE, OPENTHERM_MESSAGE_WRITE_SETTING, ,
|
105
|
+
OPENTHERM_MESSAGE_WRITE_POSTSCRIPT, )
|
106
|
+
default:
|
107
|
+
break;
|
119
108
|
}
|
120
109
|
|
121
110
|
// Finally, handle the simple read requests, which only change with the message id.
|
122
|
-
switch (request_id) {
|
111
|
+
switch (request_id) {
|
112
|
+
OPENTHERM_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_READ_MESSAGE, OPENTHERM_IGNORE, , , )
|
113
|
+
default:
|
114
|
+
break;
|
115
|
+
}
|
123
116
|
switch (request_id) {
|
124
117
|
OPENTHERM_BINARY_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_READ_MESSAGE, OPENTHERM_IGNORE, , , )
|
118
|
+
default:
|
119
|
+
break;
|
125
120
|
}
|
126
|
-
#pragma GCC diagnostic pop
|
127
121
|
|
128
122
|
// And if we get here, a message was requested which somehow wasn't handled.
|
129
123
|
// This shouldn't happen due to the way the defines are configured, so we
|
@@ -163,18 +157,36 @@ void OpenthermHub::setup() {
|
|
163
157
|
// communicate at least once every second. Sending the status request is
|
164
158
|
// good practice anyway.
|
165
159
|
this->add_repeating_message(MessageId::STATUS);
|
160
|
+
this->write_initial_messages_(this->messages_);
|
161
|
+
this->message_iterator_ = this->messages_.begin();
|
162
|
+
}
|
166
163
|
|
167
|
-
|
168
|
-
this->initial_messages_.insert(this->initial_messages_.begin(), MessageId::STATUS);
|
169
|
-
|
170
|
-
if (this->opentherm_version_ > 0.0f) {
|
171
|
-
this->initial_messages_.insert(this->initial_messages_.begin(), MessageId::OT_VERSION_CONTROLLER);
|
172
|
-
}
|
164
|
+
void OpenthermHub::on_shutdown() { this->opentherm_->stop(); }
|
173
165
|
|
174
|
-
|
166
|
+
// Disabling clang-tidy for this particular line since it keeps removing the trailing underscore (bug?)
|
167
|
+
void OpenthermHub::write_initial_messages_(std::vector<MessageId> &target) { // NOLINT
|
168
|
+
std::vector<std::pair<MessageId, uint8_t>> sorted;
|
169
|
+
std::copy_if(this->configured_messages_.begin(), this->configured_messages_.end(), std::back_inserter(sorted),
|
170
|
+
[](const std::pair<MessageId, uint8_t> &pair) { return pair.second < REPEATING_MESSAGE_ORDER; });
|
171
|
+
std::sort(sorted.begin(), sorted.end(),
|
172
|
+
[](const std::pair<MessageId, uint8_t> &a, const std::pair<MessageId, uint8_t> &b) {
|
173
|
+
return a.second < b.second;
|
174
|
+
});
|
175
|
+
|
176
|
+
target.clear();
|
177
|
+
std::transform(sorted.begin(), sorted.end(), std::back_inserter(target),
|
178
|
+
[](const std::pair<MessageId, uint8_t> &pair) { return pair.first; });
|
175
179
|
}
|
176
180
|
|
177
|
-
|
181
|
+
// Disabling clang-tidy for this particular line since it keeps removing the trailing underscore (bug?)
|
182
|
+
void OpenthermHub::write_repeating_messages_(std::vector<MessageId> &target) { // NOLINT
|
183
|
+
target.clear();
|
184
|
+
for (auto const &pair : this->configured_messages_) {
|
185
|
+
if (pair.second == REPEATING_MESSAGE_ORDER) {
|
186
|
+
target.push_back(pair.first);
|
187
|
+
}
|
188
|
+
}
|
189
|
+
}
|
178
190
|
|
179
191
|
void OpenthermHub::loop() {
|
180
192
|
if (this->sync_mode_) {
|
@@ -184,29 +196,18 @@ void OpenthermHub::loop() {
|
|
184
196
|
|
185
197
|
auto cur_time = millis();
|
186
198
|
auto const cur_mode = this->opentherm_->get_mode();
|
199
|
+
|
200
|
+
if (this->handle_error_(cur_mode)) {
|
201
|
+
return;
|
202
|
+
}
|
203
|
+
|
187
204
|
switch (cur_mode) {
|
188
205
|
case OperationMode::WRITE:
|
189
206
|
case OperationMode::READ:
|
190
207
|
case OperationMode::LISTEN:
|
191
|
-
if (!this->check_timings_(cur_time)) {
|
192
|
-
break;
|
193
|
-
}
|
194
|
-
this->last_mode_ = cur_mode;
|
195
|
-
break;
|
196
|
-
case OperationMode::ERROR_PROTOCOL:
|
197
|
-
if (this->last_mode_ == OperationMode::WRITE) {
|
198
|
-
this->handle_protocol_write_error_();
|
199
|
-
} else if (this->last_mode_ == OperationMode::READ) {
|
200
|
-
this->handle_protocol_read_error_();
|
201
|
-
}
|
202
|
-
|
203
|
-
this->stop_opentherm_();
|
204
|
-
break;
|
205
|
-
case OperationMode::ERROR_TIMEOUT:
|
206
|
-
this->handle_timeout_error_();
|
207
|
-
this->stop_opentherm_();
|
208
208
|
break;
|
209
209
|
case OperationMode::IDLE:
|
210
|
+
this->check_timings_(cur_time);
|
210
211
|
if (this->should_skip_loop_(cur_time)) {
|
211
212
|
break;
|
212
213
|
}
|
@@ -219,6 +220,28 @@ void OpenthermHub::loop() {
|
|
219
220
|
case OperationMode::RECEIVED:
|
220
221
|
this->read_response_();
|
221
222
|
break;
|
223
|
+
default:
|
224
|
+
break;
|
225
|
+
}
|
226
|
+
this->last_mode_ = cur_mode;
|
227
|
+
}
|
228
|
+
|
229
|
+
bool OpenthermHub::handle_error_(OperationMode mode) {
|
230
|
+
switch (mode) {
|
231
|
+
case OperationMode::ERROR_PROTOCOL:
|
232
|
+
// Protocol error can happen only while reading boiler response.
|
233
|
+
this->handle_protocol_error_();
|
234
|
+
return true;
|
235
|
+
case OperationMode::ERROR_TIMEOUT:
|
236
|
+
// Timeout error might happen while we wait for device to respond.
|
237
|
+
this->handle_timeout_error_();
|
238
|
+
return true;
|
239
|
+
case OperationMode::ERROR_TIMER:
|
240
|
+
// Timer error can happen only on ESP32.
|
241
|
+
this->handle_timer_error_();
|
242
|
+
return true;
|
243
|
+
default:
|
244
|
+
return false;
|
222
245
|
}
|
223
246
|
}
|
224
247
|
|
@@ -237,16 +260,20 @@ void OpenthermHub::sync_loop_() {
|
|
237
260
|
}
|
238
261
|
|
239
262
|
this->start_conversation_();
|
263
|
+
// There may be a timer error at this point
|
264
|
+
if (this->handle_error_(this->opentherm_->get_mode())) {
|
265
|
+
return;
|
266
|
+
}
|
240
267
|
|
268
|
+
// Spin while message is being sent to device
|
241
269
|
if (!this->spin_wait_(1150, [&] { return this->opentherm_->is_active(); })) {
|
242
270
|
ESP_LOGE(TAG, "Hub timeout triggered during send");
|
243
271
|
this->stop_opentherm_();
|
244
272
|
return;
|
245
273
|
}
|
246
274
|
|
247
|
-
|
248
|
-
|
249
|
-
this->stop_opentherm_();
|
275
|
+
// Check for errors and ensure we are in the right state (message sent successfully)
|
276
|
+
if (this->handle_error_(this->opentherm_->get_mode())) {
|
250
277
|
return;
|
251
278
|
} else if (!this->opentherm_->is_sent()) {
|
252
279
|
ESP_LOGW(TAG, "Unexpected state after sending request: %s",
|
@@ -257,19 +284,20 @@ void OpenthermHub::sync_loop_() {
|
|
257
284
|
|
258
285
|
// Listen for the response
|
259
286
|
this->opentherm_->listen();
|
287
|
+
// There may be a timer error at this point
|
288
|
+
if (this->handle_error_(this->opentherm_->get_mode())) {
|
289
|
+
return;
|
290
|
+
}
|
291
|
+
|
292
|
+
// Spin while response is being received
|
260
293
|
if (!this->spin_wait_(1150, [&] { return this->opentherm_->is_active(); })) {
|
261
294
|
ESP_LOGE(TAG, "Hub timeout triggered during receive");
|
262
295
|
this->stop_opentherm_();
|
263
296
|
return;
|
264
297
|
}
|
265
298
|
|
266
|
-
|
267
|
-
|
268
|
-
this->stop_opentherm_();
|
269
|
-
return;
|
270
|
-
} else if (this->opentherm_->is_protocol_error()) {
|
271
|
-
this->handle_protocol_read_error_();
|
272
|
-
this->stop_opentherm_();
|
299
|
+
// Check for errors and ensure we are in the right state (message received successfully)
|
300
|
+
if (this->handle_error_(this->opentherm_->get_mode())) {
|
273
301
|
return;
|
274
302
|
} else if (!this->opentherm_->has_message()) {
|
275
303
|
ESP_LOGW(TAG, "Unexpected state after receiving response: %s",
|
@@ -281,17 +309,13 @@ void OpenthermHub::sync_loop_() {
|
|
281
309
|
this->read_response_();
|
282
310
|
}
|
283
311
|
|
284
|
-
|
312
|
+
void OpenthermHub::check_timings_(uint32_t cur_time) {
|
285
313
|
if (this->last_conversation_start_ > 0 && (cur_time - this->last_conversation_start_) > 1150) {
|
286
314
|
ESP_LOGW(TAG,
|
287
315
|
"%d ms elapsed since the start of the last convo, but 1150 ms are allowed at maximum. Look at other "
|
288
316
|
"components that might slow the loop down.",
|
289
317
|
(int) (cur_time - this->last_conversation_start_));
|
290
|
-
this->stop_opentherm_();
|
291
|
-
return false;
|
292
318
|
}
|
293
|
-
|
294
|
-
return true;
|
295
319
|
}
|
296
320
|
|
297
321
|
bool OpenthermHub::should_skip_loop_(uint32_t cur_time) const {
|
@@ -304,14 +328,17 @@ bool OpenthermHub::should_skip_loop_(uint32_t cur_time) const {
|
|
304
328
|
}
|
305
329
|
|
306
330
|
void OpenthermHub::start_conversation_() {
|
307
|
-
if (this->
|
308
|
-
this->sending_initial_
|
309
|
-
|
310
|
-
|
311
|
-
|
331
|
+
if (this->message_iterator_ == this->messages_.end()) {
|
332
|
+
if (this->sending_initial_) {
|
333
|
+
this->sending_initial_ = false;
|
334
|
+
this->write_repeating_messages_(this->messages_);
|
335
|
+
}
|
336
|
+
this->message_iterator_ = this->messages_.begin();
|
312
337
|
}
|
313
338
|
|
314
|
-
auto request = this->build_request_(*this->
|
339
|
+
auto request = this->build_request_(*this->message_iterator_);
|
340
|
+
|
341
|
+
this->before_send_callback_.call(request);
|
315
342
|
|
316
343
|
ESP_LOGD(TAG, "Sending request with id %d (%s)", request.id,
|
317
344
|
this->opentherm_->message_id_to_str((MessageId) request.id));
|
@@ -331,37 +358,48 @@ void OpenthermHub::read_response_() {
|
|
331
358
|
|
332
359
|
this->stop_opentherm_();
|
333
360
|
|
361
|
+
this->before_process_response_callback_.call(response);
|
334
362
|
this->process_response(response);
|
335
363
|
|
336
|
-
this->
|
364
|
+
this->message_iterator_++;
|
337
365
|
}
|
338
366
|
|
339
367
|
void OpenthermHub::stop_opentherm_() {
|
340
368
|
this->opentherm_->stop();
|
341
369
|
this->last_conversation_end_ = millis();
|
342
370
|
}
|
343
|
-
|
344
|
-
|
345
|
-
this->opentherm_->operation_mode_to_str(this->opentherm_->get_mode()));
|
346
|
-
this->opentherm_->debug_data(this->last_request_);
|
347
|
-
}
|
348
|
-
void OpenthermHub::handle_protocol_read_error_() {
|
371
|
+
|
372
|
+
void OpenthermHub::handle_protocol_error_() {
|
349
373
|
OpenThermError error;
|
350
374
|
this->opentherm_->get_protocol_error(error);
|
351
375
|
ESP_LOGW(TAG, "Protocol error occured while receiving response: %s",
|
352
|
-
this->opentherm_->
|
376
|
+
this->opentherm_->protocol_error_to_str(error.error_type));
|
353
377
|
this->opentherm_->debug_error(error);
|
378
|
+
this->stop_opentherm_();
|
354
379
|
}
|
380
|
+
|
355
381
|
void OpenthermHub::handle_timeout_error_() {
|
356
|
-
ESP_LOGW(TAG, "
|
382
|
+
ESP_LOGW(TAG, "Timeout while waiting for response from device");
|
357
383
|
this->stop_opentherm_();
|
358
384
|
}
|
359
385
|
|
386
|
+
void OpenthermHub::handle_timer_error_() {
|
387
|
+
this->opentherm_->report_and_reset_timer_error();
|
388
|
+
this->stop_opentherm_();
|
389
|
+
// Timer error is critical, there is no point in retrying.
|
390
|
+
this->mark_failed();
|
391
|
+
}
|
392
|
+
|
360
393
|
void OpenthermHub::dump_config() {
|
394
|
+
std::vector<MessageId> initial_messages;
|
395
|
+
std::vector<MessageId> repeating_messages;
|
396
|
+
this->write_initial_messages_(initial_messages);
|
397
|
+
this->write_repeating_messages_(repeating_messages);
|
398
|
+
|
361
399
|
ESP_LOGCONFIG(TAG, "OpenTherm:");
|
362
400
|
LOG_PIN(" In: ", this->in_pin_);
|
363
401
|
LOG_PIN(" Out: ", this->out_pin_);
|
364
|
-
ESP_LOGCONFIG(TAG, " Sync mode: %
|
402
|
+
ESP_LOGCONFIG(TAG, " Sync mode: %s", YESNO(this->sync_mode_));
|
365
403
|
ESP_LOGCONFIG(TAG, " Sensors: %s", SHOW(OPENTHERM_SENSOR_LIST(ID, )));
|
366
404
|
ESP_LOGCONFIG(TAG, " Binary sensors: %s", SHOW(OPENTHERM_BINARY_SENSOR_LIST(ID, )));
|
367
405
|
ESP_LOGCONFIG(TAG, " Switches: %s", SHOW(OPENTHERM_SWITCH_LIST(ID, )));
|
@@ -369,12 +407,12 @@ void OpenthermHub::dump_config() {
|
|
369
407
|
ESP_LOGCONFIG(TAG, " Outputs: %s", SHOW(OPENTHERM_OUTPUT_LIST(ID, )));
|
370
408
|
ESP_LOGCONFIG(TAG, " Numbers: %s", SHOW(OPENTHERM_NUMBER_LIST(ID, )));
|
371
409
|
ESP_LOGCONFIG(TAG, " Initial requests:");
|
372
|
-
for (auto type :
|
373
|
-
ESP_LOGCONFIG(TAG, " - %d (%s)", type, this->opentherm_->message_id_to_str(
|
410
|
+
for (auto type : initial_messages) {
|
411
|
+
ESP_LOGCONFIG(TAG, " - %d (%s)", type, this->opentherm_->message_id_to_str(type));
|
374
412
|
}
|
375
413
|
ESP_LOGCONFIG(TAG, " Repeating requests:");
|
376
|
-
for (auto type :
|
377
|
-
ESP_LOGCONFIG(TAG, " - %d (%s)", type, this->opentherm_->message_id_to_str(
|
414
|
+
for (auto type : repeating_messages) {
|
415
|
+
ESP_LOGCONFIG(TAG, " - %d (%s)", type, this->opentherm_->message_id_to_str(type));
|
378
416
|
}
|
379
417
|
}
|
380
418
|
|
@@ -38,6 +38,9 @@
|
|
38
38
|
namespace esphome {
|
39
39
|
namespace opentherm {
|
40
40
|
|
41
|
+
static const uint8_t REPEATING_MESSAGE_ORDER = 255;
|
42
|
+
static const uint8_t INITIAL_UNORDERED_MESSAGE_ORDER = 254;
|
43
|
+
|
41
44
|
// OpenTherm component for ESPHome
|
42
45
|
class OpenthermHub : public Component {
|
43
46
|
protected:
|
@@ -58,15 +61,12 @@ class OpenthermHub : public Component {
|
|
58
61
|
|
59
62
|
OPENTHERM_INPUT_SENSOR_LIST(OPENTHERM_DECLARE_INPUT_SENSOR, )
|
60
63
|
|
61
|
-
|
62
|
-
|
63
|
-
// and the repeating messages which are sent repeatedly to update various sensors
|
64
|
-
// and boiler parameters (like the setpoint).
|
65
|
-
std::vector<MessageId> repeating_messages_;
|
66
|
-
// Indicates if we are still working on the initial requests or not
|
64
|
+
OPENTHERM_SETTING_LIST(OPENTHERM_DECLARE_SETTING, )
|
65
|
+
|
67
66
|
bool sending_initial_ = true;
|
68
|
-
|
69
|
-
std::vector<MessageId
|
67
|
+
std::unordered_map<MessageId, uint8_t> configured_messages_;
|
68
|
+
std::vector<MessageId> messages_;
|
69
|
+
std::vector<MessageId>::const_iterator message_iterator_;
|
70
70
|
|
71
71
|
uint32_t last_conversation_start_ = 0;
|
72
72
|
uint32_t last_conversation_end_ = 0;
|
@@ -78,20 +78,25 @@ class OpenthermHub : public Component {
|
|
78
78
|
// Very likely to happen while using Dallas temperature sensors.
|
79
79
|
bool sync_mode_ = false;
|
80
80
|
|
81
|
-
|
81
|
+
CallbackManager<void(OpenthermData &)> before_send_callback_;
|
82
|
+
CallbackManager<void(OpenthermData &)> before_process_response_callback_;
|
82
83
|
|
83
84
|
// Create OpenTherm messages based on the message id
|
84
85
|
OpenthermData build_request_(MessageId request_id) const;
|
85
|
-
|
86
|
-
void
|
86
|
+
bool handle_error_(OperationMode mode);
|
87
|
+
void handle_protocol_error_();
|
87
88
|
void handle_timeout_error_();
|
89
|
+
void handle_timer_error_();
|
88
90
|
void stop_opentherm_();
|
89
91
|
void start_conversation_();
|
90
92
|
void read_response_();
|
91
|
-
|
93
|
+
void check_timings_(uint32_t cur_time);
|
92
94
|
bool should_skip_loop_(uint32_t cur_time) const;
|
93
95
|
void sync_loop_();
|
94
96
|
|
97
|
+
void write_initial_messages_(std::vector<MessageId> &target);
|
98
|
+
void write_repeating_messages_(std::vector<MessageId> &target);
|
99
|
+
|
95
100
|
template<typename F> bool spin_wait_(uint32_t timeout, F func) {
|
96
101
|
auto start_time = millis();
|
97
102
|
while (func()) {
|
@@ -127,13 +132,18 @@ class OpenthermHub : public Component {
|
|
127
132
|
|
128
133
|
OPENTHERM_INPUT_SENSOR_LIST(OPENTHERM_SET_INPUT_SENSOR, )
|
129
134
|
|
135
|
+
OPENTHERM_SETTING_LIST(OPENTHERM_SET_SETTING, )
|
136
|
+
|
130
137
|
// Add a request to the vector of initial requests
|
131
|
-
void add_initial_message(MessageId message_id) {
|
138
|
+
void add_initial_message(MessageId message_id) {
|
139
|
+
this->configured_messages_[message_id] = INITIAL_UNORDERED_MESSAGE_ORDER;
|
140
|
+
}
|
141
|
+
void add_initial_message(MessageId message_id, uint8_t order) { this->configured_messages_[message_id] = order; }
|
132
142
|
// Add a request to the set of repeating requests. Note that a large number of repeating
|
133
143
|
// requests will slow down communication with the boiler. Each request may take up to 1 second,
|
134
144
|
// so with all sensors enabled, it may take about half a minute before a change in setpoint
|
135
145
|
// will be processed.
|
136
|
-
void add_repeating_message(MessageId message_id) { this->
|
146
|
+
void add_repeating_message(MessageId message_id) { this->configured_messages_[message_id] = REPEATING_MESSAGE_ORDER; }
|
137
147
|
|
138
148
|
// There are seven status variables, which can either be set as a simple variable,
|
139
149
|
// or using a switch. ch_enable and dhw_enable default to true, the others to false.
|
@@ -149,7 +159,13 @@ class OpenthermHub : public Component {
|
|
149
159
|
void set_summer_mode_active(bool value) { this->summer_mode_active = value; }
|
150
160
|
void set_dhw_block(bool value) { this->dhw_block = value; }
|
151
161
|
void set_sync_mode(bool sync_mode) { this->sync_mode_ = sync_mode; }
|
152
|
-
|
162
|
+
|
163
|
+
void add_on_before_send_callback(std::function<void(OpenthermData &)> &&callback) {
|
164
|
+
this->before_send_callback_.add(std::move(callback));
|
165
|
+
}
|
166
|
+
void add_on_before_process_response_callback(std::function<void(OpenthermData &)> &&callback) {
|
167
|
+
this->before_process_response_callback_.add(std::move(callback));
|
168
|
+
}
|
153
169
|
|
154
170
|
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
155
171
|
|
@@ -52,7 +52,9 @@ bool OpenTherm::initialize() {
|
|
52
52
|
OpenTherm::instance = this;
|
53
53
|
#endif
|
54
54
|
this->in_pin_->pin_mode(gpio::FLAG_INPUT);
|
55
|
+
this->in_pin_->setup();
|
55
56
|
this->out_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
57
|
+
this->out_pin_->setup();
|
56
58
|
this->out_pin_->digital_write(true);
|
57
59
|
|
58
60
|
#if defined(ESP32) || defined(USE_ESP_IDF)
|
@@ -182,7 +184,7 @@ bool IRAM_ATTR OpenTherm::timer_isr(OpenTherm *arg) {
|
|
182
184
|
}
|
183
185
|
arg->capture_ = 1; // reset counter
|
184
186
|
} else if (arg->capture_ > 0xFF) {
|
185
|
-
// no change for too long, invalid
|
187
|
+
// no change for too long, invalid manchester encoding
|
186
188
|
arg->mode_ = OperationMode::ERROR_PROTOCOL;
|
187
189
|
arg->error_type_ = ProtocolErrorType::NO_CHANGE_TOO_LONG;
|
188
190
|
arg->stop_timer_();
|
@@ -312,21 +314,31 @@ bool OpenTherm::init_esp32_timer_() {
|
|
312
314
|
}
|
313
315
|
|
314
316
|
void IRAM_ATTR OpenTherm::start_esp32_timer_(uint64_t alarm_value) {
|
315
|
-
|
317
|
+
// We will report timer errors outside of interrupt handler
|
318
|
+
this->timer_error_ = ESP_OK;
|
319
|
+
this->timer_error_type_ = TimerErrorType::NO_TIMER_ERROR;
|
316
320
|
|
317
|
-
|
318
|
-
if (
|
319
|
-
|
320
|
-
ESP_LOGE(TAG, "Failed to set alarm value. Error: %s", error);
|
321
|
+
this->timer_error_ = timer_set_alarm_value(this->timer_group_, this->timer_idx_, alarm_value);
|
322
|
+
if (this->timer_error_ != ESP_OK) {
|
323
|
+
this->timer_error_type_ = TimerErrorType::SET_ALARM_VALUE_ERROR;
|
321
324
|
return;
|
322
325
|
}
|
326
|
+
this->timer_error_ = timer_start(this->timer_group_, this->timer_idx_);
|
327
|
+
if (this->timer_error_ != ESP_OK) {
|
328
|
+
this->timer_error_type_ = TimerErrorType::TIMER_START_ERROR;
|
329
|
+
}
|
330
|
+
}
|
323
331
|
|
324
|
-
|
325
|
-
if (
|
326
|
-
const auto *error = esp_err_to_name(result);
|
327
|
-
ESP_LOGE(TAG, "Failed to start the timer. Error: %s", error);
|
332
|
+
void OpenTherm::report_and_reset_timer_error() {
|
333
|
+
if (this->timer_error_ == ESP_OK) {
|
328
334
|
return;
|
329
335
|
}
|
336
|
+
|
337
|
+
ESP_LOGE(TAG, "Error occured while manipulating timer (%s): %s", this->timer_error_to_str(this->timer_error_type_),
|
338
|
+
esp_err_to_name(this->timer_error_));
|
339
|
+
|
340
|
+
this->timer_error_ = ESP_OK;
|
341
|
+
this->timer_error_type_ = NO_TIMER_ERROR;
|
330
342
|
}
|
331
343
|
|
332
344
|
// 5 kHz timer_
|
@@ -343,21 +355,18 @@ void IRAM_ATTR OpenTherm::start_write_timer_() {
|
|
343
355
|
|
344
356
|
void IRAM_ATTR OpenTherm::stop_timer_() {
|
345
357
|
InterruptLock const lock;
|
358
|
+
// We will report timer errors outside of interrupt handler
|
359
|
+
this->timer_error_ = ESP_OK;
|
360
|
+
this->timer_error_type_ = TimerErrorType::NO_TIMER_ERROR;
|
346
361
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
if (result != ESP_OK) {
|
351
|
-
const auto *error = esp_err_to_name(result);
|
352
|
-
ESP_LOGE(TAG, "Failed to pause the timer. Error: %s", error);
|
362
|
+
this->timer_error_ = timer_pause(this->timer_group_, this->timer_idx_);
|
363
|
+
if (this->timer_error_ != ESP_OK) {
|
364
|
+
this->timer_error_type_ = TimerErrorType::TIMER_PAUSE_ERROR;
|
353
365
|
return;
|
354
366
|
}
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
const auto *error = esp_err_to_name(result);
|
359
|
-
ESP_LOGE(TAG, "Failed to set timer counter to 0 after pausing. Error: %s", error);
|
360
|
-
return;
|
367
|
+
this->timer_error_ = timer_set_counter_value(this->timer_group_, this->timer_idx_, 0);
|
368
|
+
if (this->timer_error_ != ESP_OK) {
|
369
|
+
this->timer_error_type_ = TimerErrorType::SET_COUNTER_VALUE_ERROR;
|
361
370
|
}
|
362
371
|
}
|
363
372
|
|
@@ -386,6 +395,9 @@ void IRAM_ATTR OpenTherm::stop_timer_() {
|
|
386
395
|
timer1_detachInterrupt();
|
387
396
|
}
|
388
397
|
|
398
|
+
// There is nothing to report on ESP8266
|
399
|
+
void OpenTherm::report_and_reset_timer_error() {}
|
400
|
+
|
389
401
|
#endif // END ESP8266
|
390
402
|
|
391
403
|
// https://stackoverflow.com/questions/21617970/how-to-check-if-value-has-even-parity-of-bits-or-odd
|
@@ -412,11 +424,12 @@ const char *OpenTherm::operation_mode_to_str(OperationMode mode) {
|
|
412
424
|
TO_STRING_MEMBER(SENT)
|
413
425
|
TO_STRING_MEMBER(ERROR_PROTOCOL)
|
414
426
|
TO_STRING_MEMBER(ERROR_TIMEOUT)
|
427
|
+
TO_STRING_MEMBER(ERROR_TIMER)
|
415
428
|
default:
|
416
429
|
return "<INVALID>";
|
417
430
|
}
|
418
431
|
}
|
419
|
-
const char *OpenTherm::
|
432
|
+
const char *OpenTherm::protocol_error_to_str(ProtocolErrorType error_type) {
|
420
433
|
switch (error_type) {
|
421
434
|
TO_STRING_MEMBER(NO_ERROR)
|
422
435
|
TO_STRING_MEMBER(NO_TRANSITION)
|
@@ -427,6 +440,17 @@ const char *OpenTherm::protocol_error_to_to_str(ProtocolErrorType error_type) {
|
|
427
440
|
return "<INVALID>";
|
428
441
|
}
|
429
442
|
}
|
443
|
+
const char *OpenTherm::timer_error_to_str(TimerErrorType error_type) {
|
444
|
+
switch (error_type) {
|
445
|
+
TO_STRING_MEMBER(NO_TIMER_ERROR)
|
446
|
+
TO_STRING_MEMBER(SET_ALARM_VALUE_ERROR)
|
447
|
+
TO_STRING_MEMBER(TIMER_START_ERROR)
|
448
|
+
TO_STRING_MEMBER(TIMER_PAUSE_ERROR)
|
449
|
+
TO_STRING_MEMBER(SET_COUNTER_VALUE_ERROR)
|
450
|
+
default:
|
451
|
+
return "<INVALID>";
|
452
|
+
}
|
453
|
+
}
|
430
454
|
const char *OpenTherm::message_type_to_str(MessageType message_type) {
|
431
455
|
switch (message_type) {
|
432
456
|
TO_STRING_MEMBER(READ_DATA)
|
@@ -36,11 +36,12 @@ enum OperationMode {
|
|
36
36
|
READ = 2, // reading 32-bit data frame
|
37
37
|
RECEIVED = 3, // data frame received with valid start and stop bit
|
38
38
|
|
39
|
-
WRITE = 4, // writing data
|
39
|
+
WRITE = 4, // writing data to output
|
40
40
|
SENT = 5, // all data written to output
|
41
41
|
|
42
|
-
ERROR_PROTOCOL = 8, //
|
43
|
-
ERROR_TIMEOUT = 9
|
42
|
+
ERROR_PROTOCOL = 8, // protocol error, can happed only during READ
|
43
|
+
ERROR_TIMEOUT = 9, // timeout while waiting for response from device, only during LISTEN
|
44
|
+
ERROR_TIMER = 10 // error operating the ESP32 timer
|
44
45
|
};
|
45
46
|
|
46
47
|
enum ProtocolErrorType {
|
@@ -51,6 +52,14 @@ enum ProtocolErrorType {
|
|
51
52
|
NO_CHANGE_TOO_LONG = 4, // No level change for too much timer ticks
|
52
53
|
};
|
53
54
|
|
55
|
+
enum TimerErrorType {
|
56
|
+
NO_TIMER_ERROR = 0, // No error
|
57
|
+
SET_ALARM_VALUE_ERROR = 1, // No transition in the middle of the bit
|
58
|
+
TIMER_START_ERROR = 2, // Stop bit wasn't present when expected
|
59
|
+
TIMER_PAUSE_ERROR = 3, // Parity check didn't pass
|
60
|
+
SET_COUNTER_VALUE_ERROR = 4, // No level change for too much timer ticks
|
61
|
+
};
|
62
|
+
|
54
63
|
enum MessageType {
|
55
64
|
READ_DATA = 0,
|
56
65
|
READ_ACK = 4,
|
@@ -299,7 +308,9 @@ class OpenTherm {
|
|
299
308
|
*
|
300
309
|
* @return true if last listen() or send() operation ends up with an error.
|
301
310
|
*/
|
302
|
-
bool is_error() {
|
311
|
+
bool is_error() {
|
312
|
+
return mode_ == OperationMode::ERROR_TIMEOUT || mode_ == OperationMode::ERROR_PROTOCOL || mode_ == ERROR_TIMER;
|
313
|
+
}
|
303
314
|
|
304
315
|
/**
|
305
316
|
* Indicates whether last listen() or send() operation ends up with a *timeout* error
|
@@ -313,14 +324,22 @@ class OpenTherm {
|
|
313
324
|
*/
|
314
325
|
bool is_protocol_error() { return mode_ == OperationMode::ERROR_PROTOCOL; }
|
315
326
|
|
327
|
+
/**
|
328
|
+
* Indicates whether start_esp32_timer_() or stop_timer_() had an error. Only relevant when used on ESP32.
|
329
|
+
* @return true if there was an error.
|
330
|
+
*/
|
331
|
+
bool is_timer_error() { return mode_ == OperationMode::ERROR_TIMER; }
|
332
|
+
|
316
333
|
bool is_active() { return mode_ == LISTEN || mode_ == READ || mode_ == WRITE; }
|
317
334
|
|
318
335
|
OperationMode get_mode() { return mode_; }
|
319
336
|
|
320
337
|
void debug_data(OpenthermData &data);
|
321
338
|
void debug_error(OpenThermError &error) const;
|
339
|
+
void report_and_reset_timer_error();
|
322
340
|
|
323
|
-
const char *
|
341
|
+
const char *protocol_error_to_str(ProtocolErrorType error_type);
|
342
|
+
const char *timer_error_to_str(TimerErrorType error_type);
|
324
343
|
const char *message_type_to_str(MessageType message_type);
|
325
344
|
const char *operation_mode_to_str(OperationMode mode);
|
326
345
|
const char *message_id_to_str(MessageId id);
|
@@ -349,10 +368,12 @@ class OpenTherm {
|
|
349
368
|
uint32_t data_;
|
350
369
|
uint8_t bit_pos_;
|
351
370
|
int32_t timeout_counter_; // <0 no timeout
|
352
|
-
|
353
371
|
int32_t device_timeout_;
|
354
372
|
|
355
373
|
#if defined(ESP32) || defined(USE_ESP_IDF)
|
374
|
+
esp_err_t timer_error_ = ESP_OK;
|
375
|
+
TimerErrorType timer_error_type_ = TimerErrorType::NO_TIMER_ERROR;
|
376
|
+
|
356
377
|
bool init_esp32_timer_();
|
357
378
|
void start_esp32_timer_(uint64_t alarm_value);
|
358
379
|
#endif
|