esphome 2025.9.3__py3-none-any.whl → 2025.10.0b2__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 +94 -31
- esphome/address_cache.py +142 -0
- esphome/automation.py +130 -32
- esphome/build_gen/platformio.py +1 -3
- esphome/codegen.py +1 -0
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/api/__init__.py +166 -3
- esphome/components/api/api_connection.cpp +84 -41
- esphome/components/api/api_connection.h +22 -16
- esphome/components/api/api_frame_helper.cpp +33 -19
- esphome/components/api/api_frame_helper.h +19 -4
- esphome/components/api/api_frame_helper_noise.cpp +41 -53
- esphome/components/api/api_frame_helper_noise.h +1 -1
- esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
- esphome/components/api/api_frame_helper_plaintext.h +1 -1
- esphome/components/api/api_pb2.cpp +189 -15
- esphome/components/api/api_pb2.h +132 -20
- esphome/components/api/api_pb2_dump.cpp +97 -9
- esphome/components/api/api_pb2_service.cpp +118 -160
- esphome/components/api/api_pb2_service.h +31 -3
- esphome/components/api/api_server.cpp +68 -10
- esphome/components/api/api_server.h +32 -4
- esphome/components/api/custom_api_device.h +8 -8
- esphome/components/api/homeassistant_service.h +123 -6
- esphome/components/api/proto.h +6 -2
- esphome/components/api/user_services.h +2 -2
- esphome/components/as7341/sensor.py +1 -1
- esphome/components/audio/__init__.py +1 -1
- esphome/components/audio/audio.cpp +1 -1
- esphome/components/audio/audio_decoder.cpp +9 -9
- esphome/components/bl0906/bl0906.cpp +2 -2
- esphome/components/bl0942/bl0942.cpp +2 -2
- esphome/components/ble_client/__init__.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +4 -30
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
- esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
- esphome/components/camera_encoder/__init__.py +2 -4
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
- esphome/components/canbus/canbus.cpp +7 -5
- esphome/components/canbus/canbus.h +7 -7
- esphome/components/captive_portal/__init__.py +18 -1
- esphome/components/captive_portal/captive_portal.cpp +40 -46
- esphome/components/captive_portal/captive_portal.h +20 -22
- esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
- esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
- esphome/components/ccs811/ccs811.cpp +1 -1
- esphome/components/climate/climate.cpp +10 -7
- esphome/components/cm1106/cm1106.cpp +1 -1
- esphome/components/copy/lock/copy_lock.cpp +1 -1
- esphome/components/cover/cover.cpp +1 -0
- esphome/components/daikin_arc/daikin_arc.cpp +19 -12
- esphome/components/dashboard_import/dashboard_import.cpp +1 -1
- esphome/components/dashboard_import/dashboard_import.h +1 -1
- esphome/components/deep_sleep/__init__.py +9 -2
- esphome/components/deep_sleep/deep_sleep_component.h +11 -9
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
- esphome/components/ektf2232/touchscreen/__init__.py +8 -5
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
- esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
- esphome/components/epaper_spi/__init__.py +1 -0
- esphome/components/epaper_spi/display.py +80 -0
- esphome/components/epaper_spi/epaper_spi.cpp +227 -0
- esphome/components/epaper_spi/epaper_spi.h +93 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
- esphome/components/es7210/es7210.cpp +3 -3
- esphome/components/esp32/__init__.py +256 -340
- esphome/components/esp32/boards.py +81 -0
- esphome/components/esp32/preferences.cpp +23 -17
- esphome/components/esp32_ble/__init__.py +167 -44
- esphome/components/esp32_ble/ble.cpp +47 -3
- esphome/components/esp32_ble/ble.h +18 -0
- esphome/components/esp32_ble/ble_advertising.cpp +7 -3
- esphome/components/esp32_ble/ble_advertising.h +4 -0
- esphome/components/esp32_ble/ble_uuid.cpp +16 -42
- esphome/components/esp32_ble_beacon/__init__.py +3 -4
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +0 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
- esphome/components/esp32_ble_server/__init__.py +28 -14
- esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
- esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
- esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
- esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
- esphome/components/esp32_ble_server/ble_server.cpp +59 -24
- esphome/components/esp32_ble_server/ble_server.h +38 -20
- esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
- esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
- esphome/components/esp32_ble_tracker/__init__.py +25 -80
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -8
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
- esphome/components/esp32_camera/__init__.py +1 -3
- esphome/components/esp32_can/esp32_can.cpp +22 -4
- esphome/components/esp32_can/esp32_can.h +3 -0
- esphome/components/esp32_hosted/__init__.py +2 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +135 -65
- esphome/components/esp32_improv/esp32_improv_component.h +7 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp8266/__init__.py +3 -3
- esphome/components/esphome/ota/__init__.py +21 -2
- esphome/components/esphome/ota/ota_esphome.cpp +456 -146
- esphome/components/esphome/ota/ota_esphome.h +49 -2
- esphome/components/ethernet/__init__.py +39 -22
- esphome/components/ethernet/ethernet_component.cpp +28 -5
- esphome/components/ethernet/ethernet_component.h +5 -1
- esphome/components/external_components/__init__.py +8 -6
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
- esphome/components/font/__init__.py +5 -5
- esphome/components/graph/graph.cpp +1 -1
- esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
- esphome/components/haier/hon_climate.cpp +2 -2
- esphome/components/haier/hon_climate.h +1 -1
- esphome/components/hdc1080/hdc1080.cpp +42 -34
- esphome/components/hdc1080/hdc1080.h +1 -3
- esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
- esphome/components/http_request/__init__.py +3 -3
- esphome/components/htu21d/htu21d.cpp +13 -18
- esphome/components/htu21d/htu21d.h +1 -1
- esphome/components/i2s_audio/__init__.py +1 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
- esphome/components/improv_serial/improv_serial_component.cpp +12 -15
- esphome/components/improv_serial/improv_serial_component.h +6 -8
- esphome/components/json/json_util.cpp +42 -44
- esphome/components/json/json_util.h +57 -0
- esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
- esphome/components/key_collector/key_collector.h +4 -4
- esphome/components/libretiny/__init__.py +6 -6
- esphome/components/libretiny/preferences.cpp +23 -16
- esphome/components/light/light_call.cpp +98 -120
- esphome/components/light/light_call.h +17 -7
- esphome/components/lm75b/__init__.py +0 -0
- esphome/components/lm75b/lm75b.cpp +39 -0
- esphome/components/lm75b/lm75b.h +19 -0
- esphome/components/lm75b/sensor.py +34 -0
- esphome/components/lock/lock.h +12 -6
- esphome/components/logger/__init__.py +15 -27
- esphome/components/logger/logger.cpp +10 -20
- esphome/components/logger/logger.h +105 -62
- esphome/components/logger/logger_esp32.cpp +0 -48
- esphome/components/logger/logger_zephyr.cpp +2 -3
- esphome/components/logger/select/logger_level_select.cpp +6 -7
- esphome/components/logger/select/logger_level_select.h +7 -0
- esphome/components/ltr501/ltr501.cpp +7 -6
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
- esphome/components/matrix_keypad/matrix_keypad.h +4 -4
- esphome/components/max7219digit/max7219digit.cpp +1 -1
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +3 -3
- esphome/components/mcp2515/mcp2515.cpp +31 -3
- esphome/components/mcp2515/mcp2515_defs.h +3 -1
- esphome/components/md5/md5.cpp +0 -26
- esphome/components/md5/md5.h +10 -20
- esphome/components/mdns/__init__.py +93 -19
- esphome/components/mdns/mdns_component.cpp +57 -94
- esphome/components/mdns/mdns_component.h +35 -11
- esphome/components/mdns/mdns_esp32.cpp +7 -13
- esphome/components/mdns/mdns_esp8266.cpp +7 -7
- esphome/components/mdns/mdns_libretiny.cpp +3 -4
- esphome/components/mdns/mdns_rp2040.cpp +3 -4
- esphome/components/mipi/__init__.py +1 -5
- esphome/components/mipi_spi/display.py +24 -8
- esphome/components/mipi_spi/mipi_spi.h +3 -3
- esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
- esphome/components/mmc5603/mmc5603.cpp +3 -3
- esphome/components/modbus/modbus.cpp +27 -13
- esphome/components/modbus/modbus.h +5 -3
- esphome/components/modbus/modbus_definitions.h +86 -0
- esphome/components/modbus_controller/__init__.py +29 -1
- esphome/components/modbus_controller/const.py +4 -0
- esphome/components/modbus_controller/modbus_controller.cpp +38 -13
- esphome/components/modbus_controller/modbus_controller.h +18 -29
- esphome/components/mpr121/mpr121.cpp +41 -42
- esphome/components/mpr121/mpr121.h +0 -1
- esphome/components/nau7802/nau7802.cpp +2 -2
- esphome/components/network/__init__.py +7 -3
- esphome/components/nextion/display.py +4 -4
- esphome/components/nextion/nextion.cpp +8 -8
- esphome/components/number/__init__.py +2 -0
- esphome/components/number/number_call.cpp +23 -12
- esphome/components/number/number_call.h +5 -0
- esphome/components/online_image/bmp_image.cpp +2 -1
- esphome/components/online_image/jpeg_image.cpp +4 -2
- esphome/components/opentherm/opentherm.cpp +5 -5
- esphome/components/opentherm/opentherm.h +3 -3
- esphome/components/openthread/openthread.cpp +11 -10
- esphome/components/openthread/openthread.h +0 -1
- esphome/components/ota/ota_backend.h +1 -0
- esphome/components/packages/__init__.py +10 -8
- esphome/components/packet_transport/packet_transport.cpp +2 -0
- esphome/components/pid/pid_controller.cpp +1 -1
- esphome/components/prometheus/prometheus_handler.cpp +239 -239
- esphome/components/psram/__init__.py +30 -28
- esphome/components/qmc5883l/qmc5883l.cpp +15 -0
- esphome/components/qmc5883l/qmc5883l.h +3 -0
- esphome/components/qmc5883l/sensor.py +31 -12
- esphome/components/remote_base/gobox_protocol.cpp +3 -3
- esphome/components/remote_receiver/__init__.py +14 -2
- esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
- esphome/components/remote_receiver/remote_receiver.h +4 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
- esphome/components/remote_transmitter/__init__.py +2 -2
- esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
- esphome/components/rp2040/__init__.py +11 -11
- esphome/components/rtttl/rtttl.cpp +2 -2
- esphome/components/scd30/sensor.py +1 -1
- esphome/components/script/__init__.py +1 -1
- esphome/components/script/script.h +7 -7
- esphome/components/select/select.cpp +5 -4
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/sha256/__init__.py +22 -0
- esphome/components/sha256/sha256.cpp +116 -0
- esphome/components/sha256/sha256.h +60 -0
- esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
- esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
- esphome/components/spi/__init__.py +0 -3
- esphome/components/split_buffer/__init__.py +5 -0
- esphome/components/split_buffer/split_buffer.cpp +133 -0
- esphome/components/split_buffer/split_buffer.h +40 -0
- esphome/components/sps30/sps30.cpp +14 -10
- esphome/components/sps30/sps30.h +2 -0
- esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
- esphome/components/st7789v/st7789v.cpp +3 -2
- esphome/components/statsd/statsd.cpp +1 -1
- esphome/components/substitutions/__init__.py +3 -1
- esphome/components/substitutions/jinja.py +13 -3
- esphome/components/sx126x/__init__.py +16 -0
- esphome/components/sx126x/sx126x.cpp +15 -1
- esphome/components/sx126x/sx126x.h +9 -1
- esphome/components/sx126x/sx126x_reg.h +2 -0
- esphome/components/text_sensor/text_sensor.cpp +16 -0
- esphome/components/text_sensor/text_sensor.h +3 -10
- esphome/components/tormatic/tormatic_cover.cpp +1 -1
- esphome/components/tuya/select/tuya_select.cpp +1 -1
- esphome/components/tuya/tuya.cpp +29 -4
- esphome/components/uart/__init__.py +37 -27
- esphome/components/uart/uart.h +6 -0
- esphome/components/uart/uart_component.cpp +8 -0
- esphome/components/uart/uart_component.h +28 -0
- esphome/components/uart/uart_component_esp_idf.cpp +64 -10
- esphome/components/uart/uart_component_esp_idf.h +5 -2
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
- esphome/components/usb_host/__init__.py +12 -2
- esphome/components/usb_host/usb_host.h +89 -14
- esphome/components/usb_host/usb_host_client.cpp +157 -22
- esphome/components/usb_host/usb_host_component.cpp +1 -1
- esphome/components/usb_uart/__init__.py +0 -1
- esphome/components/usb_uart/ch34x.cpp +4 -4
- esphome/components/usb_uart/cp210x.cpp +3 -3
- esphome/components/usb_uart/usb_uart.cpp +88 -32
- esphome/components/usb_uart/usb_uart.h +30 -6
- esphome/components/valve/valve.cpp +1 -0
- esphome/components/veml7700/veml7700.cpp +7 -6
- esphome/components/version/version_text_sensor.cpp +2 -1
- esphome/components/voice_assistant/voice_assistant.cpp +3 -2
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
- esphome/components/web_server/list_entities.cpp +3 -4
- esphome/components/web_server/list_entities.h +8 -10
- esphome/components/web_server/ota/__init__.py +1 -1
- esphome/components/web_server/ota/ota_web_server.cpp +9 -3
- esphome/components/web_server/web_server.cpp +509 -404
- esphome/components/web_server/web_server.h +5 -6
- esphome/components/web_server/web_server_v1.cpp +21 -19
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.h +27 -7
- esphome/components/web_server_idf/__init__.py +1 -1
- esphome/components/web_server_idf/multipart.cpp +2 -2
- esphome/components/web_server_idf/multipart.h +2 -2
- esphome/components/web_server_idf/utils.cpp +2 -2
- esphome/components/web_server_idf/utils.h +2 -2
- esphome/components/web_server_idf/web_server_idf.cpp +118 -26
- esphome/components/web_server_idf/web_server_idf.h +12 -10
- esphome/components/wifi/__init__.py +13 -11
- esphome/components/wifi/wifi_component.cpp +74 -56
- esphome/components/wifi/wifi_component.h +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/wts01/__init__.py +0 -0
- esphome/components/wts01/sensor.py +41 -0
- esphome/components/wts01/wts01.cpp +91 -0
- esphome/components/wts01/wts01.h +27 -0
- esphome/components/zephyr/__init__.py +5 -5
- esphome/components/zwave_proxy/__init__.py +43 -0
- esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
- esphome/components/zwave_proxy/zwave_proxy.h +93 -0
- esphome/config.py +79 -24
- esphome/config_validation.py +13 -15
- esphome/const.py +9 -2
- esphome/core/__init__.py +33 -22
- esphome/core/component.cpp +28 -18
- esphome/core/component_iterator.h +2 -1
- esphome/core/config.py +15 -15
- esphome/core/defines.h +21 -0
- esphome/core/entity_helpers.py +9 -6
- esphome/core/hash_base.h +56 -0
- esphome/core/helpers.cpp +19 -3
- esphome/core/helpers.h +26 -0
- esphome/core/scheduler.cpp +5 -21
- esphome/core/scheduler.h +19 -8
- esphome/core/string_ref.h +1 -1
- esphome/core/time.cpp +5 -5
- esphome/cpp_generator.py +4 -29
- esphome/dashboard/const.py +21 -4
- esphome/dashboard/core.py +10 -8
- esphome/dashboard/dns.py +15 -0
- esphome/dashboard/entries.py +15 -21
- esphome/dashboard/models.py +76 -0
- esphome/dashboard/settings.py +7 -7
- esphome/dashboard/status/mdns.py +46 -2
- esphome/dashboard/web_server.py +367 -93
- esphome/espota2.py +112 -32
- esphome/external_files.py +6 -7
- esphome/git.py +8 -0
- esphome/helpers.py +124 -77
- esphome/loader.py +8 -9
- esphome/pins.py +2 -2
- esphome/platformio_api.py +56 -18
- esphome/storage_json.py +26 -21
- esphome/types.py +30 -2
- esphome/util.py +32 -16
- esphome/vscode.py +8 -8
- esphome/wizard.py +10 -10
- esphome/writer.py +50 -15
- esphome/yaml_util.py +37 -31
- esphome/zeroconf.py +12 -3
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/METADATA +12 -12
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/RECORD +340 -320
- esphome/components/event_emitter/__init__.py +0 -5
- esphome/components/event_emitter/event_emitter.cpp +0 -14
- esphome/components/event_emitter/event_emitter.h +0 -63
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
- esphome/components/uart/uart_component_esp32_arduino.h +0 -60
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
- esphome/core/string_ref.cpp +0 -12
- esphome/dashboard/util/file.py +0 -63
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,6 @@
|
|
2
2
|
#if defined(USE_ESP32) && defined(USE_MDNS)
|
3
3
|
|
4
4
|
#include <mdns.h>
|
5
|
-
#include <cstring>
|
6
5
|
#include "esphome/core/hal.h"
|
7
6
|
#include "esphome/core/log.h"
|
8
7
|
#include "mdns_component.h"
|
@@ -29,23 +28,18 @@ void MDNSComponent::setup() {
|
|
29
28
|
std::vector<mdns_txt_item_t> txt_records;
|
30
29
|
for (const auto &record : service.txt_records) {
|
31
30
|
mdns_txt_item_t it{};
|
32
|
-
//
|
33
|
-
|
34
|
-
it.
|
31
|
+
// key and value are either compile-time string literals in flash or pointers to dynamic_txt_values_
|
32
|
+
// Both remain valid for the lifetime of this function, and ESP-IDF makes internal copies
|
33
|
+
it.key = MDNS_STR_ARG(record.key);
|
34
|
+
it.value = MDNS_STR_ARG(record.value);
|
35
35
|
txt_records.push_back(it);
|
36
36
|
}
|
37
37
|
uint16_t port = const_cast<TemplatableValue<uint16_t> &>(service.port).value();
|
38
|
-
err = mdns_service_add(nullptr, service.service_type
|
39
|
-
txt_records.size());
|
40
|
-
|
41
|
-
// free records
|
42
|
-
for (const auto &it : txt_records) {
|
43
|
-
delete it.key; // NOLINT(cppcoreguidelines-owning-memory)
|
44
|
-
delete it.value; // NOLINT(cppcoreguidelines-owning-memory)
|
45
|
-
}
|
38
|
+
err = mdns_service_add(nullptr, MDNS_STR_ARG(service.service_type), MDNS_STR_ARG(service.proto), port,
|
39
|
+
txt_records.data(), txt_records.size());
|
46
40
|
|
47
41
|
if (err != ESP_OK) {
|
48
|
-
ESP_LOGW(TAG, "Failed to register service %s: %s", service.service_type
|
42
|
+
ESP_LOGW(TAG, "Failed to register service %s: %s", MDNS_STR_ARG(service.service_type), esp_err_to_name(err));
|
49
43
|
}
|
50
44
|
}
|
51
45
|
}
|
@@ -21,19 +21,19 @@ void MDNSComponent::setup() {
|
|
21
21
|
// part of the wire protocol to have an underscore, and for example ESP-IDF
|
22
22
|
// expects the underscore to be there, the ESP8266 implementation always adds
|
23
23
|
// the underscore itself.
|
24
|
-
auto *proto = service.proto
|
25
|
-
while (*proto == '_') {
|
24
|
+
auto *proto = MDNS_STR_ARG(service.proto);
|
25
|
+
while (progmem_read_byte((const uint8_t *) proto) == '_') {
|
26
26
|
proto++;
|
27
27
|
}
|
28
|
-
auto *service_type = service.service_type
|
29
|
-
while (*service_type == '_') {
|
28
|
+
auto *service_type = MDNS_STR_ARG(service.service_type);
|
29
|
+
while (progmem_read_byte((const uint8_t *) service_type) == '_') {
|
30
30
|
service_type++;
|
31
31
|
}
|
32
32
|
uint16_t port = const_cast<TemplatableValue<uint16_t> &>(service.port).value();
|
33
|
-
MDNS.addService(service_type, proto, port);
|
33
|
+
MDNS.addService(FPSTR(service_type), FPSTR(proto), port);
|
34
34
|
for (const auto &record : service.txt_records) {
|
35
|
-
MDNS.addServiceTxt(service_type, proto, record.key
|
36
|
-
|
35
|
+
MDNS.addServiceTxt(FPSTR(service_type), FPSTR(proto), FPSTR(MDNS_STR_ARG(record.key)),
|
36
|
+
FPSTR(MDNS_STR_ARG(record.value)));
|
37
37
|
}
|
38
38
|
}
|
39
39
|
}
|
@@ -21,19 +21,18 @@ void MDNSComponent::setup() {
|
|
21
21
|
// part of the wire protocol to have an underscore, and for example ESP-IDF
|
22
22
|
// expects the underscore to be there, the ESP8266 implementation always adds
|
23
23
|
// the underscore itself.
|
24
|
-
auto *proto = service.proto
|
24
|
+
auto *proto = MDNS_STR_ARG(service.proto);
|
25
25
|
while (*proto == '_') {
|
26
26
|
proto++;
|
27
27
|
}
|
28
|
-
auto *service_type = service.service_type
|
28
|
+
auto *service_type = MDNS_STR_ARG(service.service_type);
|
29
29
|
while (*service_type == '_') {
|
30
30
|
service_type++;
|
31
31
|
}
|
32
32
|
uint16_t port_ = const_cast<TemplatableValue<uint16_t> &>(service.port).value();
|
33
33
|
MDNS.addService(service_type, proto, port_);
|
34
34
|
for (const auto &record : service.txt_records) {
|
35
|
-
MDNS.addServiceTxt(service_type, proto, record.key.
|
36
|
-
const_cast<TemplatableValue<std::string> &>(record.value).value().c_str());
|
35
|
+
MDNS.addServiceTxt(service_type, proto, MDNS_STR_ARG(record.key), MDNS_STR_ARG(record.value));
|
37
36
|
}
|
38
37
|
}
|
39
38
|
}
|
@@ -21,19 +21,18 @@ void MDNSComponent::setup() {
|
|
21
21
|
// part of the wire protocol to have an underscore, and for example ESP-IDF
|
22
22
|
// expects the underscore to be there, the ESP8266 implementation always adds
|
23
23
|
// the underscore itself.
|
24
|
-
auto *proto = service.proto
|
24
|
+
auto *proto = MDNS_STR_ARG(service.proto);
|
25
25
|
while (*proto == '_') {
|
26
26
|
proto++;
|
27
27
|
}
|
28
|
-
auto *service_type = service.service_type
|
28
|
+
auto *service_type = MDNS_STR_ARG(service.service_type);
|
29
29
|
while (*service_type == '_') {
|
30
30
|
service_type++;
|
31
31
|
}
|
32
32
|
uint16_t port = const_cast<TemplatableValue<uint16_t> &>(service.port).value();
|
33
33
|
MDNS.addService(service_type, proto, port);
|
34
34
|
for (const auto &record : service.txt_records) {
|
35
|
-
MDNS.addServiceTxt(service_type, proto, record.key.
|
36
|
-
const_cast<TemplatableValue<std::string> &>(record.value).value().c_str());
|
35
|
+
MDNS.addServiceTxt(service_type, proto, MDNS_STR_ARG(record.key), MDNS_STR_ARG(record.value));
|
37
36
|
}
|
38
37
|
}
|
39
38
|
}
|
@@ -343,11 +343,7 @@ class DriverChip:
|
|
343
343
|
)
|
344
344
|
offset_height = native_height - height - offset_height
|
345
345
|
# Swap default dimensions if swap_xy is set, or if rotation is 90/270 and we are not using a buffer
|
346
|
-
|
347
|
-
90,
|
348
|
-
270,
|
349
|
-
)
|
350
|
-
if transform.get(CONF_SWAP_XY) is True or rotated:
|
346
|
+
if transform.get(CONF_SWAP_XY) is True:
|
351
347
|
width, height = height, width
|
352
348
|
offset_height, offset_width = offset_width, offset_height
|
353
349
|
return width, height, offset_width, offset_height
|
@@ -380,25 +380,41 @@ def get_instance(config):
|
|
380
380
|
bus_type = BusTypes[bus_type]
|
381
381
|
buffer_type = cg.uint8 if color_depth == 8 else cg.uint16
|
382
382
|
frac = denominator(config)
|
383
|
-
rotation =
|
383
|
+
rotation = (
|
384
384
|
0 if model.rotation_as_transform(config) else config.get(CONF_ROTATION, 0)
|
385
|
-
|
385
|
+
)
|
386
386
|
templateargs = [
|
387
387
|
buffer_type,
|
388
388
|
bufferpixels,
|
389
389
|
config[CONF_BYTE_ORDER] == "big_endian",
|
390
390
|
display_pixel_mode,
|
391
391
|
bus_type,
|
392
|
-
width,
|
393
|
-
height,
|
394
|
-
offset_width,
|
395
|
-
offset_height,
|
396
392
|
]
|
397
393
|
# If a buffer is required, use MipiSpiBuffer, otherwise use MipiSpi
|
398
394
|
if requires_buffer(config):
|
399
|
-
templateargs.
|
400
|
-
|
395
|
+
templateargs.extend(
|
396
|
+
[
|
397
|
+
width,
|
398
|
+
height,
|
399
|
+
offset_width,
|
400
|
+
offset_height,
|
401
|
+
DISPLAY_ROTATIONS[rotation],
|
402
|
+
frac,
|
403
|
+
]
|
404
|
+
)
|
401
405
|
return MipiSpiBuffer, templateargs
|
406
|
+
# Swap height and width if the display is rotated 90 or 270 degrees in software
|
407
|
+
if rotation in (90, 270):
|
408
|
+
width, height = height, width
|
409
|
+
offset_width, offset_height = offset_height, offset_width
|
410
|
+
templateargs.extend(
|
411
|
+
[
|
412
|
+
width,
|
413
|
+
height,
|
414
|
+
offset_width,
|
415
|
+
offset_height,
|
416
|
+
]
|
417
|
+
)
|
402
418
|
return MipiSpi, templateargs
|
403
419
|
|
404
420
|
|
@@ -340,7 +340,7 @@ class MipiSpi : public display::Display,
|
|
340
340
|
this->write_cmd_addr_data(0, 0, 0, 0, ptr, w * h, 8);
|
341
341
|
}
|
342
342
|
} else {
|
343
|
-
for (size_t y = 0; y != h; y++) {
|
343
|
+
for (size_t y = 0; y != static_cast<size_t>(h); y++) {
|
344
344
|
if constexpr (BUS_TYPE == BUS_TYPE_SINGLE || BUS_TYPE == BUS_TYPE_SINGLE_16) {
|
345
345
|
this->write_array(ptr, w);
|
346
346
|
} else if constexpr (BUS_TYPE == BUS_TYPE_QUAD) {
|
@@ -372,8 +372,8 @@ class MipiSpi : public display::Display,
|
|
372
372
|
uint8_t dbuffer[DISPLAYPIXEL * 48];
|
373
373
|
uint8_t *dptr = dbuffer;
|
374
374
|
auto stride = x_offset + w + x_pad; // stride in pixels
|
375
|
-
for (size_t y = 0; y != h; y++) {
|
376
|
-
for (size_t x = 0; x != w; x++) {
|
375
|
+
for (size_t y = 0; y != static_cast<size_t>(h); y++) {
|
376
|
+
for (size_t x = 0; x != static_cast<size_t>(w); x++) {
|
377
377
|
auto color_val = ptr[y * stride + x];
|
378
378
|
if constexpr (DISPLAYPIXEL == PIXEL_MODE_18 && BUFFERPIXEL == PIXEL_MODE_16) {
|
379
379
|
// 16 to 18 bit conversion
|
@@ -572,7 +572,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|
572
572
|
}
|
573
573
|
} else {
|
574
574
|
// Determine how many frames to mix
|
575
|
-
for (
|
575
|
+
for (size_t i = 0; i < transfer_buffers_with_data.size(); ++i) {
|
576
576
|
const uint32_t frames_available_in_buffer =
|
577
577
|
speakers_with_data[i]->get_audio_stream_info().bytes_to_frames(transfer_buffers_with_data[i]->available());
|
578
578
|
frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
|
@@ -581,7 +581,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|
581
581
|
audio::AudioStreamInfo primary_stream_info = speakers_with_data[0]->get_audio_stream_info();
|
582
582
|
|
583
583
|
// Mix two streams together
|
584
|
-
for (
|
584
|
+
for (size_t i = 1; i < transfer_buffers_with_data.size(); ++i) {
|
585
585
|
mix_audio_samples(primary_buffer, primary_stream_info,
|
586
586
|
reinterpret_cast<int16_t *>(transfer_buffers_with_data[i]->get_buffer_start()),
|
587
587
|
speakers_with_data[i]->get_audio_stream_info(),
|
@@ -596,7 +596,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|
596
596
|
}
|
597
597
|
|
598
598
|
// Update source transfer buffer lengths and add new audio durations to the source speaker pending playbacks
|
599
|
-
for (
|
599
|
+
for (size_t i = 0; i < transfer_buffers_with_data.size(); ++i) {
|
600
600
|
transfer_buffers_with_data[i]->decrease_buffer_length(
|
601
601
|
speakers_with_data[i]->get_audio_stream_info().frames_to_bytes(frames_to_mix));
|
602
602
|
speakers_with_data[i]->pending_playback_frames_ += frames_to_mix;
|
@@ -128,21 +128,21 @@ void MMC5603Component::update() {
|
|
128
128
|
raw_x |= buffer[1] << 4;
|
129
129
|
raw_x |= buffer[2] << 0;
|
130
130
|
|
131
|
-
const float x = 0.
|
131
|
+
const float x = 0.00625 * (raw_x - 524288);
|
132
132
|
|
133
133
|
int32_t raw_y = 0;
|
134
134
|
raw_y |= buffer[3] << 12;
|
135
135
|
raw_y |= buffer[4] << 4;
|
136
136
|
raw_y |= buffer[5] << 0;
|
137
137
|
|
138
|
-
const float y = 0.
|
138
|
+
const float y = 0.00625 * (raw_y - 524288);
|
139
139
|
|
140
140
|
int32_t raw_z = 0;
|
141
141
|
raw_z |= buffer[6] << 12;
|
142
142
|
raw_z |= buffer[7] << 4;
|
143
143
|
raw_z |= buffer[8] << 0;
|
144
144
|
|
145
|
-
const float z = 0.
|
145
|
+
const float z = 0.00625 * (raw_z - 524288);
|
146
146
|
|
147
147
|
const float heading = atan2f(0.0f - x, y) * 180.0f / M_PI;
|
148
148
|
ESP_LOGD(TAG, "Got x=%0.02fµT y=%0.02fµT z=%0.02fµT heading=%0.01f°", x, y, z, heading);
|
@@ -66,7 +66,10 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
|
66
66
|
uint8_t data_offset = 3;
|
67
67
|
|
68
68
|
// Per https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf Ch 5 User-Defined function codes
|
69
|
-
if (((function_code >=
|
69
|
+
if (((function_code >= FUNCTION_CODE_USER_DEFINED_SPACE_1_INIT) &&
|
70
|
+
(function_code <= FUNCTION_CODE_USER_DEFINED_SPACE_1_END)) ||
|
71
|
+
((function_code >= FUNCTION_CODE_USER_DEFINED_SPACE_2_INIT) &&
|
72
|
+
(function_code <= FUNCTION_CODE_USER_DEFINED_SPACE_2_END))) {
|
70
73
|
// Handle user-defined function, since we don't know how big this ought to be,
|
71
74
|
// ideally we should delegate the entire length detection to whatever handler is
|
72
75
|
// installed, but wait, there is the CRC, and if we get a hit there is a good
|
@@ -91,10 +94,14 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
|
91
94
|
} else {
|
92
95
|
// data starts at 2 and length is 4 for read registers commands
|
93
96
|
if (this->role == ModbusRole::SERVER) {
|
94
|
-
if (function_code ==
|
97
|
+
if (function_code == ModbusFunctionCode::READ_COILS ||
|
98
|
+
function_code == ModbusFunctionCode::READ_DISCRETE_INPUTS ||
|
99
|
+
function_code == ModbusFunctionCode::READ_HOLDING_REGISTERS ||
|
100
|
+
function_code == ModbusFunctionCode::READ_INPUT_REGISTERS ||
|
101
|
+
function_code == ModbusFunctionCode::WRITE_SINGLE_REGISTER) {
|
95
102
|
data_offset = 2;
|
96
103
|
data_len = 4;
|
97
|
-
} else if (function_code ==
|
104
|
+
} else if (function_code == ModbusFunctionCode::WRITE_MULTIPLE_REGISTERS) {
|
98
105
|
if (at < 6) {
|
99
106
|
return true;
|
100
107
|
}
|
@@ -104,7 +111,10 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
|
104
111
|
}
|
105
112
|
} else {
|
106
113
|
// the response for write command mirrors the requests and data starts at offset 2 instead of 3 for read commands
|
107
|
-
if (function_code ==
|
114
|
+
if (function_code == ModbusFunctionCode::WRITE_SINGLE_COIL ||
|
115
|
+
function_code == ModbusFunctionCode::WRITE_SINGLE_REGISTER ||
|
116
|
+
function_code == ModbusFunctionCode::WRITE_MULTIPLE_COILS ||
|
117
|
+
function_code == ModbusFunctionCode::WRITE_MULTIPLE_REGISTERS) {
|
108
118
|
data_offset = 2;
|
109
119
|
data_len = 4;
|
110
120
|
}
|
@@ -112,7 +122,7 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
|
112
122
|
|
113
123
|
// Error ( msb indicates error )
|
114
124
|
// response format: Byte[0] = device address, Byte[1] function code | 0x80 , Byte[2] exception code, Byte[3-4] crc
|
115
|
-
if ((function_code &
|
125
|
+
if ((function_code & FUNCTION_CODE_EXCEPTION_MASK) == FUNCTION_CODE_EXCEPTION_MASK) {
|
116
126
|
data_offset = 2;
|
117
127
|
data_len = 1;
|
118
128
|
}
|
@@ -143,10 +153,10 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
|
143
153
|
if (device->address_ == address) {
|
144
154
|
found = true;
|
145
155
|
// Is it an error response?
|
146
|
-
if ((function_code &
|
156
|
+
if ((function_code & FUNCTION_CODE_EXCEPTION_MASK) == FUNCTION_CODE_EXCEPTION_MASK) {
|
147
157
|
ESP_LOGD(TAG, "Modbus error function code: 0x%X exception: %d", function_code, raw[2]);
|
148
158
|
if (waiting_for_response != 0) {
|
149
|
-
device->on_modbus_error(function_code &
|
159
|
+
device->on_modbus_error(function_code & FUNCTION_CODE_MASK, raw[2]);
|
150
160
|
} else {
|
151
161
|
// Ignore modbus exception not related to a pending command
|
152
162
|
ESP_LOGD(TAG, "Ignoring Modbus error - not expecting a response");
|
@@ -154,12 +164,14 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
|
154
164
|
continue;
|
155
165
|
}
|
156
166
|
if (this->role == ModbusRole::SERVER) {
|
157
|
-
if (function_code ==
|
167
|
+
if (function_code == ModbusFunctionCode::READ_HOLDING_REGISTERS ||
|
168
|
+
function_code == ModbusFunctionCode::READ_INPUT_REGISTERS) {
|
158
169
|
device->on_modbus_read_registers(function_code, uint16_t(data[1]) | (uint16_t(data[0]) << 8),
|
159
170
|
uint16_t(data[3]) | (uint16_t(data[2]) << 8));
|
160
171
|
continue;
|
161
172
|
}
|
162
|
-
if (function_code ==
|
173
|
+
if (function_code == ModbusFunctionCode::WRITE_SINGLE_REGISTER ||
|
174
|
+
function_code == ModbusFunctionCode::WRITE_MULTIPLE_REGISTERS) {
|
163
175
|
device->on_modbus_write_registers(function_code, data);
|
164
176
|
continue;
|
165
177
|
}
|
@@ -199,7 +211,7 @@ void Modbus::send(uint8_t address, uint8_t function_code, uint16_t start_address
|
|
199
211
|
|
200
212
|
// Only check max number of registers for standard function codes
|
201
213
|
// Some devices use non standard codes like 0x43
|
202
|
-
if (number_of_entities > MAX_VALUES && function_code <=
|
214
|
+
if (number_of_entities > MAX_VALUES && function_code <= ModbusFunctionCode::WRITE_MULTIPLE_REGISTERS) {
|
203
215
|
ESP_LOGE(TAG, "send too many values %d max=%zu", number_of_entities, MAX_VALUES);
|
204
216
|
return;
|
205
217
|
}
|
@@ -210,15 +222,17 @@ void Modbus::send(uint8_t address, uint8_t function_code, uint16_t start_address
|
|
210
222
|
if (this->role == ModbusRole::CLIENT) {
|
211
223
|
data.push_back(start_address >> 8);
|
212
224
|
data.push_back(start_address >> 0);
|
213
|
-
if (function_code !=
|
225
|
+
if (function_code != ModbusFunctionCode::WRITE_SINGLE_COIL &&
|
226
|
+
function_code != ModbusFunctionCode::WRITE_SINGLE_REGISTER) {
|
214
227
|
data.push_back(number_of_entities >> 8);
|
215
228
|
data.push_back(number_of_entities >> 0);
|
216
229
|
}
|
217
230
|
}
|
218
231
|
|
219
232
|
if (payload != nullptr) {
|
220
|
-
if (this->role == ModbusRole::SERVER || function_code ==
|
221
|
-
|
233
|
+
if (this->role == ModbusRole::SERVER || function_code == ModbusFunctionCode::WRITE_MULTIPLE_COILS ||
|
234
|
+
function_code == ModbusFunctionCode::WRITE_MULTIPLE_REGISTERS) { // Write multiple
|
235
|
+
data.push_back(payload_len); // Byte count is required for write
|
222
236
|
} else {
|
223
237
|
payload_len = 2; // Write single register or coil
|
224
238
|
}
|
@@ -3,6 +3,8 @@
|
|
3
3
|
#include "esphome/core/component.h"
|
4
4
|
#include "esphome/components/uart/uart.h"
|
5
5
|
|
6
|
+
#include "esphome/components/modbus/modbus_definitions.h"
|
7
|
+
|
6
8
|
#include <vector>
|
7
9
|
|
8
10
|
namespace esphome {
|
@@ -65,12 +67,12 @@ class ModbusDevice {
|
|
65
67
|
this->parent_->send(this->address_, function, start_address, number_of_entities, payload_len, payload);
|
66
68
|
}
|
67
69
|
void send_raw(const std::vector<uint8_t> &payload) { this->parent_->send_raw(payload); }
|
68
|
-
void send_error(uint8_t function_code,
|
70
|
+
void send_error(uint8_t function_code, ModbusExceptionCode exception_code) {
|
69
71
|
std::vector<uint8_t> error_response;
|
70
72
|
error_response.reserve(3);
|
71
73
|
error_response.push_back(this->address_);
|
72
|
-
error_response.push_back(function_code |
|
73
|
-
error_response.push_back(exception_code);
|
74
|
+
error_response.push_back(function_code | FUNCTION_CODE_EXCEPTION_MASK);
|
75
|
+
error_response.push_back(static_cast<uint8_t>(exception_code));
|
74
76
|
this->send_raw(error_response);
|
75
77
|
}
|
76
78
|
// If more than one device is connected block sending a new command before a response is received
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/core/component.h"
|
4
|
+
|
5
|
+
namespace esphome {
|
6
|
+
namespace modbus {
|
7
|
+
|
8
|
+
/// Modbus definitions from specs:
|
9
|
+
/// https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf
|
10
|
+
// 5 Function Code Categories
|
11
|
+
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_1_INIT = 65; // 0x41
|
12
|
+
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_1_END = 72; // 0x48
|
13
|
+
|
14
|
+
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_2_INIT = 100; // 0x64
|
15
|
+
const uint8_t FUNCTION_CODE_USER_DEFINED_SPACE_2_END = 110; // 0x6E
|
16
|
+
|
17
|
+
enum class ModbusFunctionCode : uint8_t {
|
18
|
+
CUSTOM = 0x00,
|
19
|
+
READ_COILS = 0x01,
|
20
|
+
READ_DISCRETE_INPUTS = 0x02,
|
21
|
+
READ_HOLDING_REGISTERS = 0x03,
|
22
|
+
READ_INPUT_REGISTERS = 0x04,
|
23
|
+
WRITE_SINGLE_COIL = 0x05,
|
24
|
+
WRITE_SINGLE_REGISTER = 0x06,
|
25
|
+
READ_EXCEPTION_STATUS = 0x07, // not implemented
|
26
|
+
DIAGNOSTICS = 0x08, // not implemented
|
27
|
+
GET_COMM_EVENT_COUNTER = 0x0B, // not implemented
|
28
|
+
GET_COMM_EVENT_LOG = 0x0C, // not implemented
|
29
|
+
WRITE_MULTIPLE_COILS = 0x0F,
|
30
|
+
WRITE_MULTIPLE_REGISTERS = 0x10,
|
31
|
+
REPORT_SERVER_ID = 0x11, // not implemented
|
32
|
+
READ_FILE_RECORD = 0x14, // not implemented
|
33
|
+
WRITE_FILE_RECORD = 0x15, // not implemented
|
34
|
+
MASK_WRITE_REGISTER = 0x16, // not implemented
|
35
|
+
READ_WRITE_MULTIPLE_REGISTERS = 0x17, // not implemented
|
36
|
+
READ_FIFO_QUEUE = 0x18, // not implemented
|
37
|
+
};
|
38
|
+
|
39
|
+
/*Allow comparison operators between ModbusFunctionCode and uint8_t*/
|
40
|
+
inline bool operator==(ModbusFunctionCode lhs, uint8_t rhs) { return static_cast<uint8_t>(lhs) == rhs; }
|
41
|
+
inline bool operator==(uint8_t lhs, ModbusFunctionCode rhs) { return lhs == static_cast<uint8_t>(rhs); }
|
42
|
+
inline bool operator!=(ModbusFunctionCode lhs, uint8_t rhs) { return !(static_cast<uint8_t>(lhs) == rhs); }
|
43
|
+
inline bool operator!=(uint8_t lhs, ModbusFunctionCode rhs) { return !(lhs == static_cast<uint8_t>(rhs)); }
|
44
|
+
inline bool operator<(ModbusFunctionCode lhs, uint8_t rhs) { return static_cast<uint8_t>(lhs) < rhs; }
|
45
|
+
inline bool operator<(uint8_t lhs, ModbusFunctionCode rhs) { return lhs < static_cast<uint8_t>(rhs); }
|
46
|
+
inline bool operator<=(ModbusFunctionCode lhs, uint8_t rhs) { return static_cast<uint8_t>(lhs) <= rhs; }
|
47
|
+
inline bool operator<=(uint8_t lhs, ModbusFunctionCode rhs) { return lhs <= static_cast<uint8_t>(rhs); }
|
48
|
+
inline bool operator>(ModbusFunctionCode lhs, uint8_t rhs) { return static_cast<uint8_t>(lhs) > rhs; }
|
49
|
+
inline bool operator>(uint8_t lhs, ModbusFunctionCode rhs) { return lhs > static_cast<uint8_t>(rhs); }
|
50
|
+
inline bool operator>=(ModbusFunctionCode lhs, uint8_t rhs) { return static_cast<uint8_t>(lhs) >= rhs; }
|
51
|
+
inline bool operator>=(uint8_t lhs, ModbusFunctionCode rhs) { return lhs >= static_cast<uint8_t>(rhs); }
|
52
|
+
|
53
|
+
// 4.3 MODBUS Data model
|
54
|
+
enum class ModbusRegisterType : uint8_t {
|
55
|
+
CUSTOM = 0x00,
|
56
|
+
COIL = 0x01,
|
57
|
+
DISCRETE_INPUT = 0x02,
|
58
|
+
HOLDING = 0x03,
|
59
|
+
READ = 0x04,
|
60
|
+
};
|
61
|
+
|
62
|
+
// 7 MODBUS Exception Responses:
|
63
|
+
const uint8_t FUNCTION_CODE_MASK = 0x7F;
|
64
|
+
const uint8_t FUNCTION_CODE_EXCEPTION_MASK = 0x80;
|
65
|
+
|
66
|
+
enum class ModbusExceptionCode : uint8_t {
|
67
|
+
ILLEGAL_FUNCTION = 0x01,
|
68
|
+
ILLEGAL_DATA_ADDRESS = 0x02,
|
69
|
+
ILLEGAL_DATA_VALUE = 0x03,
|
70
|
+
SERVICE_DEVICE_FAILURE = 0x04,
|
71
|
+
ACKNOWLEDGE = 0x05,
|
72
|
+
SERVER_DEVICE_BUSY = 0x06,
|
73
|
+
MEMORY_PARITY_ERROR = 0x08,
|
74
|
+
GATEWAY_PATH_UNAVAILABLE = 0x0A,
|
75
|
+
GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 0x0B,
|
76
|
+
};
|
77
|
+
|
78
|
+
// 6.12 16 (0x10) Write Multiple registers:
|
79
|
+
const uint8_t MAX_NUM_OF_REGISTERS_TO_WRITE = 123; // 0x7B
|
80
|
+
|
81
|
+
// 6.3 03 (0x03) Read Holding Registers
|
82
|
+
// 6.4 04 (0x04) Read Input Registers
|
83
|
+
const uint8_t MAX_NUM_OF_REGISTERS_TO_READ = 125; // 0x7D
|
84
|
+
/// End of Modbus definitions
|
85
|
+
} // namespace modbus
|
86
|
+
} // namespace esphome
|
@@ -20,6 +20,7 @@ from .const import (
|
|
20
20
|
CONF_BYTE_OFFSET,
|
21
21
|
CONF_COMMAND_THROTTLE,
|
22
22
|
CONF_CUSTOM_COMMAND,
|
23
|
+
CONF_ENABLED,
|
23
24
|
CONF_FORCE_NEW_RANGE,
|
24
25
|
CONF_MAX_CMD_RETRIES,
|
25
26
|
CONF_MODBUS_CONTROLLER_ID,
|
@@ -28,8 +29,11 @@ from .const import (
|
|
28
29
|
CONF_ON_OFFLINE,
|
29
30
|
CONF_ON_ONLINE,
|
30
31
|
CONF_REGISTER_COUNT,
|
32
|
+
CONF_REGISTER_LAST_ADDRESS,
|
31
33
|
CONF_REGISTER_TYPE,
|
34
|
+
CONF_REGISTER_VALUE,
|
32
35
|
CONF_RESPONSE_SIZE,
|
36
|
+
CONF_SERVER_COURTESY_RESPONSE,
|
33
37
|
CONF_SKIP_UPDATES,
|
34
38
|
CONF_VALUE_TYPE,
|
35
39
|
)
|
@@ -49,6 +53,7 @@ ModbusController = modbus_controller_ns.class_(
|
|
49
53
|
)
|
50
54
|
|
51
55
|
SensorItem = modbus_controller_ns.struct("SensorItem")
|
56
|
+
ServerCourtesyResponse = modbus_controller_ns.struct("ServerCourtesyResponse")
|
52
57
|
ServerRegister = modbus_controller_ns.struct("ServerRegister")
|
53
58
|
|
54
59
|
ModbusFunctionCode_ns = modbus_controller_ns.namespace("ModbusFunctionCode")
|
@@ -143,6 +148,14 @@ ModbusOfflineTrigger = modbus_controller_ns.class_(
|
|
143
148
|
|
144
149
|
_LOGGER = logging.getLogger(__name__)
|
145
150
|
|
151
|
+
SERVER_COURTESY_RESPONSE_SCHEMA = cv.Schema(
|
152
|
+
{
|
153
|
+
cv.Optional(CONF_ENABLED, default=False): cv.boolean,
|
154
|
+
cv.Optional(CONF_REGISTER_LAST_ADDRESS, default=0xFFFF): cv.hex_uint16_t,
|
155
|
+
cv.Optional(CONF_REGISTER_VALUE, default=0): cv.hex_uint16_t,
|
156
|
+
}
|
157
|
+
)
|
158
|
+
|
146
159
|
ModbusServerRegisterSchema = cv.Schema(
|
147
160
|
{
|
148
161
|
cv.GenerateID(): cv.declare_id(ServerRegister),
|
@@ -162,6 +175,7 @@ CONFIG_SCHEMA = cv.All(
|
|
162
175
|
cv.Optional(
|
163
176
|
CONF_COMMAND_THROTTLE, default="0ms"
|
164
177
|
): cv.positive_time_period_milliseconds,
|
178
|
+
cv.Optional(CONF_SERVER_COURTESY_RESPONSE): SERVER_COURTESY_RESPONSE_SCHEMA,
|
165
179
|
cv.Optional(CONF_MAX_CMD_RETRIES, default=4): cv.positive_int,
|
166
180
|
cv.Optional(CONF_OFFLINE_SKIP_UPDATES, default=0): cv.positive_int,
|
167
181
|
cv.Optional(
|
@@ -232,7 +246,7 @@ def validate_modbus_register(config):
|
|
232
246
|
|
233
247
|
|
234
248
|
def _final_validate(config):
|
235
|
-
if CONF_SERVER_REGISTERS in config:
|
249
|
+
if CONF_SERVER_COURTESY_RESPONSE in config or CONF_SERVER_REGISTERS in config:
|
236
250
|
return modbus.final_validate_modbus_device("modbus_controller", role="server")(
|
237
251
|
config
|
238
252
|
)
|
@@ -299,6 +313,20 @@ async def to_code(config):
|
|
299
313
|
var = cg.new_Pvariable(config[CONF_ID])
|
300
314
|
cg.add(var.set_allow_duplicate_commands(config[CONF_ALLOW_DUPLICATE_COMMANDS]))
|
301
315
|
cg.add(var.set_command_throttle(config[CONF_COMMAND_THROTTLE]))
|
316
|
+
if server_courtesy_response := config.get(CONF_SERVER_COURTESY_RESPONSE):
|
317
|
+
cg.add(
|
318
|
+
var.set_server_courtesy_response(
|
319
|
+
cg.StructInitializer(
|
320
|
+
ServerCourtesyResponse,
|
321
|
+
("enabled", server_courtesy_response[CONF_ENABLED]),
|
322
|
+
(
|
323
|
+
"register_last_address",
|
324
|
+
server_courtesy_response[CONF_REGISTER_LAST_ADDRESS],
|
325
|
+
),
|
326
|
+
("register_value", server_courtesy_response[CONF_REGISTER_VALUE]),
|
327
|
+
)
|
328
|
+
)
|
329
|
+
)
|
302
330
|
cg.add(var.set_max_cmd_retries(config[CONF_MAX_CMD_RETRIES]))
|
303
331
|
cg.add(var.set_offline_skip_updates(config[CONF_OFFLINE_SKIP_UPDATES]))
|
304
332
|
if CONF_SERVER_REGISTERS in config:
|
@@ -2,6 +2,7 @@ CONF_ALLOW_DUPLICATE_COMMANDS = "allow_duplicate_commands"
|
|
2
2
|
CONF_BITMASK = "bitmask"
|
3
3
|
CONF_BYTE_OFFSET = "byte_offset"
|
4
4
|
CONF_COMMAND_THROTTLE = "command_throttle"
|
5
|
+
CONF_ENABLED = "enabled"
|
5
6
|
CONF_OFFLINE_SKIP_UPDATES = "offline_skip_updates"
|
6
7
|
CONF_CUSTOM_COMMAND = "custom_command"
|
7
8
|
CONF_FORCE_NEW_RANGE = "force_new_range"
|
@@ -13,8 +14,11 @@ CONF_ON_ONLINE = "on_online"
|
|
13
14
|
CONF_ON_OFFLINE = "on_offline"
|
14
15
|
CONF_RAW_ENCODE = "raw_encode"
|
15
16
|
CONF_REGISTER_COUNT = "register_count"
|
17
|
+
CONF_REGISTER_LAST_ADDRESS = "register_last_address"
|
16
18
|
CONF_REGISTER_TYPE = "register_type"
|
19
|
+
CONF_REGISTER_VALUE = "register_value"
|
17
20
|
CONF_RESPONSE_SIZE = "response_size"
|
21
|
+
CONF_SERVER_COURTESY_RESPONSE = "server_courtesy_response"
|
18
22
|
CONF_SKIP_UPDATES = "skip_updates"
|
19
23
|
CONF_USE_WRITE_MULTIPLE = "use_write_multiple"
|
20
24
|
CONF_VALUE_TYPE = "value_type"
|