diff --git a/Doxygen b/Doxygen
index f41527f96..3fad571e1 100644
--- a/Doxygen
+++ b/Doxygen
@@ -38,7 +38,7 @@ PROJECT_NAME           = "ESPHome"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 2021.11.4
+PROJECT_NUMBER         = 2021.12.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/Makefile b/Makefile
index f0de3646d..db1b4fe08 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 ESPHOME_PATH = ../esphome
-ESPHOME_REF = 2021.11.4
+ESPHOME_REF = 2021.12.0
 
 .PHONY: html html-strict cleanhtml deploy help webserver Makefile netlify netlify-api api netlify-dependencies svg2png copy-svg2png minify
 
diff --git a/_static/changelog-2021.12.0.png b/_static/changelog-2021.12.0.png
new file mode 100644
index 000000000..69b0a6659
Binary files /dev/null and b/_static/changelog-2021.12.0.png differ
diff --git a/_static/version b/_static/version
index ff01a93a5..acbbb4230 100644
--- a/_static/version
+++ b/_static/version
@@ -1 +1 @@
-2021.11.4
\ No newline at end of file
+2021.12.0
\ No newline at end of file
diff --git a/changelog/2021.12.0.rst b/changelog/2021.12.0.rst
new file mode 100644
index 000000000..a4158b689
--- /dev/null
+++ b/changelog/2021.12.0.rst
@@ -0,0 +1,265 @@
+ESPHome 2021.12.0 - 11th December 2021
+======================================
+
+.. seo::
+    :description: Changelog for ESPHome 2021.12.0.
+    :image: /_static/changelog-2021.12.0.png
+    :author: ESPHome
+    :author_twitter: @esphome_
+
+.. imgtable::
+    :columns: 3
+
+    Button Core, components/button/index, folder-open.svg
+    Template Button, components/button/template, description.svg
+    Restart Button, components/button/restart, restart.svg
+    BLE Binary Output, components/output/ble_client, bluetooth.svg
+    Tuya Text Sensor, components/text_sensor/tuya, tuya.png
+    SDP800 Series, components/sensor/sdp3x, sdp31.jpg, Pressure
+
+
+State of the Open Smart Home
+----------------------------
+
+Today is the `State of the Open Smart Home <https://www.home-assistant.io/state-of-the-open-home/>`__ hosted by Nabu Casa, Home Assistant & ESPHome
+and we’ll be joined by our friends from WLED, Z-Wave JS, Stanford’s OVAL lab and Northeastern University to talk about our work on making this vision a reality.
+
+Where: YouTube
+
+When: Today, Saturday, December 11, at 11am PST / 8pm CET
+
+.. raw:: html
+
+    <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/6ZMXE5PXPqU"
+            title="YouTube video player" frameborder="0"
+            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
+            allowfullscreen>
+    </iframe>
+
+Buttons
+-------
+
+This release brings :doc:`buttons </components/button/index>` from Home Assistant. Many times there have been questions on how to simply trigger automations
+from the Home Assistant frontend with a button so here you go. Here is a very simple example:
+
+.. code:: yaml
+
+    button:
+      - platform: template
+        name: Test Button
+        on_press:
+          then:
+            - logger.log: "The button was pressed!!!"
+
+Multiple WiFi networks with static IP
+-------------------------------------
+
+This release has a fix that allows using multiple networks each with their own static IP address configuration.
+When using these options, you **must** also set ``wifi`` -> ``use_address`` when installing new firmware as ESPHome
+cannot know which IP address to use automatically.
+
+The Dashboard and secrets
+-------------------------
+
+The ESPHome Dashboard will now save the wifi credentials as secrets (``wifi_ssid`` / ``wifi_password``) for future use. If you are already using these secrets,
+then the dashboard will not ask for credentials and will configure using them for you.
+
+The dashboard also now can view the logs straight from a serial connected device via the web browser. It will show up as an option when choosing the method to
+view them.
+
+NEC remote protocol
+-------------------
+
+In this version, the order of transferring bits was corrected from MSB to LSB in accordance with the NEC standard.
+Therefore, if the the configuration file has come from an earlier version of ESPhome, it is necessary to reverse
+the order of the address and command bits when moving to 2021.12 or above.
+For example, address: ``0x84ED``, command: ``0x13EC`` becomes ``0xB721`` and ``0x37C8`` respectively.
+
+Tuya Covers
+-----------
+
+:esphomepr:`2637` adds new functionality to the Tuya cover component, but at the same time removes the "soft"
+inversion of the direction. Instead, it seems that most if not all tuya covers have a "hidden" datapoint that
+sets the direction on the secondary MCU. See the :doc:`documentation </components/cover/tuya>` for the new
+configuration options.
+
+
+Full list of changes
+--------------------
+
+New Features
+^^^^^^^^^^^^
+
+- pmsx003: add support for new PMS5003S device :esphomepr:`2710` by :ghuser:`NeoAcheron` (new-feature)
+- Add climate on_state trigger :esphomepr:`2707` by :ghuser:`dudanov` (new-feature)
+- Add greeyac protocol to IR Climate / HeatpumpIR :esphomepr:`2694` by :ghuser:`cmroche` (new-feature)
+- Provide an option to select unique_id generator :esphomepr:`2701` by :ghuser:`kbialek` (new-feature)
+- Ignore secrets yaml on command line :esphomepr:`2715` by :ghuser:`cvwillegen` (new-feature)
+- Add max_telegram_length option to dsmr :esphomepr:`2674` by :ghuser:`mmakaay` (new-feature)
+- Relax the icon validator to allow non-mdi icons :esphomepr:`2764` by :ghuser:`paulmonigatti` (new-feature)
+- Add support for P1 Data Request pin control :esphomepr:`2676` by :ghuser:`mmakaay` (new-feature)
+- Add support for sdp8xx :esphomepr:`2779` by :ghuser:`martgras` (new-feature)
+- Add map filter for text sensors :esphomepr:`2761` by :ghuser:`oxan` (new-feature)
+- Optionally show internal components on the web server :esphomepr:`2627` by :ghuser:`mechanarchy` (new-feature)
+- cse7766: add energy sensor :esphomepr:`2822` by :ghuser:`ianchi` (new-feature)
+- Allow Git credentials to be loaded from secrets :esphomepr:`2825` by :ghuser:`mechanarchy` (new-feature)
+- Expand uart invert feature to ESP8266 :esphomepr:`1727` by :ghuser:`Lewn` (new-feature)
+
+New Components
+^^^^^^^^^^^^^^
+
+- Add ble_client binary_output :esphomepr:`2200` by :ghuser:`tekmaven` (new-integration)
+- Add support for button entities :esphomepr:`2824` by :ghuser:`jesserockz` (new-integration)
+
+Breaking Changes
+^^^^^^^^^^^^^^^^
+
+- Fix NEC protocol implementation :esphomepr:`2534` by :ghuser:`dudanov` (breaking-change)
+- Tuya Cover improvements :esphomepr:`2637` by :ghuser:`pauln` (breaking-change)
+
+Beta Changes
+^^^^^^^^^^^^
+
+- Feed watchdog during OTA :esphomepr:`2852` by :ghuser:`oxan`
+- Bump esphome-dashboard to 20211206.0 :esphomepr:`2870` by :ghuser:`jesserockz`
+- tlc59208f : fix compilation error :esphomepr:`2867` by :ghuser:`martgras`
+- ADC: Turn verbose the debugging "got voltage" :esphomepr:`2863` by :ghuser:`CarlosGS`
+- SPS30 : fix i2c read size :esphomepr:`2866` by :ghuser:`martgras`
+- Fix MCP23x17 not disabling pullup after config change :esphomepr:`2855` by :ghuser:`oxan`
+- Ignore already stopped dhcp for ethernet :esphomepr:`2862` by :ghuser:`madron`
+- Add endpoint to fetch secrets keys :esphomepr:`2873` by :ghuser:`jesserockz`
+- Adopt using wifi secrets that should exist at this point :esphomepr:`2874` by :ghuser:`jesserockz`
+- Allow wizard to specify secrets :esphomepr:`2875` by :ghuser:`jesserockz`
+- Feed watchdog when no component loops :esphomepr:`2857` by :ghuser:`oxan`
+- Bump esphome-dashboard to 20211207.0 :esphomepr:`2877` by :ghuser:`jesserockz`
+- Feed watchdog while setting up OTA :esphomepr:`2876` by :ghuser:`CarlosGS`
+- Use new platform component config blocks for wizard :esphomepr:`2885` by :ghuser:`jesserockz`
+- Bump esphome-dashboard to 20211208.0 :esphomepr:`2887` by :ghuser:`jesserockz`
+- Fix published state for modbus number :esphomepr:`2894` by :ghuser:`jesserockz`
+- Modbus number/output use write single :esphomepr:`2896` by :ghuser:`glmnet`
+- Fix for two points setting when fan_only_cooling is disabled :esphomepr:`2903` by :ghuser:`kbx81`
+- Bump esphome-dashboard to 20211211.0 :esphomepr:`2904` by :ghuser:`jesserockz`
+
+All changes
+^^^^^^^^^^^
+
+- Defines tidy :esphomepr:`2696` by :ghuser:`jesserockz`
+- pmsx003: add support for new PMS5003S device :esphomepr:`2710` by :ghuser:`NeoAcheron` (new-feature)
+- Add climate on_state trigger :esphomepr:`2707` by :ghuser:`dudanov` (new-feature)
+- Add greeyac protocol to IR Climate / HeatpumpIR :esphomepr:`2694` by :ghuser:`cmroche` (new-feature)
+- Fix rom/rtc.h deprecation compile warning for debug component :esphomepr:`2520` by :ghuser:`mmakaay`
+- Drop unused constants from const.py :esphomepr:`2718` by :ghuser:`oxan`
+- Install test requirements in lint Docker image :esphomepr:`2719` by :ghuser:`oxan`
+- Clean-up MAC address helpers :esphomepr:`2713` by :ghuser:`oxan`
+- Provide an option to select unique_id generator :esphomepr:`2701` by :ghuser:`kbialek` (new-feature)
+- Ignore secrets yaml on command line :esphomepr:`2715` by :ghuser:`cvwillegen` (new-feature)
+- Allow for subsecond sampling of hmc5883l :esphomepr:`2735` by :ghuser:`jaharkes`
+- Change log level from DEBUG to INFO for sniffing services of `rf_bridge` :esphomepr:`2736` by :ghuser:`nagyrobi`
+- Add ble_client binary_output :esphomepr:`2200` by :ghuser:`tekmaven` (new-integration)
+- Remove duplicated const data in esp8266 boards :esphomepr:`2740` by :ghuser:`jesserockz`
+- Move to use improv lib from platformio :esphomepr:`2741` by :ghuser:`jesserockz`
+- Add max_telegram_length option to dsmr :esphomepr:`2674` by :ghuser:`mmakaay` (new-feature)
+- Changed LUT for DKE epaper on ttgo t5 2.13inch to improve partial rfresh :esphomepr:`2475` by :ghuser:`spattinson`
+- Fix NEC protocol implementation :esphomepr:`2534` by :ghuser:`dudanov` (breaking-change)
+- Remove arduino dependency from hm3301 :esphomepr:`2745` by :ghuser:`martgras`
+- Add retry handler :esphomepr:`2721` by :ghuser:`martgras`
+- Introduce str_snprintf helper function :esphomepr:`2780` by :ghuser:`oxan`
+- Prettier date time display after time sync :esphomepr:`2778` by :ghuser:`cvwillegen`
+- Fix distorted gif frames when resizing :esphomepr:`2774` by :ghuser:`davet2001`
+- fixed wrong setup-usage tc9548a :esphomepr:`2766` by :ghuser:`andreashergert1984`
+- Relax the icon validator to allow non-mdi icons :esphomepr:`2764` by :ghuser:`paulmonigatti` (new-feature)
+- Bump black from 21.10b0 to 21.11b1 :esphomepr:`2760` by :ghuser:`dependabot[bot]`
+- Update aht10.cpp to address issue #1635 :esphomepr:`2675` by :ghuser:`krunkel`
+- Add support for P1 Data Request pin control :esphomepr:`2676` by :ghuser:`mmakaay` (new-feature)
+- Allow specifying the dashboard bind address :esphomepr:`2787` by :ghuser:`jesserockz`
+- remove LEDC_HIGH_SPEED_MODE for C3, S2, S3 :esphomepr:`2791` by :ghuser:`martgras`
+- Fix LEDC resolution calculation on ESP32-C3/S2/S3 :esphomepr:`2794` by :ghuser:`rsumner`
+- Add support for sdp8xx :esphomepr:`2779` by :ghuser:`martgras` (new-feature)
+- Allow empty UART debug: option, logging in hex format by default :esphomepr:`2771` by :ghuser:`mmakaay`
+- Bump pylint from 2.11.1 to 2.12.1 :esphomepr:`2798` by :ghuser:`dependabot[bot]`
+- Fix CI cache key for test3.yaml compile :esphomepr:`2757` by :ghuser:`oxan`
+- Drop obsolete comment from CI workflow file :esphomepr:`2758` by :ghuser:`oxan`
+- Cache virtualenv instead of pip cache between CI runs :esphomepr:`2759` by :ghuser:`oxan`
+- Add map filter for text sensors :esphomepr:`2761` by :ghuser:`oxan` (new-feature)
+- Only match GCC warnings from ESPHome source files in CI :esphomepr:`2756` by :ghuser:`oxan`
+- Correct constant for dynamic I2S bus in NeoPixelBus :esphomepr:`2797` by :ghuser:`oxan`
+- Consistently format errors in CI scripts  :esphomepr:`2762` by :ghuser:`oxan`
+- Cancel previous workflows for PRs and branches :esphomepr:`2800` by :ghuser:`jesserockz`
+- total_daily_energy: allow to disable restore mode :esphomepr:`2795` by :ghuser:`ianchi`
+- Modbus_controller: Add custom command. :esphomepr:`2680` by :ghuser:`martgras`
+- Fix usage of deprecated climate method in anova :esphomepr:`2801` by :ghuser:`oxan`
+- Make clang-tidy suggest stdint.h int types :esphomepr:`2820` by :ghuser:`oxan`
+- Fixed data type inside fast_random_8() routine :esphomepr:`2818` by :ghuser:`anatoly-savchenkov`
+- Improve DSMR read timeout handling :esphomepr:`2699` by :ghuser:`mmakaay`
+- Optionally show internal components on the web server :esphomepr:`2627` by :ghuser:`mechanarchy` (new-feature)
+- Fix custom mode_state_topic :esphomepr:`2827` by :ghuser:`definitio`
+- Add support for button entities :esphomepr:`2824` by :ghuser:`jesserockz` (new-integration)
+- Tuya text_sensor and raw data usage :esphomepr:`1812` by :ghuser:`dentra`
+- Fix 8266 SPI Clock Polarity Setting :esphomepr:`2836` by :ghuser:`kbx81`
+- Fix too-broad matcher for custom CI script :esphomepr:`2829` by :ghuser:`oxan`
+- cse7766: add energy sensor :esphomepr:`2822` by :ghuser:`ianchi` (new-feature)
+- Burst read for BME280, to reduce spurious spikes :esphomepr:`2809` by :ghuser:`CarlosGS`
+- Bump aioesphomeapi from 10.2.0 to 10.6.0 :esphomepr:`2840` by :ghuser:`dependabot[bot]`
+- Button device class :esphomepr:`2835` by :ghuser:`jesserockz`
+- Implement unit_of_measurement for number component :esphomepr:`2804` by :ghuser:`puuu`
+- Number mode :esphomepr:`2838` by :ghuser:`jesserockz`
+- Bump esphome-dashboard to 20211201.0 :esphomepr:`2842` by :ghuser:`jesserockz`
+- Allow Git credentials to be loaded from secrets :esphomepr:`2825` by :ghuser:`mechanarchy` (new-feature)
+- Fix compile warning in Tuya automations :esphomepr:`2837` by :ghuser:`oxan`
+- Add problem matcher for Python formatting errors :esphomepr:`2833` by :ghuser:`oxan`
+- Fix CI check for Windows line endings :esphomepr:`2831` by :ghuser:`oxan`
+- Don't enable namespace comment clang-tidy check twice :esphomepr:`2830` by :ghuser:`oxan`
+- ESP32 Deep Sleep: correct level value :esphomepr:`2812` by :ghuser:`jhamhader`
+- Fix OTA updates on esp8266 by declaring arch_get_cpu_cycle_count IRAM_ATTR and HOT :esphomepr:`2843` by :ghuser:`Doridian`
+- Fix compilation using subprocesses :esphomepr:`2834` by :ghuser:`oxan`
+- Expand uart invert feature to ESP8266 :esphomepr:`1727` by :ghuser:`Lewn` (new-feature)
+- Support setting manual_ip under networks option :esphomepr:`2839` by :ghuser:`oxan`
+- Enable a bunch of clang-tidy checks :esphomepr:`2149` by :ghuser:`oxan`
+- Set ESP32 watchdog to loop task  :esphomepr:`2846` by :ghuser:`oxan`
+- Tuya Cover improvements :esphomepr:`2637` by :ghuser:`pauln` (breaking-change)
+- Fix wifi not working with manual_ip using esp-idf :esphomepr:`2849` by :ghuser:`Maelstrom96`
+- modbus_controller: bugfix: enable overriding calculated register size :esphomepr:`2845` by :ghuser:`martgras`
+- Feed watchdog during OTA :esphomepr:`2852` by :ghuser:`oxan`
+- Bump esphome-dashboard to 20211206.0 :esphomepr:`2870` by :ghuser:`jesserockz`
+- tlc59208f : fix compilation error :esphomepr:`2867` by :ghuser:`martgras`
+- ADC: Turn verbose the debugging "got voltage" :esphomepr:`2863` by :ghuser:`CarlosGS`
+- SPS30 : fix i2c read size :esphomepr:`2866` by :ghuser:`martgras`
+- Fix MCP23x17 not disabling pullup after config change :esphomepr:`2855` by :ghuser:`oxan`
+- Ignore already stopped dhcp for ethernet :esphomepr:`2862` by :ghuser:`madron`
+- Add endpoint to fetch secrets keys :esphomepr:`2873` by :ghuser:`jesserockz`
+- Adopt using wifi secrets that should exist at this point :esphomepr:`2874` by :ghuser:`jesserockz`
+- Allow wizard to specify secrets :esphomepr:`2875` by :ghuser:`jesserockz`
+- Feed watchdog when no component loops :esphomepr:`2857` by :ghuser:`oxan`
+- Bump esphome-dashboard to 20211207.0 :esphomepr:`2877` by :ghuser:`jesserockz`
+- Feed watchdog while setting up OTA :esphomepr:`2876` by :ghuser:`CarlosGS`
+- Use new platform component config blocks for wizard :esphomepr:`2885` by :ghuser:`jesserockz`
+- Bump esphome-dashboard to 20211208.0 :esphomepr:`2887` by :ghuser:`jesserockz`
+- Fix published state for modbus number :esphomepr:`2894` by :ghuser:`jesserockz`
+- Modbus number/output use write single :esphomepr:`2896` by :ghuser:`glmnet`
+- Fix for two points setting when fan_only_cooling is disabled :esphomepr:`2903` by :ghuser:`kbx81`
+- Bump esphome-dashboard to 20211211.0 :esphomepr:`2904` by :ghuser:`jesserockz`
+
+Past Changelogs
+---------------
+
+.. toctree::
+    :maxdepth: 1
+
+    2021.11.0
+    2021.10.0
+    2021.9.0
+    2021.8.0
+    v1.20.0
+    v1.19.0
+    v1.18.0
+    v1.17.0
+    v1.16.0
+    v1.15.0
+    v1.14.0
+    v1.13.0
+    v1.12.0
+    v1.11.0
+    v1.10.0
+    v1.9.0
+    v1.8.0
+    v1.7.0
diff --git a/changelog/index.rst b/changelog/index.rst
index c3815151c..5691d5838 100644
--- a/changelog/index.rst
+++ b/changelog/index.rst
@@ -2,7 +2,7 @@ Changelog
 =========
 
 .. redirect::
-    :url: /changelog/2021.11.0.html
+    :url: /changelog/2021.12.0.html
 
 .. toctree::
     :glob:
diff --git a/components/api.rst b/components/api.rst
index 781534074..aa4628e21 100644
--- a/components/api.rst
+++ b/components/api.rst
@@ -3,7 +3,7 @@ Native API Component
 
 .. seo::
     :description: Instructions for setting up the native ESPHome API for communication with Home Assistant.
-    :image: server-network.png
+    :image: server-network.svg
     :keywords: Native API, ESPHome, Home Assistant
 
 The ESPHome native API is used to communicate with clients directly, with a highly-optimized
diff --git a/components/binary_sensor/ble_presence.rst b/components/binary_sensor/ble_presence.rst
index ab6f35268..60d53f7cf 100644
--- a/components/binary_sensor/ble_presence.rst
+++ b/components/binary_sensor/ble_presence.rst
@@ -3,7 +3,7 @@ ESP32 Bluetooth Low Energy Device
 
 .. seo::
     :description: Instructions for setting up BLE binary sensors for the ESP32.
-    :image: bluetooth.png
+    :image: bluetooth.svg
 
 The ``ble_presence`` binary sensor platform lets you track the presence of a
 Bluetooth Low Energy device.
diff --git a/components/binary_sensor/esp32_touch.rst b/components/binary_sensor/esp32_touch.rst
index 5f137ba40..30b301d9b 100644
--- a/components/binary_sensor/esp32_touch.rst
+++ b/components/binary_sensor/esp32_touch.rst
@@ -3,7 +3,7 @@ ESP32 Touch Pad
 
 .. seo::
     :description: Instructions for setting up the touch pad on the ESP32.
-    :image: touch.png
+    :image: touch.svg
 
 .. _esp32-touch-component:
 
diff --git a/components/binary_sensor/gpio.rst b/components/binary_sensor/gpio.rst
index 7c869459f..96bbca3be 100644
--- a/components/binary_sensor/gpio.rst
+++ b/components/binary_sensor/gpio.rst
@@ -3,7 +3,7 @@ GPIO Binary Sensor
 
 .. seo::
     :description: Instructions for setting up GPIO binary sensors with ESPHome.
-    :image: pin.png
+    :image: pin.svg
 
 The GPIO Binary Sensor platform allows you to use any input pin on your
 device as a binary sensor.
diff --git a/components/binary_sensor/homeassistant.rst b/components/binary_sensor/homeassistant.rst
index db99d7637..f98924abd 100644
--- a/components/binary_sensor/homeassistant.rst
+++ b/components/binary_sensor/homeassistant.rst
@@ -3,7 +3,7 @@ Home Assistant Binary Sensor
 
 .. seo::
     :description: Instructions for setting up Home Assistant binary sensors with ESPHome that import states from your Home Assistant instance.
-    :image: home-assistant.png
+    :image: home-assistant.svg
 
 The ``homeassistant`` binary sensor platform allows you to create binary sensors that **import**
 states from your Home Assistant instance using the :doc:`native API </components/api>`.
diff --git a/components/binary_sensor/index.rst b/components/binary_sensor/index.rst
index 60c1a7205..bfeb3fe0c 100644
--- a/components/binary_sensor/index.rst
+++ b/components/binary_sensor/index.rst
@@ -3,7 +3,7 @@ Binary Sensor Component
 
 .. seo::
     :description: Information about the base representation of all binary sensors.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 With ESPHome you can use different types of binary sensors. They will
 automatically appear in the Home Assistant front-end and have several
diff --git a/components/binary_sensor/modbus_controller.rst b/components/binary_sensor/modbus_controller.rst
index 3aecace82..455ee0048 100644
--- a/components/binary_sensor/modbus_controller.rst
+++ b/components/binary_sensor/modbus_controller.rst
@@ -23,7 +23,16 @@ Configuration variables:
 - **address**: (**Required**, int): start address of the first register in a range
 - **bitmask** : some values are packed in a response. The bitmask is used to determined if the result is true or false
 - **skip_updates**: (*Optional*, int): By default all sensors of of a modbus_controller are updated together. For data points that don't change very frequently updates can be skipped. A value of 5 would only update this sensor range in every 5th update cycle
-- **force_new_range**: (*Optional*, boolean): If possible sensors with sequential addresses are grouped together and requested in one range. Setting `foce_new_range: true` enforces the start of a new range at that address.
+- **register_count**: (*Optional*, int): only required for uncommon response encodings or to :ref:`optimize modbus communications<modbus_register_count>`
+  The number of registers this data point spans. Overrides the defaults determined by ``value_type``.
+  If no value for ``register_count`` is provided, it is calculated based on the register type.
+
+  The default size for 1 register is 16 bits (1 Word). Some devices are not adhering to this convention and have registers larger than 16 bits.  In this case ``register_count`` and  ``response_size`` must be set. For example, if your modbus device uses 1 registers for a FP32 value instead the default of two set ``register_count: 1`` and ``response_size: 4``.
+- **response_size**:  (*Optional*, int): Size of the response for the register in bytes. Defaults to register_count*2.
+- **force_new_range**: (*Optional*, boolean): If possible sensors with sequential addresses are grouped together and requested in one range. Setting ``force_new_range: true`` enforces the start of a new range at that address.
+- **custom_data** (*Optional*, list of bytes): raw bytes for modbus command. This allows using non-standard commands. If ``custom_data`` is used ``address`` and ``register_type`` can't be used.
+  custom data must contain all required bytes including the modbus device address. The crc is automatically calculated and appended to the command.
+  See :ref:`modbus_custom_data` how to use ``custom_command``
 - **lambda** (*Optional*, :ref:`lambda <config-lambda>`):
   Lambda to be evaluated every update interval to get the new value of the sensor
 - **offset**: (*Optional*, int): not required for most cases
diff --git a/components/binary_sensor/status.rst b/components/binary_sensor/status.rst
index 9a873e58e..cdaac910a 100644
--- a/components/binary_sensor/status.rst
+++ b/components/binary_sensor/status.rst
@@ -3,7 +3,7 @@ Status Binary Sensor
 
 .. seo::
     :description: Instructions for setting up MQTT status binary sensors.
-    :image: server-network.png
+    :image: server-network.svg
 
 The Status Binary Sensor exposes the node state (if it’s connected to via MQTT/native API)
 for Home Assistant.
diff --git a/components/binary_sensor/template.rst b/components/binary_sensor/template.rst
index f83745c7b..55e62fd5f 100644
--- a/components/binary_sensor/template.rst
+++ b/components/binary_sensor/template.rst
@@ -3,7 +3,7 @@ Template Binary Sensor
 
 .. seo::
     :description: Instructions for setting up template binary sensors.
-    :image: description.png
+    :image: description.svg
 
 The ``template`` binary sensor platform allows you to define any :ref:`lambda template <config-lambda>`
 and construct a binary sensor out if it.
diff --git a/components/button/index.rst b/components/button/index.rst
new file mode 100644
index 000000000..b1f460df8
--- /dev/null
+++ b/components/button/index.rst
@@ -0,0 +1,121 @@
+Button Component
+================
+
+.. seo::
+    :description: Instructions for setting up button components in ESPHome.
+    :image: folder-open.svg
+
+ESPHome has support for components to create a button entity. A button entity is
+basically a momentary switch with no state and can be triggered by either YAML or
+the user/frontend.
+
+.. note::
+
+    Home Assistant Core 2021.12 or higher is required for ESPHome button entities to work.
+
+.. _config-button:
+
+Base Button Configuration
+-------------------------
+
+All buttons in ESPHome have a name and an optional icon.
+
+.. code-block:: yaml
+
+    # Example button configuration
+    button:
+      - platform: ...
+        name: Livingroom Lazy Mood
+        id: my_button
+
+        # Optional variables:
+        icon: "mdi:emoticon-outline"
+        on_press:
+          - logger.log: "Button pressed"
+
+Configuration variables:
+
+- **name** (**Required**, string): The name for the button.
+- **icon** (*Optional*, icon): Manually set the icon to use for the button in the frontend.
+- **internal** (*Optional*, boolean): Mark this component as internal. Internal components will
+  not be exposed to the frontend (like Home Assistant). Only specifying an ``id`` without
+  a ``name`` will implicitly set this to true.
+- **disabled_by_default** (*Optional*, boolean): If true, then this entity should not be added to any client's frontend,
+  (usually Home Assistant) without the user manually enabling it (via the Home Assistant UI).
+- **entity_category** (*Optional*, string): The category of the entity.
+  See https://developers.home-assistant.io/docs/core/entity/#generic-properties
+  for a list of available options. Set to ``""`` to remove the default entity category.
+- **device_class** (*Optional*, string): The device class for the button.
+  See https://developers.home-assistant.io/docs/core/entity/button/#available-device-classes
+  for a list of available options.
+
+Automations:
+
+- **on_press** (*Optional*, :ref:`Automation <automation>`): An automation to perform
+  when the button is pressed. See :ref:`button-on_press`.
+
+MQTT options:
+
+- All other options from :ref:`MQTT Component <config-mqtt-component>`.
+
+Button Automation
+-----------------
+
+.. _button-on_press:
+
+``on_press``
+************
+
+This automation will be triggered when the button is pressed.
+
+.. code-block:: yaml
+
+    button:
+      - platform: template
+        # ...
+        on_press:
+          then:
+            - logger.log: Button Pressed
+
+Configuration variables: see :ref:`Automation <automation>`.
+
+.. _button-press_action:
+
+``button.press`` Action
+***********************
+
+This is an :ref:`Action <config-action>` for pressing a button in an Automation.
+
+.. code-block:: yaml
+
+    - button.press: my_button
+
+Configuration variables:
+
+- **id** (**Required**, :ref:`config-id`): The ID of the button to set.
+
+.. _button-lambda_calls:
+
+lambda calls
+************
+
+From :ref:`lambdas <config-lambda>`, you can press a button.
+
+- ``press()``: Press the button.
+
+  .. code-block:: cpp
+
+      // Within lambda, press the button.
+      id(my_button).press();
+
+See Also
+--------
+
+- :apiref:`button/button.h`
+- :ghedit:`Edit`
+
+.. toctree::
+    :maxdepth: 1
+    :glob:
+
+    *
diff --git a/components/button/restart.rst b/components/button/restart.rst
new file mode 100644
index 000000000..9f7f1ce2f
--- /dev/null
+++ b/components/button/restart.rst
@@ -0,0 +1,31 @@
+Restart Button
+==============
+
+.. seo::
+    :description: Instructions for setting up buttons that can remotely reboot the ESP in ESPHome.
+    :image: restart.svg
+
+The ``restart`` button platform allows you to restart your node remotely
+through Home Assistant.
+
+.. code-block:: yaml
+
+    # Example configuration entry
+    button:
+      - platform: restart
+        name: "Living Room Restart"
+
+Configuration variables:
+------------------------
+
+- **name** (**Required**, string): The name for the button.
+- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
+- All other options from :ref:`Button <config-button>`.
+
+See Also
+--------
+
+- :doc:`/components/switch/restart`
+- :doc:`template`
+- :apiref:`restart/button/restart_button.h`
+- :ghedit:`Edit`
diff --git a/components/button/template.rst b/components/button/template.rst
new file mode 100644
index 000000000..959edfa91
--- /dev/null
+++ b/components/button/template.rst
@@ -0,0 +1,32 @@
+Template Button
+===============
+
+.. seo::
+    :description: Instructions for setting up template buttons that can execute arbitrary actions when pressed.
+    :image: description.svg
+
+The ``template`` button platform allows you to create simple buttons out of just actions. Once defined,
+it will automatically appear in Home Assistant as a button and can be controlled through the frontend.
+
+.. code-block:: yaml
+
+    # Example configuration entry
+    button:
+      - platform: template
+        name: "Template Button"
+        on_press:
+          - logger.log: Button Pressed
+
+Configuration variables:
+------------------------
+
+- **name** (**Required**, string): The name of the switch.
+- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
+- All other options from :ref:`Button <config-button>`.
+
+See Also
+--------
+
+- :doc:`/guides/automations`
+- :doc:`/components/button/index`
+- :ghedit:`Edit`
diff --git a/components/canbus.rst b/components/canbus.rst
index 197bb5378..eeaf3a9e0 100644
--- a/components/canbus.rst
+++ b/components/canbus.rst
@@ -5,7 +5,7 @@ CAN bus
 
 .. seo::
     :description: Instructions for setting up an CAN bus in ESPHome
-    :image: canbus.png
+    :image: canbus.svg
     :keywords: CAN
 
 Controller Area Network (CAN bus) is a serial bus protocol to connect individual systems and sensors
diff --git a/components/captive_portal.rst b/components/captive_portal.rst
index cefd84933..f41324a96 100644
--- a/components/captive_portal.rst
+++ b/components/captive_portal.rst
@@ -3,7 +3,7 @@ Captive Portal
 
 .. seo::
     :description: Instructions for setting up the Captive Portal fallback mechanism in ESPHome.
-    :image: wifi-strength-alert-outline.png
+    :image: wifi-strength-alert-outline.svg
 
 The captive portal component in ESPHome is a fallback mechanism for when connecting to the
 configured :doc:`WiFi <wifi>` fails.
diff --git a/components/climate/bang_bang.rst b/components/climate/bang_bang.rst
index 91555e84b..cbe696c9f 100644
--- a/components/climate/bang_bang.rst
+++ b/components/climate/bang_bang.rst
@@ -3,7 +3,7 @@ Bang Bang Climate Controller
 
 .. seo::
     :description: Instructions for setting up Bang Bang climate controllers with ESPHome.
-    :image: air-conditioner.png
+    :image: air-conditioner.svg
 
 The ``bang_bang`` climate platform allows you to regulate a value with a
 `bang-bang controller <https://en.wikipedia.org/wiki/Bang%E2%80%93bang_control>`__ (also called hysteresis controller).
diff --git a/components/climate/index.rst b/components/climate/index.rst
index 7c1f3e75b..3551fcf64 100644
--- a/components/climate/index.rst
+++ b/components/climate/index.rst
@@ -3,7 +3,7 @@ Climate Component
 
 .. seo::
     :description: Information about the base representation of all climate devices.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 ESPHome has support for climate devices. Climate devices can represent different types of
 hardware, but the defining factor is that climate devices have a settable target temperature
@@ -184,6 +184,21 @@ advanced stuff.
       // etc. see API reference
       call.perform();
 
+.. _climate-on_state_trigger:
+
+``climate.on_state`` Trigger
+******************************************************
+
+This trigger is activated each time the state of the climate device is updated 
+(for example, if the current temperature measurement or the mode set by the users changes).
+
+.. code-block:: yaml
+
+    climate:
+      - platform: midea  # or any other platform
+        # ...
+        on_state:
+        - logger.log: "State updated!"
 
 See Also
 --------
diff --git a/components/climate/ir_climate.rst b/components/climate/ir_climate.rst
index 4152dfa6e..6d4f05d01 100755
--- a/components/climate/ir_climate.rst
+++ b/components/climate/ir_climate.rst
@@ -3,7 +3,7 @@ IR Remote Climate
 
 .. seo::
     :description: Controls a variety of compatible Climate devices via IR
-    :image: air-conditioner-ir.png
+    :image: air-conditioner-ir.svg
 
 This climate component allows you to control compatible AC units by sending an infrared (IR)
 control signal, just as the unit's handheld remote controller would.
@@ -96,11 +96,23 @@ This platform utilises the library's generic one-size-fits-all API, which might
 
 Additional configuration must be specified for this platform:
 
-- **protocol** (**Required**, string): Choose one of Arduino-HeatpumpIR's supported protcols: ``aux``, ``ballu``, ``carrier_mca``, ``carrier_nqv``, ``daikin_arc417``, ``daikin_arc480``, ``daikin``, ``fuego``, ``fujitsu_awyz``, ``gree``, ``greeya``, ``greeyan``, ``hisense_aud``, ``hitachi``, ``hyundai``, ``ivt``, ``midea``, ``mitsubishi_fa``, ``mitsubishi_fd``, ``mitsubishi_fe``, ``mitsubishi_heavy_fdtc``, ``mitsubishi_heavy_zj``, ``mitsubishi_heavy_zm``, ``mitsubishi_heavy_zmp``, ``mitsubishi_heavy_kj``, ``mitsubishi_msc``, ``mitsubishi_msy``, ``mitsubishi_sez``, ``panasonic_ckp``, ``panasonic_dke``, ``panasonic_jke``, ``panasonic_lke``, ``panasonic_nke``, ``samsung_aqv``, ``samsung_fjm``, ``sharp``, ``toshiba_daiseikai``, ``toshiba``
+- **protocol** (**Required**, string): Choose one of Arduino-HeatpumpIR's supported protcols: ``aux``, ``ballu``, ``carrier_mca``, ``carrier_nqv``, ``daikin_arc417``, ``daikin_arc480``, ``daikin``, ``fuego``, ``fujitsu_awyz``, ``gree``, ``greeya``, ``greeyac``, ``greeyan``, ``hisense_aud``, ``hitachi``, ``hyundai``, ``ivt``, ``midea``, ``mitsubishi_fa``, ``mitsubishi_fd``, ``mitsubishi_fe``, ``mitsubishi_heavy_fdtc``, ``mitsubishi_heavy_zj``, ``mitsubishi_heavy_zm``, ``mitsubishi_heavy_zmp``, ``mitsubishi_heavy_kj``, ``mitsubishi_msc``, ``mitsubishi_msy``, ``mitsubishi_sez``, ``panasonic_ckp``, ``panasonic_dke``, ``panasonic_jke``, ``panasonic_lke``, ``panasonic_nke``, ``samsung_aqv``, ``samsung_fjm``, ``sharp``, ``toshiba_daiseikai``, ``toshiba``
 - **horizontal_default** (**Required**, string): What to default to when the AC unit's horizontal direction is *not* set to swing. Options are: ``left``, ``mleft``, ``middle``, ``mright``, ``right``, ``auto``
 - **vertical_default** (**Required**, string): What to default to when the AC unit's vertical direction is *not* set to swing. Options are: ``down``, ``mdown``, ``middle``, ``mup``, ``up``, ``auto``
 - **max_temperature** (**Required**, float): The maximum temperature that the AC unit supports being set to.
 - **min_temperature** (**Required**, float): The minimum temperature that the AC unit supports being set to.
+- **sensor** (*Optional*, :ref:`config-id`): The sensor that is used to measure the ambient temperature.
+
+.. note::
+
+    - The ``greeyac`` protocol supports a feature Gree calls "I-Feel". The handheld remote control
+      has a built-in temperature sensor and it will periodically transmit the temperature from this sensor to the
+      AC unit. If a ``sensor`` is provided in the configuration with this model, the sensor's temperature will be
+      transmitted to the ``greeyac`` device in the same manner as the original remote controller. How often the
+      temperature is transmitted is determined by the ``update_interval`` assigned to the ``sensor``. Note that
+      ``update_interval`` must be less than 10 minutes or the ``greeyac`` device will revert to using its own
+      internal temperature sensor; a value of 2 minutes seems to work well. See :doc:`/components/sensor/index`
+      for more information.
 
 .. _ir-receiver_id:
 
diff --git a/components/climate/midea.rst b/components/climate/midea.rst
index 920dbc6ba..769d0a174 100644
--- a/components/climate/midea.rst
+++ b/components/climate/midea.rst
@@ -3,7 +3,7 @@ Midea Air Conditioner
 
 .. seo::
     :description: Instructions for setting up a Midea climate device
-    :image: air-conditioner.png
+    :image: air-conditioner.svg
 
 The ``midea`` component creates a Midea air conditioner climate device.
 
diff --git a/components/climate/pid.rst b/components/climate/pid.rst
index 23f57295d..a20de5579 100644
--- a/components/climate/pid.rst
+++ b/components/climate/pid.rst
@@ -3,7 +3,7 @@ PID Climate
 
 .. seo::
     :description: Instructions for setting up PID climate controllers with ESPHome.
-    :image: function.png
+    :image: function.svg
 
 The ``pid`` climate platform allows you to regulate a value with a
 `PID controller <https://en.wikipedia.org/wiki/PID_controller>`__.
diff --git a/components/climate/thermostat.rst b/components/climate/thermostat.rst
index 3b13f3761..15f035ed8 100644
--- a/components/climate/thermostat.rst
+++ b/components/climate/thermostat.rst
@@ -3,7 +3,7 @@ Thermostat Climate Controller
 
 .. seo::
     :description: Instructions for setting up Thermostat climate controllers with ESPHome.
-    :image: air-conditioner.png
+    :image: air-conditioner.svg
 
 The ``thermostat`` climate platform allows you to control a climate control system in much the same manner as a
 physical thermostat. Its operation is similar to the :doc:`bang-bang <bang_bang>` controller; a sensor measures a value
diff --git a/components/climate/tuya.rst b/components/climate/tuya.rst
index 6a2843dc6..cbc00eba7 100644
--- a/components/climate/tuya.rst
+++ b/components/climate/tuya.rst
@@ -3,7 +3,7 @@ Tuya Climate
 
 .. seo::
     :description: Instructions for setting up a Tuya climate device.
-    :image: air-conditioner.png
+    :image: air-conditioner.svg
 
 The ``tuya`` climate platform creates a climate device from a tuya component.
 
diff --git a/components/cover/am43.rst b/components/cover/am43.rst
index c096fb221..c1f05f505 100644
--- a/components/cover/am43.rst
+++ b/components/cover/am43.rst
@@ -3,7 +3,7 @@ AM43 Cover
 
 .. seo::
     :description: Setting up AM43/BLE covers in ESPHome.
-    :image: am43.png
+    :image: am43.jpg
 
 The ``am43`` cover platform allows you to control an AM43 based
 BLE cover motor. These devices are sold under various brands, such
diff --git a/components/cover/current_based.rst b/components/cover/current_based.rst
index ee4581dc1..dd6d09c97 100644
--- a/components/cover/current_based.rst
+++ b/components/cover/current_based.rst
@@ -3,14 +3,14 @@ Current Based Cover
 
 .. seo::
     :description: Instructions for setting up current-based covers in ESPHome.
-    :image:  window-open.jpg
+    :image:  window-open.svg
 
 The ``current_based`` cover platform allows you to create covers with position control by using current
-sensors to detect the fully-open and fully-closed states. This is pretty useful when using motors with 
-integrated mechanical endstops. During cover operation, the component monitors the current consumption 
-to detect when the motor has stopped. 
+sensors to detect the fully-open and fully-closed states. This is pretty useful when using motors with
+integrated mechanical endstops. During cover operation, the component monitors the current consumption
+to detect when the motor has stopped.
 
-When fully open or close is requested, the corresponding relay will stay on until the current the motor is 
+When fully open or close is requested, the corresponding relay will stay on until the current the motor is
 consuming goes below a certain amount. The amount of current needs to be specified in the configuration.
 
 Open and close durations can be specified to allow ESPHome to approximate the current position of the cover.
@@ -19,14 +19,14 @@ Open and close durations can be specified to allow ESPHome to approximate the cu
     :align: center
     :width: 75.0%
 
-This type of cover also provides safety features like current-based obstacle detection with automatic configurable 
-rollback as well as relay malfunction detection: operation cancels if there's a current flowing in the opposite 
-operation circuit (typically caused by welded relays).  
+This type of cover also provides safety features like current-based obstacle detection with automatic configurable
+rollback as well as relay malfunction detection: operation cancels if there's a current flowing in the opposite
+operation circuit (typically caused by welded relays).
 
 .. warning::
 
-    Depending on the cover and motor type, obstacles can physically damage the cover before being detectable. 
-    Verify your setup to ensure the current consumption will increase enough to be detectable before causing 
+    Depending on the cover and motor type, obstacles can physically damage the cover before being detectable.
+    Verify your setup to ensure the current consumption will increase enough to be detectable before causing
     any physical damage. Use it at your own risk.
 
 .. code-block:: yaml
@@ -56,7 +56,7 @@ operation circuit (typically caused by welded relays).
 
         obstacle_rollback: 30%
         start_sensing_delay: 0.8s
-          
+
 
 
 Configuration variables:
@@ -68,32 +68,32 @@ Configuration variables:
   be performed when the remote requests the cover to be opened.
 - **open_duration** (**Required**, :ref:`config-time`): The amount of time it takes the cover
   to open up from the fully-closed state.
-- **open_moving_current_threshold** (**Required**, float): The amount of current in Amps the motor 
-  should drain to consider the cover is opening. 
-- **open_obstacle_current_threshold** (**Required**, float): The amount of current in Amps the motor 
+- **open_moving_current_threshold** (**Required**, float): The amount of current in Amps the motor
+  should drain to consider the cover is opening.
+- **open_obstacle_current_threshold** (**Required**, float): The amount of current in Amps the motor
   should drain to consider the cover is blocked during opening.
 - **close_sensor** (**Required**, :ref:`config-id`): The close current sensor.
 - **close_action** (*Optional*, :ref:`Action <config-action>`): The action that should
   be performed when the remote requests the cover to be closed.
 - **close_duration** (**Required**, :ref:`config-time`): The amount of time it takes the cover
   to close from the fully-open state.
-- **close_moving_current_threshold** (**Required**, float): The amount of current in Amps the motor 
+- **close_moving_current_threshold** (**Required**, float): The amount of current in Amps the motor
   should drain to consider the cover is closing.
-- **close_obstacle_current_threshold** (**Required**, float): The amount of current in Amps the motor 
+- **close_obstacle_current_threshold** (**Required**, float): The amount of current in Amps the motor
   should drain to consider the cover is blocked during closing.
 - **stop_action** (**Required**, :ref:`Action <config-action>`): The action that should
   be performed to stop the cover.
 - **max_duration** (*Optional*, :ref:`config-time`): The maximum duration the cover should be opening
   or closing. Useful for protecting from dysfunctional motor integrated endstops.
-- **start_sensing_delay** (*Optional*, :ref:`config-time`): The amount of time the current sensing will be 
-  disabled when the movement starts. Motors can take some time before reaching their average consumption. 
-  Low values can cause an immediate stop because of the first current reading happening in the current-rising period. 
+- **start_sensing_delay** (*Optional*, :ref:`config-time`): The amount of time the current sensing will be
+  disabled when the movement starts. Motors can take some time before reaching their average consumption.
+  Low values can cause an immediate stop because of the first current reading happening in the current-rising period.
   Defaults to ``500ms``.
-- **obstacle_rollback** (*Optional*, percentage): The percentage of rollback the cover will perform in case of 
+- **obstacle_rollback** (*Optional*, percentage): The percentage of rollback the cover will perform in case of
   obstacle detection. Defaults to ``10%``.
 - **malfunction_detection** (*Optional*, boolean): Enable to detect malfunction detection (Tipically welded realys). Defaults to ``True``.
 - **malfunction_action** (*Optional*, :ref:`Action <config-action>`): The action that should
-  be performed when relay malfunction is detected. Malfunction may require device servicing. You can use this action 
+  be performed when relay malfunction is detected. Malfunction may require device servicing. You can use this action
   to notify other systems about this situation
 - **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
 - All other options from :ref:`Cover <config-cover>`.
@@ -101,25 +101,21 @@ Configuration variables:
 Use with Shelly 2.5
 -------------------
 
-.. seo::
-    :description: Instructions for setting up current-based covers in ESPHome using a Shelly 2.5.
-    :image:  shelly2.5.png
-
 The Shelly 2.5 is the perfect hardware for this platform. It features two outputs with current monitoring
-(thanks to an embedded :doc:`ADE7953 </components/sensor/ade7953>`) in a very small form factor (39mm x 36mm x 17 mm). 
+(thanks to an embedded :doc:`ADE7953 </components/sensor/ade7953>`) in a very small form factor (39mm x 36mm x 17 mm).
 It also features an :doc:`NTC temperature sensor </components/sensor/ntc>`.
 
 .. figure:: images/shelly2.5.png
     :align: center
     :width: 30.0%
 
-These devices typically run hot (~55Cº at 20ºC room temperature). Long-term heavy loads (near to its rated limit) can overheat the device. 
-It is strongly recommended to monitor the device temperature using the NTC temperature sensor, shutting down the device if it exceeds 90ºC. 
+These devices typically run hot (~55Cº at 20ºC room temperature). Long-term heavy loads (near to its rated limit) can overheat the device.
+It is strongly recommended to monitor the device temperature using the NTC temperature sensor, shutting down the device if it exceeds 90ºC.
 This safety feature is also present in the original firmware.
 
 .. warning::
 
-    The ADE7953 IRQ line is connected to the GPIO16. The ``irq_pin`` parameter for the :doc:`ADE7953 </components/sensor/ade7953>` MUST be 
+    The ADE7953 IRQ line is connected to the GPIO16. The ``irq_pin`` parameter for the :doc:`ADE7953 </components/sensor/ade7953>` MUST be
     set to GPIO16 to prevent device overheat (>70ºC idling).
 
 Configuration example:
@@ -135,7 +131,7 @@ Configuration example:
     i2c:
       sda: GPIO12
       scl: GPIO14
-        
+
     sensor:
       - platform: ade7953
         irq_pin: GPIO16
@@ -153,7 +149,7 @@ Configuration example:
           id: close_current
           internal: true
         update_interval: 0.5s
-        
+
       # NTC Temperature
       - platform: ntc
         sensor: temp_resistance_reading
@@ -164,7 +160,7 @@ Configuration example:
           b_constant: 3350
           reference_resistance: 10kOhm
           reference_temperature: 298.15K
-        on_value_range: 
+        on_value_range:
           above: 90
           then: # Security shutdown by overheating
             - switch.turn_on: _shutdown
@@ -182,7 +178,7 @@ Configuration example:
         internal: true
 
     binary_sensor:
-      - platform: gpio 
+      - platform: gpio
         pin:
           number: GPIO13
         name: Shelly 2.5 Open Button
@@ -243,8 +239,8 @@ Configuration example:
         malfunction_detection: true
         malfunction_action:
           then:
-            - logger.log: "Malfunction detected. Relay welded."    
-          
+            - logger.log: "Malfunction detected. Relay welded."
+
 
 
     status_led:
diff --git a/components/cover/endstop.rst b/components/cover/endstop.rst
index 9f7e6c502..1637f8d72 100644
--- a/components/cover/endstop.rst
+++ b/components/cover/endstop.rst
@@ -3,7 +3,7 @@ Endstop Cover
 
 .. seo::
     :description: Instructions for setting up time-based covers in ESPHome.
-    :image: electric-switch.png
+    :image: electric-switch.svg
 
 The ``endstop`` cover platform allows you to create covers with position control that have
 endstops at both ends of the cover to detect the fully-open and fully-closed states.
diff --git a/components/cover/index.rst b/components/cover/index.rst
index 33d5471b4..cc418a643 100644
--- a/components/cover/index.rst
+++ b/components/cover/index.rst
@@ -3,7 +3,7 @@ Cover Component
 
 .. seo::
     :description: Instructions for setting up base covers in ESPHome.
-    :image: folder-opn.png
+    :image: folder-open.svg
 
 The ``cover`` component is a generic representation of covers in ESPHome.
 A cover can (currently) either be *closed* or *open* and supports three types of
diff --git a/components/cover/template.rst b/components/cover/template.rst
index face67eea..e93b54c61 100644
--- a/components/cover/template.rst
+++ b/components/cover/template.rst
@@ -3,7 +3,7 @@ Template Cover
 
 .. seo::
     :description: Instructions for setting up template covers in ESPHome.
-    :image: description.png
+    :image: description.svg
 
 The ``template`` cover platform allows you to create simple covers out of just a few
 actions and a value lambda. Once defined, it will automatically appear in Home Assistant
diff --git a/components/cover/time_based.rst b/components/cover/time_based.rst
index dcbfa07ba..a2da02d76 100644
--- a/components/cover/time_based.rst
+++ b/components/cover/time_based.rst
@@ -3,7 +3,7 @@ Time-Based Cover
 
 .. seo::
     :description: Instructions for setting up time-based covers in ESPHome.
-    :image: timer.png
+    :image: timer.svg
 
 The ``time_based`` cover platform allows you to create covers with position control that do not
 have any position feedback. The state of the cover is thus always an assumed one, the current
diff --git a/components/cover/tuya.rst b/components/cover/tuya.rst
index 5cf827072..f23fbb911 100644
--- a/components/cover/tuya.rst
+++ b/components/cover/tuya.rst
@@ -29,7 +29,7 @@ the config and it will list the possible devices for you in the config log.
     # Make sure you can upload new firmware OTA
     ota:
 
-    # My dimmer used the hardware serial port on the alternate pins
+    # My cover used the hardware serial port on the alternate pins
     uart:
       rx_pin: GPIO13
       tx_pin: GPIO15
@@ -38,7 +38,7 @@ the config and it will list the possible devices for you in the config log.
     # Register the Tuya MCU connection
     tuya:
 
-Here is an example output for a Tuya dimmer:
+Here is an example output for a Tuya M515EGWT (motor for chain roller blinds):
 
 .. code-block:: text
 
@@ -51,7 +51,7 @@ Now you can create the cover.
 
 .. code-block:: yaml
 
-    # Create a cover using the dimmer
+    # Create a cover using the datapoint from above
     cover:
       - platform: "tuya"
         name: "motor1"
@@ -62,13 +62,46 @@ Configuration variables:
 
 - **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
 - **name** (**Required**, string): The name of the cover.
+- **control_datapoint** (*Optional*, int): The datapoint id number for sending control commands.
 - **position_datapoint** (**Required**, int): The datapoint id number of the cover position value.
+- **position_report_datapoint** (*Optional*, int): The datapoint id number of the cover position report value, if separate from position_datapoint.
+- **direction_datapoint** (*Optional*, int): The datapoint id number for setting the direction of travel.
 - **min_value** (*Optional*, int): The lowest position value, meaning cover closed. Defaults to 0.
 - **max_value** (*Optional*, int): the highest position value, meaning cover opened. Defaults to 255.
-- **invert_position** (*Optional*, boolean): invert the meaning of ``min_value`` and ``max_value``.
-  When set to ``true``, ``min_value`` will mean opened and ``max_value`` is closed.
+- **invert_position** (*Optional*, boolean): Sets the direction of travel to be inverted, if direction_datapoint is configured.
 - All other options from :ref:`Cover <config-cover>`.
 
+Supported devices
+-----------------
+
+Tuya cover devices known to be supported by this integration:
+
+- Tuya ``M515EGWT`` (motor for bead chain roller blinds)
+
+  - Only the ``position`` datapoint (2) is used for this device.
+  - Datapoint 5's function is not currently known.
+
+- Zemismart ``ZM79E-DT`` (curtain motor)
+
+  - Supported datapoints: ``control`` (1), ``position`` (2), ``position_report`` (3) and ``direction`` (5).
+  - The direction of travel is persisted to the Tuya MCU, so doesn't need to be set if you've already configured it via the remote control.
+
+If you have a Tuya cover device that isn't listed above, it may still work - but you'll need to determine which datapoints it uses
+(and what their IDs are) for yourself.
+
+Restore modes
+-------------
+
+The default restore mode (``RESTORE``) attempts to restore the state on startup, but doesn't instruct the cover to move to that state.
+
+``RESTORE_AND_CALL`` additionally instructs the cover to move to the restored state - which might not work, depending on your device (see note below).
+
+The Tuya MCU usually reports its position on startup, so ``NO_RESTORE`` will likely also appear to restore its state - but may take slightly longer.
+
+Note that if your Tuya cover device uses relative position sensing (such as the ZM79E-DT), it can't tell if the cover was moved while not powered up.
+This means that moving the cover while the device is powered off will result in its position not matching the reported/requested state.
+In this condition, it will go into an error / uncalibrated state when it next tries to go in one direction (as it can't move as far as it wants to), requiring an open/close cycle to recalibrate.
+
 
 See Also
 --------
@@ -77,4 +110,3 @@ See Also
 - :doc:`/components/cover/index`
 - :apiref:`tuya/cover/tuya_cover.h`
 - :ghedit:`Edit`
-
diff --git a/components/debug.rst b/components/debug.rst
index 182326a03..c632ff41a 100644
--- a/components/debug.rst
+++ b/components/debug.rst
@@ -3,7 +3,7 @@ Debug Component
 
 .. seo::
     :description: Instructions for setting up the debug component in ESPHome
-    :image: bug-report.png
+    :image: bug-report.svg
 
 The ``debug`` component can be used to debug problems with ESPHome. At startup, it prints
 a bunch of useful information like reset reason, free heap size, ESPHome version and so on.
diff --git a/components/deep_sleep.rst b/components/deep_sleep.rst
index 7f886e296..97e152605 100644
--- a/components/deep_sleep.rst
+++ b/components/deep_sleep.rst
@@ -5,7 +5,7 @@ Deep Sleep Component
 
 .. seo::
     :description: Instructions for setting up the deep sleep support for minimizing power consumption on ESPs.
-    :image: hotel.png
+    :image: hotel.svg
 
 The ``deep_sleep`` component can be used to automatically enter a deep sleep mode on the
 ESP8266/ESP32 after a certain amount of time. This is especially useful with nodes that operate
diff --git a/components/demo.rst b/components/demo.rst
index 8fe294d11..faccce99f 100644
--- a/components/demo.rst
+++ b/components/demo.rst
@@ -3,7 +3,7 @@ Demo Integration
 
 .. seo::
     :description: Instructions for setting up the demo integration in ESPHome
-    :image: description.png
+    :image: description.svg
 
 The ``demo`` integration can be used for testing to generate sample instances of many
 different integrations (sensors, lights, ...)
diff --git a/components/dfplayer.rst b/components/dfplayer.rst
index f9e2089f5..c574965b2 100644
--- a/components/dfplayer.rst
+++ b/components/dfplayer.rst
@@ -3,7 +3,7 @@ DF-Player mini
 
 .. seo::
     :description: Instructions for setting up DF Player Mini integration in ESPHome.
-    :image: crosshair-gps.png
+    :image: dfplayer.svg
 
 The ``dfplayer`` (`datasheet <https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299>`__), component
 allows you to play sound and music stored in an SD card or USB flash drive.
diff --git a/components/display/ili9341.rst b/components/display/ili9341.rst
index e48bf31f4..04229e353 100644
--- a/components/display/ili9341.rst
+++ b/components/display/ili9341.rst
@@ -3,7 +3,7 @@ ILI9341 TFT LCD
 
 .. seo::
     :description: Instructions for setting up ILI9341 TFT LCD display drivers.
-    :image: ili9341-full.jpg
+    :image: ili9341.jpg
 
 .. _ili9341:
 
diff --git a/components/display/index.rst b/components/display/index.rst
index 9c8cff564..4c836c9ca 100644
--- a/components/display/index.rst
+++ b/components/display/index.rst
@@ -3,7 +3,7 @@ Display Component
 
 .. seo::
     :description: Instructions for setting up the display integration.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 The ``display`` component houses ESPHome's powerful rendering and display
 engine. Fundamentally, there are these types of displays:
diff --git a/components/display/st7735.rst b/components/display/st7735.rst
index 3cb9df64a..805871a37 100644
--- a/components/display/st7735.rst
+++ b/components/display/st7735.rst
@@ -4,7 +4,7 @@ ST7735 Display
 .. seo::
     :description: Instructions for setting up a ST7735 display drivers.
     :keywords: ST7735
-    :image: ST7735.png
+    :image: st7735.jpg
 
 ST7735 Display Driver.
 
diff --git a/components/display/st7789v.rst b/components/display/st7789v.rst
index a0b52a5ee..fd47c065a 100644
--- a/components/display/st7789v.rst
+++ b/components/display/st7789v.rst
@@ -3,7 +3,7 @@ ST7789V TFT LCD
 
 .. seo::
     :description: Instructions for setting up ST7789V TFT LCD display drivers.
-    :image: st7789v-full.jpg
+    :image: st7789v.jpg
 
 .. _st7789v:
 
diff --git a/components/esp32.rst b/components/esp32.rst
index 8fea591f9..6479c4e25 100644
--- a/components/esp32.rst
+++ b/components/esp32.rst
@@ -3,7 +3,7 @@ ESP32 Platform
 
 .. seo::
     :description: Configuration for the ESP32 platform for ESPHome.
-    :image: esp32.png
+    :image: esp32.svg
 
 This component contains platform-specific options for the ESP32 platform.
 
@@ -18,7 +18,7 @@ Configuration variables:
 
 - **board** (**Required**, string): The PlatformIO board ID that should
   be used. Choose the appropriate board from
-  `this list <https://platformio.org/boards?count=1000&filter%5Bplatform%5D=espressif32>`__. 
+  `this list <https://platformio.org/boards?count=1000&filter%5Bplatform%5D=espressif32>`__.
   *This only affects pin aliases, flash size and some internal settings*, if unsure choose a generic board.
 - **framework** (*Optional*): Options for the underlying framework used by ESPHome.
   See :ref:`esp32-arduino_framework` and :ref:`esp32-espidf_framework`.
@@ -42,7 +42,7 @@ This is the default framework for ESP32 chips at the moment.
         type: arduino
         version: 2.0.0
 
-- **version** (*Optional*, string): The base framework version number to use, from 
+- **version** (*Optional*, string): The base framework version number to use, from
   `ESP32 arduino releases <https://github.com/espressif/arduino-esp32/releases>`__. Defaults to ``recommended``. Additional values are:
 
   - ``dev``: Use the latest commit from https://github.com/espressif/arduino-esp32, note this may break at any time
@@ -75,7 +75,7 @@ of the ESP32 like ESP32S2, ESP32S3, ESP32C3 and single-core ESP32 chips.
         advanced:
           ignore_efuse_mac_crc: false
 
-- **version** (*Optional*, string): The base framework version number to use, from 
+- **version** (*Optional*, string): The base framework version number to use, from
   `ESP32 ESP-IDF releases <https://github.com/espressif/esp-idf/releases>`__. Defaults to ``recommended``. Additional values are:
 
   - ``dev``: Use the latest commit from https://github.com/espressif/esp-idf, note this may break at any time
diff --git a/components/esp32_ble_beacon.rst b/components/esp32_ble_beacon.rst
index 77932565a..dac949dee 100644
--- a/components/esp32_ble_beacon.rst
+++ b/components/esp32_ble_beacon.rst
@@ -3,7 +3,7 @@ ESP32 Bluetooth Low Energy Beacon
 
 .. seo::
     :description: Instructions for setting up Bluetooth Low Energy iBeacons using the BLE feature on ESP32s.
-    :image: bluetooth.png
+    :image: bluetooth.svg
 
 The ``esp32_ble_beacon`` component creates a Bluetooth Low Energy Beacon with your ESP32 device.
 Beacons are BLE devices that repeatedly just send out a pre-defined packet of data. This packet
diff --git a/components/esp32_ble_tracker.rst b/components/esp32_ble_tracker.rst
index fca8d51f2..22882bdc1 100644
--- a/components/esp32_ble_tracker.rst
+++ b/components/esp32_ble_tracker.rst
@@ -3,7 +3,7 @@ ESP32 Bluetooth Low Energy Tracker Hub
 
 .. seo::
     :description: Instructions for setting up ESP32 bluetooth low energy device trackers using ESPHome.
-    :image: bluetooth.png
+    :image: bluetooth.svg
 
 The ``esp32_ble_tracker`` component creates a global hub so that you can track bluetooth low
 energy devices using your ESP32 node.
diff --git a/components/esp32_camera.rst b/components/esp32_camera.rst
index 1fe604aae..def25bc0e 100644
--- a/components/esp32_camera.rst
+++ b/components/esp32_camera.rst
@@ -3,7 +3,7 @@ ESP32 Camera Component
 
 .. seo::
     :description: Instructions for setting up the ESP32 Cameras in ESPHome
-    :image: camera.png
+    :image: camera.svg
 
 The ``esp32_camera`` component allows you to use ESP32-based camera boards in ESPHome that
 directly integrate into Home Assistant through the native API.
diff --git a/components/esp32_camera_web_server.rst b/components/esp32_camera_web_server.rst
index 48e345e08..6cc560258 100644
--- a/components/esp32_camera_web_server.rst
+++ b/components/esp32_camera_web_server.rst
@@ -3,7 +3,7 @@ ESP32 Camera Web Server Component
 
 .. seo::
     :description: Instructions for setting up the ESP32 Camera Web Server in ESPHome
-    :image: camera.png
+    :image: camera.svg
 
 The ``esp32_camera_web_server`` component allows you to use expose web server of
 ESP32-based camera boards in ESPHome that directly can be integrated into external
diff --git a/components/esp8266.rst b/components/esp8266.rst
index be11a4b5d..2e0f7f936 100644
--- a/components/esp8266.rst
+++ b/components/esp8266.rst
@@ -3,7 +3,7 @@ ESP8266 Platform
 
 .. seo::
     :description: Configuration for the ESP8266 platform for ESPHome.
-    :image: esp8266.png
+    :image: esp8266.svg
 
 This component contains platform-specific options for the ESP8266 platform.
 
@@ -20,11 +20,11 @@ Configuration variables:
 
 - **board** (**Required**, string): The PlatformIO board ID that should
   be used. Choose the appropriate board from
-  `this list <https://platformio.org/boards?count=1000&filter%5Bplatform%5D=espressif8266>`__. 
+  `this list <https://platformio.org/boards?count=1000&filter%5Bplatform%5D=espressif8266>`__.
   *This only affects pin aliases, flash size and some internal settings*, if unsure choose a generic board.
 - **framework** (*Optional*): Options for the underlying framework used by ESPHome.
 
-  - **version** (*Optional*, string): The base framework version number to use, from 
+  - **version** (*Optional*, string): The base framework version number to use, from
     `esp8266 arduino releases <https://github.com/esp8266/Arduino/releases>`__. Defaults to ``recommended``. Additional values
 
     - ``dev``: Use the latest commit from https://github.com/esp8266/Arduino, note this may break at any time
diff --git a/components/esphome.rst b/components/esphome.rst
index 9803dc028..ff32da635 100644
--- a/components/esphome.rst
+++ b/components/esphome.rst
@@ -3,7 +3,7 @@ ESPHome Core Configuration
 
 .. seo::
     :description: Instructions for setting up the core ESPHome configuration.
-    :image: cloud-circle.png
+    :image: cloud-circle.svg
 
 Here you specify some core information that ESPHome needs to create
 firmwares. Most importantly, this is the section of the configuration
diff --git a/components/ethernet.rst b/components/ethernet.rst
index 74127a50f..1a296c886 100644
--- a/components/ethernet.rst
+++ b/components/ethernet.rst
@@ -3,7 +3,7 @@ Ethernet Component
 
 .. seo::
     :description: Instructions for setting up the Ethernet configuration for your ESP32 node in ESPHome.
-    :image: ethernet.png
+    :image: ethernet.svg
     :keywords: Ethernet, ESP32
 
 This core ESPHome component sets up ethernet connections for ESP32s.
diff --git a/components/external_components.rst b/components/external_components.rst
index 94931bf30..efc31ca89 100644
--- a/components/external_components.rst
+++ b/components/external_components.rst
@@ -42,6 +42,8 @@ Configuration variables:
 
   - **url** (**Required**, url): HTTP git repository url. See :ref:`external-components_git`.
   - **ref** (*Optional*, string): Git ref (branch or tag). If not specified the default branch is used.
+  - **username** (*Optional*, string): Username for the Git server, if one is required
+  - **password** (*Optional*, string): Password for the Git server, if one is required
 
   local options:
 
@@ -182,6 +184,12 @@ folder and components will then be loaded from this local copy. The local path o
 varies per repository name and ref name, so repositories with different refs are considered different
 repositories and updated independently.
 
+If required, you can supply a username and password to use when authenticating with the remote git
+server using the ``username`` and ``password`` fields. This is most useful when combined with the
+``!secret``  feature, to load the values in from a ``secrets.yaml`` file. This is not a comprehensive
+security measure; your username and password will necessarily be stored in clear text within the
+``.esphome`` directory.
+
 .. _external-components_refresh:
 
 Refresh
diff --git a/components/fan/binary.rst b/components/fan/binary.rst
index 62bccd49c..78e967d09 100644
--- a/components/fan/binary.rst
+++ b/components/fan/binary.rst
@@ -3,7 +3,7 @@ Binary Fan
 
 .. seo::
     :description: Instructions for setting up binary fans.
-    :image: fan.png
+    :image: fan.svg
 
 The ``binary`` fan platform lets you represent any binary :ref:`output` as a fan.
 
diff --git a/components/fan/hbridge.rst b/components/fan/hbridge.rst
index f0f827748..cf04d1f7c 100644
--- a/components/fan/hbridge.rst
+++ b/components/fan/hbridge.rst
@@ -3,7 +3,7 @@ H-bridge Fan
 
 .. seo::
     :description: Instructions for setting up hbridge controlled fans (or motors).
-    :image: fan.png
+    :image: fan.svg
 
 The `'hbridge`' fan platform allows you to use a compatible `h-bridge` (L298N, DRV8871, MX1508, BTS7960, L9110S, DRV8833, TB6612, etc.) to control a fan (or motor/solenoid).
 
diff --git a/components/fan/index.rst b/components/fan/index.rst
index 33e2df0e4..4809f2432 100644
--- a/components/fan/index.rst
+++ b/components/fan/index.rst
@@ -3,7 +3,7 @@ Fan Component
 
 .. seo::
     :description: Instructions for setting up the base fan component.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 With the ``fan`` domain you can create components that appear as fans in
 the Home Assistant frontend. A fan can be switched ON or OFF, optionally
diff --git a/components/fan/speed.rst b/components/fan/speed.rst
index b9080022d..9969d0cdc 100644
--- a/components/fan/speed.rst
+++ b/components/fan/speed.rst
@@ -3,7 +3,7 @@ Speed Fan
 
 .. seo::
     :description: Instructions for setting up speed-controllable fans.
-    :image: fan.png
+    :image: fan.svg
 
 The ``speed`` fan platform lets you represent any float :ref:`output` as a fan that
 supports speed settings.
diff --git a/components/fingerprint_grow.rst b/components/fingerprint_grow.rst
index 9a5813a1c..6edddd3ff 100644
--- a/components/fingerprint_grow.rst
+++ b/components/fingerprint_grow.rst
@@ -3,7 +3,7 @@ Grow Fingerprint Reader
 
 .. seo::
     :description: Instructions for setting up Grow Fingerprint Reader integration in ESPHome.
-    :image: fingerprint.png
+    :image: fingerprint.svg
 
 The ``fingerprint_grow`` component allows you to use your R307, R503, ZFM-20, ... fingerprint sensors with ESPHome.
 
diff --git a/components/gps.rst b/components/gps.rst
index 648080349..d219b7d34 100644
--- a/components/gps.rst
+++ b/components/gps.rst
@@ -3,7 +3,7 @@ GPS Component
 
 .. seo::
     :description: Instructions for setting up GPS integration in ESPHome.
-    :image: crosshair-gps.png
+    :image: crosshairs-gps.svg
 
 The ``gps`` component allows you to connect GPS modules to your ESPHome project.
 Any GPS module that uses the standardized NMEA communication protocol will work.
diff --git a/components/http_request.rst b/components/http_request.rst
index 3de5b8b54..ff1813f4e 100644
--- a/components/http_request.rst
+++ b/components/http_request.rst
@@ -3,7 +3,7 @@ HTTP Request
 
 .. seo::
     :description: Instructions for setting up HTTP Requests in ESPHome
-    :image: connection.png
+    :image: connection.svg
     :keywords: http, request
 
 
diff --git a/components/i2c.rst b/components/i2c.rst
index 5f1bfcb8c..0ae58c066 100644
--- a/components/i2c.rst
+++ b/components/i2c.rst
@@ -5,7 +5,7 @@ I²C Bus
 
 .. seo::
     :description: Instructions for setting up the I²C bus to communicate with 2-wire devices in ESPHome
-    :image: i2c.png
+    :image: i2c.svg
     :keywords: i2c, iic, bus
 
 This component sets up the I²C bus for your ESP32 or ESP8266. In order for these components
diff --git a/components/index.rst b/components/index.rst
index 94727541d..3bc1dc371 100644
--- a/components/index.rst
+++ b/components/index.rst
@@ -14,6 +14,7 @@ Components
     select/index
     sensor/index
     switch/index
+    button/index
     display/index
     text_sensor/index
     stepper/index
diff --git a/components/light/binary.rst b/components/light/binary.rst
index 42bff3c7b..43e1ee7bc 100644
--- a/components/light/binary.rst
+++ b/components/light/binary.rst
@@ -3,7 +3,7 @@ Binary Light
 
 .. seo::
     :description: Instructions for setting up binary ON/OFF lights in ESPHome.
-    :image: lightbulb.png
+    :image: lightbulb.svg
 
 The ``binary`` light platform creates a simple ON/OFF-only light from a
 :ref:`binary output component <output>`.
diff --git a/components/light/color_temperature.rst b/components/light/color_temperature.rst
index 4689b9653..b66a94248 100644
--- a/components/light/color_temperature.rst
+++ b/components/light/color_temperature.rst
@@ -3,7 +3,7 @@ Color Temperature Light
 
 .. seo::
     :description: Instructions for setting up Color Temperature lights.
-    :image: brightness-medium.png
+    :image: brightness-medium.svg
 
 The ``color_temperature`` light platform creates a Color Temperature
 light from 2 :ref:`float output components <output>`. One channel controls the LED temperature,
diff --git a/components/light/cwww.rst b/components/light/cwww.rst
index 6c008644e..66fb02edb 100644
--- a/components/light/cwww.rst
+++ b/components/light/cwww.rst
@@ -3,7 +3,7 @@ Cold White + Warm White Light
 
 .. seo::
     :description: Instructions for setting up Cold White + Warm White lights.
-    :image: brightness-medium.png
+    :image: brightness-medium.svg
 
 The ``cwww`` light platform creates a cold white + warm white light from 2
 :ref:`float output components <output>` (one for each channel). The two channels
diff --git a/components/light/fastled.rst b/components/light/fastled.rst
index 271e7ffad..a7a1e8171 100644
--- a/components/light/fastled.rst
+++ b/components/light/fastled.rst
@@ -3,7 +3,7 @@ FastLED Light
 
 .. seo::
     :description: Instructions for setting up FastLED addressable lights like NEOPIXEL.
-    :image: color_lens.png
+    :image: color_lens.svg
 
 .. _fastled-clockless:
 
diff --git a/components/light/hbridge.rst b/components/light/hbridge.rst
index 5b5f0236d..6dcd095d6 100644
--- a/components/light/hbridge.rst
+++ b/components/light/hbridge.rst
@@ -3,7 +3,7 @@ H-bridge Light
 
 .. seo::
     :description: Instructions for setting up a hbridge light.
-    :image: brightness-medium.png
+    :image: brightness-medium.svg
 
 The ``hbridge`` light platform creates a dual color brightness controlled light from two
 :ref:`float output component <output>`.
diff --git a/components/light/index.rst b/components/light/index.rst
index 4d3fc22c9..5f079403a 100644
--- a/components/light/index.rst
+++ b/components/light/index.rst
@@ -3,7 +3,7 @@ Light Component
 
 .. seo::
     :description: Instructions for setting up lights and light effects in ESPHome.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 The ``light`` domain in ESPHome lets you create lights that will
 automatically be shown in Home Assistant’s frontend and have many
diff --git a/components/light/monochromatic.rst b/components/light/monochromatic.rst
index 65b850246..2b86555d2 100644
--- a/components/light/monochromatic.rst
+++ b/components/light/monochromatic.rst
@@ -3,7 +3,7 @@ Monochromatic Light
 
 .. seo::
     :description: Instructions for setting up monochromatic (brightness-only) lights.
-    :image: brightness-medium.png
+    :image: brightness-medium.svg
 
 The ``monochromatic`` light platform creates a simple brightness-only light from an
 :ref:`float output component <output>`.
diff --git a/components/light/neopixelbus.rst b/components/light/neopixelbus.rst
index ade5afe86..b136d5ab2 100644
--- a/components/light/neopixelbus.rst
+++ b/components/light/neopixelbus.rst
@@ -3,7 +3,7 @@ NeoPixelBus Light
 
 .. seo::
     :description: Instructions for setting up Neopixel addressable lights.
-    :image: color_lens.png
+    :image: color_lens.svg
 
 The ``neopixelbus`` light platform allows you to create RGB lights
 in ESPHome for an individually addressable lights like NeoPixel or WS2812.
diff --git a/components/light/partition.rst b/components/light/partition.rst
index 0c27a9c01..a5544cb45 100644
--- a/components/light/partition.rst
+++ b/components/light/partition.rst
@@ -3,7 +3,7 @@ Light Partition
 
 .. seo::
     :description: Instructions for setting up light partitions.
-    :image: color_lens.png
+    :image: color_lens.svg
 
 The ``partition`` light platform allows you to combine multiple addressable light segments
 (like :doc:`fastled` or :doc:`neopixelbus`) and/or individual lights (like :doc:`rgb`) into a single addressable light.
diff --git a/components/light/status_led.rst b/components/light/status_led.rst
index c6157e4e4..7dc670a90 100644
--- a/components/light/status_led.rst
+++ b/components/light/status_led.rst
@@ -3,14 +3,14 @@ Status LED Light
 
 .. seo::
     :description: Instructions for setting up a Status LED shared also as binary ON/OFF light in ESPHome.
-    :image: led-on.png
+    :image: led-on.svg
 
 The ``status_led`` light platform allows to share a single LED for indicating the status of
-the device (when on error/warning state) or as binary light (when on OK state). 
+the device (when on error/warning state) or as binary light (when on OK state).
 This is useful for devices with only one LED available.
 
-It provides the combined functionality of :doc:`status_led component </components/status_led>` and a 
-:doc:`binary light component </components/light/binary>` over a single shared GPIO led. 
+It provides the combined functionality of :doc:`status_led component </components/status_led>` and a
+:doc:`binary light component </components/light/binary>` over a single shared GPIO led.
 
 When the device is on error/warning state, the function of ``status_led`` will take precedence and control the blinking of the LED.
 When the device is in OK state, the LED will be restored to the state of the ``binary light`` function and can be controlled as such.
@@ -26,7 +26,7 @@ When the device is in OK state, the LED will be restored to the state of the ``b
 .. note::
 
     When using this platform the high level ``status_led`` component should not be included (at least over the same pin),
-    as its functionality is directly provided by this platform. 
+    as its functionality is directly provided by this platform.
 
     The only difference is that the platform won't be loaded in OTA safe mode, while the component would be.
 
diff --git a/components/light/tuya.rst b/components/light/tuya.rst
index 699690896..4838e7456 100644
--- a/components/light/tuya.rst
+++ b/components/light/tuya.rst
@@ -3,7 +3,7 @@ Tuya Dimmer
 
 .. seo::
     :description: Instructions for setting up a Tuya dimmer switch.
-    :image: brightness-medium.png
+    :image: brightness-medium.svg
 
 The ``tuya`` light platform creates a simple brightness-only light from a
 tuya serial component.
diff --git a/components/logger.rst b/components/logger.rst
index 80d93023c..243202470 100644
--- a/components/logger.rst
+++ b/components/logger.rst
@@ -3,7 +3,7 @@ Logger Component
 
 .. seo::
     :description: Instructions for setting up the central logging component in ESPHome.
-    :image: file-document-box.png
+    :image: file-document-box.svg
 
 The logger component automatically logs all log messages through the
 serial port and through MQTT topics. By default, all logs with a
diff --git a/components/mcp230xx.rst b/components/mcp230xx.rst
index 38cf5d124..55d04c78d 100644
--- a/components/mcp230xx.rst
+++ b/components/mcp230xx.rst
@@ -3,7 +3,7 @@ MCP230xx I/O Expander
 
 .. seo::
     :description: Instructions for setting up MCP23008, MCP23016 or MCP23017 digital port expander in ESPHome.
-    :image: mcp230xx.png
+    :image: mcp230xx.svg
 
 The Microchip MCP230xx series of general purpose, parallel I/O expansion for I²C bus applications.
 
diff --git a/components/mcp23Sxx.rst b/components/mcp23Sxx.rst
index ac7effa6e..b4863ecf9 100644
--- a/components/mcp23Sxx.rst
+++ b/components/mcp23Sxx.rst
@@ -3,7 +3,7 @@ MCP23Sxx I/O Expander
 
 .. seo::
     :description: Instructions for setting up MCP23S08, MCP23S16 or MCP23S17 digital port expander in ESPHome. This is exactly the same API as the MCP23SXX I/O Expander except talks on the SPI bus
-    :image: mcp23Sxx.png
+    :image: mcp230xx.svg
 
 The Microchip MCP23Sxx series of general purpose, parallel I/O expansion for SPI bus applications.
 This is exactly the same API as the MCP23SXX I/O Expander except talks on the SPI bus
diff --git a/components/mdns.rst b/components/mdns.rst
index 7ceb3994f..4abc18dbc 100644
--- a/components/mdns.rst
+++ b/components/mdns.rst
@@ -3,7 +3,7 @@ mDNS Component
 
 .. seo::
     :description: Instructions for setting up the mDNS configuration for your ESP node in ESPHome.
-    :image: mdns.svg
+    :image: radio-tower.svg
     :keywords: WiFi, WLAN, ESP8266, ESP32, mDNS
 
 The ``mdns`` component makes the node announce itself on the local network using the multicast DNS (mDNS) protocol.
diff --git a/components/modbus_controller.rst b/components/modbus_controller.rst
index de7d9a1e2..bf99dbd6f 100644
--- a/components/modbus_controller.rst
+++ b/components/modbus_controller.rst
@@ -7,10 +7,6 @@ Modbus Controller
 
 The ``modbus_controller`` component creates a RS485 connection to control a modbus device
 
-.. warning::
-
-    If you are using the :doc:`logger` uart logging might interfere especially on esp8266. You can disable the uart logging with the ``baud_rate: 0`` option.
-
 .. figure:: /images/modbus.png
     :align: center
     :width: 25%
@@ -29,6 +25,25 @@ See [How is this RS485 Module Working?](https://electronics.stackexchange.com/qu
 
 The controller connects to the UART of the MCU. For ESP32  GPIO PIN 16 to TXD PIN 17 to RXD are the default ports but any other pins can be used as well . 3.3V to VCC and GND to GND.
 
+.. note::
+
+    If you are using an ESP8266, serial logging may cause problems reading from UART. For best results, hardware serial is recommended. Software serial may not be able to read all received data if other components spend a lot of time in the ``loop()``.
+    
+    For hardware serial only a limited set of pins can be used. Either ``tx_pin: GPIO1`` and ``rx_pin: GPIO3``  or ``tx_pin: GPIO15`` and ``rx_pin: GPIO13``.
+    
+    The disadvantage of using the hardware uart is that you can't use serial logging because the serial logs would be sent to the modbus device and cause errors.
+    
+    Serial logging can be disabled by setting ``baud_rate: 0``.
+    
+    See :doc:`logger` for more details
+
+    .. code-block:: yaml
+
+        logger:
+            level: <level>
+            baud_rate: 0
+
+
 
 Configuration variables:
 ------------------------
@@ -42,8 +57,8 @@ Configuration variables:
   Because some modbus devices limit the rate of requests the interval between sending requests to the device can be modified.
 
 
-Getting started with Home Assistant
------------------------------------
+Example
+-------
 The following code create a modbus_controller hub talking to a modbus device at address 1 with 115200 bps
 
 
diff --git a/components/mqtt.rst b/components/mqtt.rst
index 40b36ebe7..a25bc5512 100644
--- a/components/mqtt.rst
+++ b/components/mqtt.rst
@@ -43,6 +43,10 @@ Configuration variables:
 - **discovery_prefix** (*Optional*, string): The prefix to use for Home
   Assistant’s MQTT discovery. Should not contain trailing slash.
   Defaults to ``homeassistant``.
+- **discovery_unique_id_generator** (*Optional*, string): The unique_id generator
+  to use. Can be one of ``legacy`` or ``mac``. Defaults to ``legacy``, which
+  generates unique_id in format ``ESP<component_type><default_object_id>``.
+  ``mac`` generator uses format ``<mac_address>-<component_type>-<fnv1_hash(friendly_name)>``.
 - **use_abbreviations** (*Optional*, boolean): Whether to use
   `Abbreviations <https://www.home-assistant.io/docs/mqtt/discovery/>`__
   in discovery messages. Defaults to ``true``.
diff --git a/components/number/index.rst b/components/number/index.rst
index c386efb32..aedf60267 100644
--- a/components/number/index.rst
+++ b/components/number/index.rst
@@ -3,7 +3,7 @@ Number Component
 
 .. seo::
     :description: Instructions for setting up number components in ESPHome.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 ESPHome has support for components to create a number entity. A number entity is
 like a sensor that can read a value from a device, but is useful when that value
@@ -42,6 +42,12 @@ Configuration variables:
   See https://developers.home-assistant.io/docs/core/entity/#generic-properties
   for a list of available options. Requires Home Assistant 2021.11 or newer.
   Set to ``""`` to remove the default entity category.
+- **unit_of_measurement** (*Optional*, string): Manually set the unit
+  of measurement for the number. Requires Home Assistant Core 2021.12 or newer.
+- **mode** (*Optional*, string): Defines how the number should be displayed in the frontend.
+  See https://developers.home-assistant.io/docs/core/entity/number/#properties
+  for a list of available options. Requires Home Assistant Core 2021.12 or newer.
+  Defaults to ``"auto"``.
 
 Automations:
 
diff --git a/components/number/modbus_controller.rst b/components/number/modbus_controller.rst
index c573f0c6b..6d192a0bc 100644
--- a/components/number/modbus_controller.rst
+++ b/components/number/modbus_controller.rst
@@ -3,7 +3,6 @@ Modbus Controller Number
 
 .. seo::
     :description: Instructions for setting up a modbus_controller device sensor.
-    :image: modbus_controller.png
 
 The ``modbus_controller`` platform creates a Number from a modbus_controller.
 When the Number is updated a modbus write command is created sent to the device.
@@ -19,32 +18,42 @@ Configuration variables:
     - read: Read Input Registers - registers are 16-bit registers used for input, and may only be read
 - **address**: (**Required**, int): start address of the first register in a range
 - **value_type**: (**Required**): datatype of the mod_bus register data. The default data type for modbus is a 16 bit integer in big endian format (MSB first)
-    - U_WORD (unsigned float from 1 register =16bit
-    - S_WORD (signed float from one register)
-    - U_DWORD (unsigned float from 2 registers = 32bit)
-    - S_DWORD (unsigned float from 2 registers = 32bit)
-    - U_DWORD_R (unsigend float from 2 registers low word first )
-    - S_DWORD_R (sigend float from 2 registers low word first )
-    - U_QWORD (unsigned float from 4 registers = 64bit
-    - S_QWORD (signed float from 4 registers = 64bit
-    - U_QWORD_R (unsigend float from 4 registers low word first )
-    - S_QWORD_R (sigend float from 4 registers low word first )
+    - U_WORD (unsigned 16 bit integer from 1 register = 16bit)
+    - S_WORD (signed 16 bit integer from 1 register = 16bit)
+    - U_DWORD (unsigned 32 bit integer from 2 registers = 32bit)
+    - S_DWORD (signed 32 bit integer from 2 registers = 32bit)
+    - U_DWORD_R (unsigned 32 bit integer from 2 registers low word first)
+    - S_DWORD_R (signed 32 bit integer from 2 registers low word first)
+    - U_QWORD (unsigned 64 bit integer from 4 registers = 64bit)
+    - S_QWORD (unsigned 64 bit integer from 4 registers = 64bit)
+    - U_QWORD_R (unsigned 64 bit integer from 4 registers low word first)
+    - U_QWORD_R signed 64 bit integer from 4 registers low word first)
+    - FP32 (32 bit IEEE 754 floating point from 2 registers)
+    - FP32_R (32 bit IEEE 754 floating point - same as FP32 but low word first)
 
 - **skip_updates**: (*Optional*, int): By default all sensors of of a modbus_controller are updated together. For data points that don't change very frequently updates can be skipped. A value of 5 would only update this sensor range in every 5th update cycle
   Note: The modbus_controller groups component by address ranges to reduce number of transactions. All compoents with the same address will be updated in one request. skip_updates applies for all components in the same range.
-- **register_count**: (*Optional*): only required for uncommon response encodings
-  The number of registers this data point spans. Default is 1
-- **force_new_range**: (*Optional*, boolean): If possible sensors with sequential addresses are grouped together and requested in one range. Setting `foce_new_range: true` enforces the start of a new range at that address.
+- **register_count**: (*Optional*): only required for uncommon response encodings or to :ref:`optimize modbus communications<modbus_register_count>`
+  The number of registers this data point spans. Overrides the defaults determined by ``value_type``.
+  If no value for ``register_count`` is provided, it is calculated based on the register type.
+
+  The default size for 1 register is 16 bits (1 Word). Some devices are not adhering to this convention and have registers larger than 16 bits.  In this case ``register_count`` and  ``response_size`` must be set. For example, if your modbus device uses 1 registers for a FP32 value instead the default of two set ``register_count: 1`` and ``response_size: 4``.
+- **response_size**:  (*Optional*): Size of the response for the register in bytes. Defaults to register_count*2.
+- **force_new_range**: (*Optional*, boolean): If possible sensors with sequential addresses are grouped together and requested in one range. Setting ``force_new_range: true`` enforces the start of a new range at that address.
 - **offset**: (*Optional*, int): only required for uncommon response encodings
     offset from start address in bytes. If more than one register is read a modbus read registers command this value is used to find the start of this datapoint relative to start address. The component calculates the size of the range based on offset and size of the value type
 - **min_value** (*Optional*, float): The minimum value this number can be.
 - **max_value** (*Optional*, float): The maximum value this number can be.
 - **step** (*Optional*, float): The granularity with which the number can be set. Defaults to 1
+- **custom_data** (*Optional*, list of bytes): raw bytes for modbus command. This allows using non-standard commands. If ``custom_data`` is used ``address`` and ``register_type`` can't be used.
+  custom data must contain all required bytes including the modbus device address. The crc is automatically calculated and appended to the command.
+  See :ref:`modbus_custom_data` how to use ``custom_command``
 - **lambda** (*Optional*, :ref:`lambda <config-lambda>`):
   Lambda to be evaluated every update interval to get the new value of the sensor.
 - **write_lambda** (*Optional*, :ref:`lambda <config-lambda>`): Lambda called before send.
   Lambda is evaluated before the modbus write command is created.
 - **multiply** (*Optional*, float): multiply the new value with this factor before sending the requests. Ignored if lambda is defined.
+- **use_write_multiple**: (*Optional*, boolean): By default the modbus command ``Preset Single Registers`` (function code 6) is used for setting the holding register if only 1 register is set. If your device only supports ``Preset Multiple Registers`` (function code 16) set this option to true.
 
 
 All other options from :ref:`Number <config-number>`.
@@ -54,7 +63,7 @@ Parameters passed into the lambda
 - **x** (float): The parsed float value of the modbus data
 
 - **data** (std::vector<uint8_t): vector containing the complete raw modbus response bytes for this sensor
-      note: because the response contains data for all registers in the same range you have to use `data[item->offset]` to get the first response byte for your sensor.
+      note: because the response contains data for all registers in the same range you have to use ``data[item->offset]`` to get the first response byte for your sensor.
 - **item** (const pointer to a SensorItem derived object):  The sensor object itself.
 
 Possible return values for the lambda:
@@ -69,7 +78,7 @@ Possible return values for the lambda:
 - **x** (float): The float value to be sent to the modbus device
 
 - **payload** (`std::vector<uint16_t>&payload`): empty vector for the payload. The lamdba can add 16 bit raw modbus register words.
-      note: because the response contains data for all registers in the same range you have to use `data[item->offset]` to get the first response byte for your sensor.
+      note: because the response contains data for all registers in the same range you have to use ``data[item->offset]`` to get the first response byte for your sensor.
 - **item** (const pointer to a SensorItem derived object):  The sensor object itself.
 
 Possible return values for the lambda:
diff --git a/components/number/template.rst b/components/number/template.rst
index d07f1e9a1..13cbef2f7 100644
--- a/components/number/template.rst
+++ b/components/number/template.rst
@@ -3,7 +3,7 @@ Template Number
 
 .. seo::
     :description: Instructions for setting up template numbers with ESPHome.
-    :image: description.png
+    :image: description.svg
 
 The ``template`` number platform allows you to create a number with templated values
 using :ref:`lambdas <config-lambda>`.
diff --git a/components/ota.rst b/components/ota.rst
index 5cc499cea..c11fa7aa4 100644
--- a/components/ota.rst
+++ b/components/ota.rst
@@ -3,7 +3,7 @@ OTA Update Component
 
 .. seo::
     :description: Instructions for setting up Over-The-Air (OTA) updates for ESPs to upload firmwares remotely.
-    :image: system-update.png
+    :image: system-update.svg
 
 .. _config-ota:
 
diff --git a/components/output/ble_client.rst b/components/output/ble_client.rst
new file mode 100644
index 000000000..38ef7111a
--- /dev/null
+++ b/components/output/ble_client.rst
@@ -0,0 +1,43 @@
+BLE Client Binary Output
+========================
+
+.. seo::
+    :description: Writes a binary value to a BLE device.
+    :image: bluetooth.svg
+
+The ``ble_client`` component is a output that can
+write a binary value to service characteristics of
+BLE devices.
+
+For more information on BLE services and characteristics, see
+:doc:`/components/ble_client`.
+
+.. code-block:: yaml
+
+    esp32_ble_tracker:
+
+    ble_client:
+      - mac_address: FF:FF:20:00:0F:15
+        id: itag_black
+
+    output:
+      - platform: ble_client
+        ble_client_id: itag_black
+        service_uuid: "10110000-5354-4F52-5A26-4249434B454C"
+        characteristic_uuid: "10110013-5354-4f52-5a26-4249434b454c"
+
+Configuration variables:
+------------------------
+
+- **ble_client_id** (**Required**, :ref:`config-id`): ID of the associated BLE client.
+- **service_uuid** (**Required**, UUID): UUID of the service on the device.
+- **characteristic_uuid** (**Required**, UUID): UUID of the service's characteristic to write to.
+- **id** (*Optional*, :ref:`config-id`): The ID to use for code generation, and for reference by dependent components.
+- All other options from :ref:`Output <config-output>`.
+
+See Also
+--------
+
+- :doc:`/components/output/index`
+- :doc:`/components/ble_client`
+- :ghedit:`Edit`
diff --git a/components/output/gpio.rst b/components/output/gpio.rst
index 0f269617c..ba946b971 100644
--- a/components/output/gpio.rst
+++ b/components/output/gpio.rst
@@ -3,7 +3,7 @@ GPIO Output
 
 .. seo::
     :description: Instructions for setting up binary outputs for GPIO pins.
-    :image: pin.png
+    :image: pin.svg
 
 The GPIO output component is quite simple: It exposes a single GPIO pin
 as an output component. Note that output components are **not** switches and
diff --git a/components/output/index.rst b/components/output/index.rst
index 05c77ec6d..12ab21389 100644
--- a/components/output/index.rst
+++ b/components/output/index.rst
@@ -5,7 +5,7 @@ Output Component
 
 .. seo::
     :description: Instructions for setting up generic outputs in ESPHome
-    :image: folder-open.png
+    :image: folder-open.svg
 
 Each platform of the ``output`` domain exposes some output to
 ESPHome. These are grouped into two categories: ``binary`` outputs
diff --git a/components/output/mcp4725.rst b/components/output/mcp4725.rst
index 71749d428..c337bc892 100644
--- a/components/output/mcp4725.rst
+++ b/components/output/mcp4725.rst
@@ -3,7 +3,7 @@ MCP4725 Output
 
 .. seo::
     :description: Instructions for setting up MCP4725 outputs on the ESP.
-    :image: mcp4725.png
+    :image: mcp4725.jpg
 
 The MCP4725 output component allows to use `12bit external DAC
 <https://learn.sparkfun.com/tutorials/mcp4725-digital-to-analog-converter-hookup-guide/all>`__
diff --git a/components/output/modbus_controller.rst b/components/output/modbus_controller.rst
index 9196ff178..3bd20bfc9 100644
--- a/components/output/modbus_controller.rst
+++ b/components/output/modbus_controller.rst
@@ -3,7 +3,6 @@ Modbus Controller Output
 
 .. seo::
     :description: Instructions for setting up a modbus_controller device sensor.
-    :image: modbus_controller.png
 
 The ``modbus_controller`` platform creates a output from a modbus_controller.
 
@@ -14,24 +13,27 @@ Configuration variables:
 - **name** (**Required**, string): The name of the sensor.
 - **address**: (**Required**, int): start address of the first register in a range
 - **value_type**: (**Required**): datatype of the mod_bus register data. The default data type for modbus is a 16 bit integer in big endian format (MSB first)
-    - U_WORD (unsigned float from 1 register =16bit
-    - S_WORD (signed float from one register)
-    - U_DWORD (unsigned float from 2 registers = 32bit)
-    - S_DWORD (unsigned float from 2 registers = 32bit)
-    - U_DWORD_R (unsigend float from 2 registers low word first )
-    - S_DWORD_R (sigend float from 2 registers low word first )
-    - U_QWORD (unsigned float from 4 registers = 64bit
-    - S_QWORD (signed float from 4 registers = 64bit
-    - U_QWORD_R (unsigend float from 4 registers low word first )
-    - S_QWORD_R (sigend float from 4 registers low word first )
+    - U_WORD (unsigned 16 bit integer from 1 register = 16bit)
+    - S_WORD (signed 16 bit integer from 1 register = 16bit)
+    - U_DWORD (unsigned 32 bit integer from 2 registers = 32bit)
+    - S_DWORD (signed 32 bit integer from 2 registers = 32bit)
+    - U_DWORD_R (unsigned 32 bit integer from 2 registers low word first)
+    - S_DWORD_R (signed 32 bit integer from 2 registers low word first)
+    - U_QWORD (unsigned 64 bit integer from 4 registers = 64bit)
+    - S_QWORD (unsigned 64 bit integer from 4 registers = 64bit)
+    - U_QWORD_R (unsigned 64 bit integer from 4 registers low word first)
+    - U_QWORD_R signed 64 bit integer from 4 registers low word first)
+    - FP32 (32 bit IEEE 754 floating point from 2 registers)
+    - FP32_R (32 bit IEEE 754 floating point - same as FP32 but low word first)
 - **register_count**: (*Optional*): only required for uncommon response encodings
   The number of registers this data point spans. Default is 1
 - **write_lambda** (*Optional*, :ref:`lambda <config-lambda>`):
-  Lambda is evaluated before the modbus write command is created. The value is passed in as `float x` and an empty vector is passed in as `std::vector<uint16_t>&payload`
+  Lambda is evaluated before the modbus write command is created. The value is passed in as ``float x`` and an empty vector is passed in as ``std::vector<uint16_t>&payload``
   You can directly define the payload by adding data to payload then the return value is ignored and the content of payload is used.
 - **multiply** (*Optional*, float): multiply the new value with this factor before sending the requests. Ignored if lambda is defined.
 - **offset**: (*Optional*, int): only required for uncommon response encodings
     offset from start address in bytes. If more than one register is read a modbus read registers command this value is used to find the start of this datapoint relative to start address. The component calculates the size of the range based on offset and size of the value type
+- **use_write_multiple**: (*Optional*, boolean): By default the modbus command ``Preset Single Registers`` (function code 6) is used for setting the holding register if only 1 register is set. If your device only supports ``Preset Multiple Registers`` (function code 16) set this option to true.
 
 All other options from :ref:`Output <config-output>`.
 
@@ -41,7 +43,7 @@ All other options from :ref:`Output <config-output>`.
 - **x** (float): The float value to be sent to the modbus device
 
 - **payload** (`std::vector<uint16_t>&payload`): empty vector for the payload. The lamdba can add 16 bit raw modbus register words.
-      note: because the response contains data for all registers in the same range you have to use `data[item->offset]` to get the first response byte for your sensor.
+      note: because the response contains data for all registers in the same range you have to use ``data[item->offset]`` to get the first response byte for your sensor.
 - **item** (const pointer to a SensorItem derived object):  The sensor object itself.
 
 Possible return values for the lambda:
diff --git a/components/output/my9231.rst b/components/output/my9231.rst
index 2101752da..c3889ed75 100644
--- a/components/output/my9231.rst
+++ b/components/output/my9231.rst
@@ -3,7 +3,7 @@ MY9231/MY9291 LED driver
 
 .. seo::
     :description: Instructions for setting up MY9231 and MY9291 LED drives in ESPHome.
-    :image: my9231.png
+    :image: my9231.svg
     :keywords: MY9231, MY9291, Sonoff B1, Ai-thinker AiLight WiFi light bulb, Arilux E27 Smart Bulb
 
 .. _my9231-component:
diff --git a/components/output/sm16716.rst b/components/output/sm16716.rst
index 837d15b76..bab404c31 100644
--- a/components/output/sm16716.rst
+++ b/components/output/sm16716.rst
@@ -3,7 +3,7 @@ SM16716 LED driver
 
 .. seo::
     :description: Instructions for setting up SM16716 LED drivers in ESPHome.
-    :image: sm16716.png
+    :image: sm16716.svg
     :keywords: SM16716, Feit Electric A19 Smart WiFi Bulb, Merkury Innovations A21 Smart Wi-Fi Bulb
 
 .. _sm16716-component:
diff --git a/components/output/template.rst b/components/output/template.rst
index 5edda1d9c..6a60c249a 100644
--- a/components/output/template.rst
+++ b/components/output/template.rst
@@ -3,7 +3,7 @@ Template Output
 
 .. seo::
     :description: Instructions for setting up template outputs with ESPHome.
-    :image: description.png
+    :image: description.svg
 
 The ``template`` output component can be used to create templated binary and float outputs in ESPHome.
 
diff --git a/components/output/tlc5947.rst b/components/output/tlc5947.rst
index 7a456f857..57b84345d 100644
--- a/components/output/tlc5947.rst
+++ b/components/output/tlc5947.rst
@@ -3,7 +3,7 @@ TLC5947 LED driver
 
 .. seo::
     :description: Instructions for setting up TLC5947 LED drivers in ESPHome.
-    :image: images/tlc5947.jpg
+    :image: tlc5947.jpg
     :keywords: tlc5947,
 
 .. _tlc5947-component:
diff --git a/components/power_supply.rst b/components/power_supply.rst
index 5a33a2e38..b08311ee5 100644
--- a/components/power_supply.rst
+++ b/components/power_supply.rst
@@ -3,7 +3,7 @@ Power Supply Component
 
 .. seo::
     :description: Instructions for setting up power supplies which will automatically turn on together with outputs.
-    :image: power.png
+    :image: power.svg
     :keywords: power, ATX
 
 The ``power_supply`` component allows you to have a high power mode for
diff --git a/components/prometheus.rst b/components/prometheus.rst
index e49480ac9..acc4b5fbc 100644
--- a/components/prometheus.rst
+++ b/components/prometheus.rst
@@ -3,7 +3,7 @@ Prometheus Component
 
 .. seo::
     :description: Instructions for setting up a prometheus exporter with ESPHome.
-    :image: prometheus.png
+    :image: prometheus.svg
 
 The ``prometheus`` component enables an HTTP endpoint for the
 :doc:`web_server` in order to integrate a `Prometheus <https://prometheus.io/>`__ installation.
diff --git a/components/remote_receiver.rst b/components/remote_receiver.rst
index 77f76b5f1..eb193ea5e 100644
--- a/components/remote_receiver.rst
+++ b/components/remote_receiver.rst
@@ -3,7 +3,7 @@ Remote Receiver
 
 .. seo::
     :description: Instructions for setting up remote receiver binary sensors for infrared and RF codes.
-    :image: remote.png
+    :image: remote.svg
     :keywords: RF, infrared
 
 The ``remote_receiver`` component lets you receive and decode any remote signal, these can
@@ -71,6 +71,13 @@ Automations:
 - **on_nec** (*Optional*, :ref:`Automation <automation>`): An automation to perform when a
   NEC remote code has been decoded. A variable ``x`` of type :apistruct:`remote_base::NECData`
   is passed to the automation for use in lambdas.
+
+  .. note::
+
+      In version 2021.12, the order of transferring bits was corrected from MSB to LSB in accordance with the NEC standard.
+      Therefore, if the the configuration file has come from an earlier version of ESPhome, it is necessary to reverse the order of the address and command bits when moving to 2021.12 or above.
+      For example, address: 0x84ED, command: 0x13EC becomes 0xB721 and 0x37C8 respectively.
+
 - **on_sony** (*Optional*, :ref:`Automation <automation>`): An automation to perform when a
   Sony remote code has been decoded. A variable ``x`` of type :apistruct:`remote_base::SonyData`
   is passed to the automation for use in lambdas.
@@ -152,6 +159,12 @@ Remote code selection (exactly one of these has to be included):
 
 - **nec**: Trigger on a decoded NEC remote code with the given data.
 
+  .. note::
+
+      In version 2021.12, the order of transferring bits was corrected from MSB to LSB in accordance with the NEC standard.
+      Therefore, if the the configuration file has come from an earlier version of ESPhome, it is necessary to reverse the order of the address and command bits when moving to 2021.12 or above.
+      For example, address: 0x84ED, command: 0x13EC becomes 0xB721 and 0x37C8 respectively.
+
   - **address** (**Required**, int): The address to trigger on, see dumper output for more info.
   - **command** (**Required**, int): The NEC command to listen for.
 
diff --git a/components/remote_transmitter.rst b/components/remote_transmitter.rst
index 56c08e26c..8655a3419 100644
--- a/components/remote_transmitter.rst
+++ b/components/remote_transmitter.rst
@@ -3,7 +3,7 @@ Remote Transmitter
 
 .. seo::
     :description: Instructions for setting up switches that send out pre-defined sequences of IR or RF signals
-    :image: remote.png
+    :image: remote.svg
     :keywords: Infrared, IR, RF, Remote, TX
 
 The ``remote_transmitter`` component lets you send digital packets to control
@@ -183,6 +183,12 @@ Configuration variables:
 
 This :ref:`action <config-action>` sends an NEC infrared remote code to a remote transmitter.
 
+.. note::
+
+    In version 2021.12, the order of transferring bits was corrected from MSB to LSB in accordance with the NEC standard.
+    Therefore, if the the configuration file has come from an earlier version of ESPhome, it is necessary to reverse the order of the address and command bits when moving to 2021.12 or above.
+    For example, address: 0x84ED, command: 0x13EC becomes 0xB721 and 0x37C8 respectively.
+
 .. code-block:: yaml
 
     on_...:
diff --git a/components/rtttl.rst b/components/rtttl.rst
index cc6b88fa6..1b71b8b76 100644
--- a/components/rtttl.rst
+++ b/components/rtttl.rst
@@ -3,7 +3,7 @@ Rtttl Buzzer
 
 .. seo::
     :description: Instructions for setting up a buzzer to play tones and rtttl songs with ESPHome.
-    :image: crosshair-gps.png
+    :image: buzzer.jpg
 
 The ``rtttl``, component allows you to easily connect a passive piezo buzzer to your microcontroller
 and play monophonic songs. It accepts the Ring Tone Text Transfer Language, rtttl format (`Wikipedia
diff --git a/components/select/index.rst b/components/select/index.rst
index 8ef140408..450d4bac1 100644
--- a/components/select/index.rst
+++ b/components/select/index.rst
@@ -3,7 +3,7 @@ Select Component
 
 .. seo::
     :description: Instructions for setting up select components in ESPHome.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 ESPHome has support for components to create a select entity. A select entity is
 basically an option list that can be set by either yaml, hardware or the user/frontend.
diff --git a/components/select/template.rst b/components/select/template.rst
index 23cb9126d..c6d011cb1 100644
--- a/components/select/template.rst
+++ b/components/select/template.rst
@@ -3,7 +3,7 @@ Template Select
 
 .. seo::
     :description: Instructions for setting up Template Select(s) with ESPHome.
-    :image: description.png
+    :image: description.svg
 
 The ``template`` Select platform allows you to create a Select with templated values
 using :ref:`lambdas <config-lambda>`.
diff --git a/components/sensor/adc.rst b/components/sensor/adc.rst
index 505ae08f4..bd3cb5f8d 100644
--- a/components/sensor/adc.rst
+++ b/components/sensor/adc.rst
@@ -3,7 +3,7 @@ Analog To Digital Sensor
 
 .. seo::
     :description: Instructions for setting up built-in analog voltage sensors.
-    :image: flash.png
+    :image: flash.svg
 
 The Analog To Digital (``adc``) Sensor allows you to use the built-in
 ADC in your device to measure a voltage on certain pins. On the ESP8266
diff --git a/components/sensor/ade7953.rst b/components/sensor/ade7953.rst
index 94f661596..e9fb99ac9 100644
--- a/components/sensor/ade7953.rst
+++ b/components/sensor/ade7953.rst
@@ -3,7 +3,7 @@ ADE7953 Power Sensor
 
 .. seo::
     :description: Instructions for setting up ADE7953 power sensors
-    :image: ade7953.png
+    :image: ade7953.svg
 
 .. note::
 
diff --git a/components/sensor/am43.rst b/components/sensor/am43.rst
index e0fcc6192..108c75f5e 100644
--- a/components/sensor/am43.rst
+++ b/components/sensor/am43.rst
@@ -3,7 +3,7 @@ AM43 Sensor
 
 .. seo::
     :description: Sensors on AM43/BLE covers in ESPHome.
-    :image: am43.png
+    :image: am43.jpg
 
 The ``am43`` sensor platform allows you to read the light and
 battery sensors on an AM43 BLE cover motor. The platform connects
diff --git a/components/sensor/as3935.rst b/components/sensor/as3935.rst
index 5868e5014..0d770e66e 100644
--- a/components/sensor/as3935.rst
+++ b/components/sensor/as3935.rst
@@ -3,7 +3,7 @@ AMS AS3935 Franklin Lightning Sensor
 
 .. seo::
     :description: Instructions for setting up AS3935 lightning sensor
-    :image: images/as3935.jpg
+    :image: as3935.jpg
     :keywords: as3935
 
 The **AS3935** sensor platform allows you to use your AS3935 sensor
diff --git a/components/sensor/atm90e32.rst b/components/sensor/atm90e32.rst
index 07509a624..84ac5ede2 100644
--- a/components/sensor/atm90e32.rst
+++ b/components/sensor/atm90e32.rst
@@ -3,7 +3,7 @@ ATM90E32 Power Sensor
 
 .. seo::
     :description: Instructions for setting up ATM90E32 energy metering sensors
-    :image: atm90e32.png
+    :image: atm90e32.jpg
     :keywords: ATM90E32, CircuitSetup, Split Single Phase Real Time Whole House Energy Meter, Expandable 6 Channel ESP32 Energy Meter Main Board
 
 The ``atm90e32`` sensor platform allows you to use your ATM90E32 voltage/current and power sensors
diff --git a/components/sensor/ble_rssi.rst b/components/sensor/ble_rssi.rst
index 7c8a9f665..3e880aec4 100644
--- a/components/sensor/ble_rssi.rst
+++ b/components/sensor/ble_rssi.rst
@@ -3,7 +3,7 @@ ESP32 Bluetooth Low Energy RSSI Sensor
 
 .. seo::
     :description: Instructions for setting up RSSI sensors for the ESP32 BLE.
-    :image: bluetooth.png
+    :image: bluetooth.svg
     :keywords: ESP32
 
 The ``ble_rssi`` sensor platform lets you track the RSSI value or signal strength of a
diff --git a/components/sensor/cse7761.rst b/components/sensor/cse7761.rst
index 999047aa8..64bb889c0 100644
--- a/components/sensor/cse7761.rst
+++ b/components/sensor/cse7761.rst
@@ -3,7 +3,7 @@ CSE7761 Power Sensor
 
 .. seo::
     :description: Instructions for setting up CSE7761 power sensors for the Sonoff Dual R3 v1.x
-    :image: cse7761.png
+    :image: cse7761.svg
     :keywords: cse7761, Sonoff Dual R3
 
 The ``cse7761`` sensor platform allows you to use your CSE7761 voltage/current and power sensors
diff --git a/components/sensor/cse7766.rst b/components/sensor/cse7766.rst
index 642ea7ca6..c6172b471 100644
--- a/components/sensor/cse7766.rst
+++ b/components/sensor/cse7766.rst
@@ -3,7 +3,7 @@ CSE7766 Power Sensor
 
 .. seo::
     :description: Instructions for setting up CSE7766 power sensors for the Sonoff Pow R2
-    :image: cse7766.png
+    :image: cse7766.svg
     :keywords: cse7766, cse7759b, Sonoff Pow R2
 
 The ``cse7766`` sensor platform allows you to use your CSE7766 voltage/current and power sensors
@@ -38,7 +38,8 @@ Additionally, you need to set the baud rate to 4800.
           name: "Sonoff Pow R2 Voltage"
         power:
           name: "Sonoff Pow R2 Power"
-
+        energy:
+          name: "Sonoff Pow R2 Energy"
 .. note::
 
     The configuration above should work for Sonoff POWs (R2).
@@ -52,6 +53,8 @@ Configuration variables:
   :ref:`Sensor <config-sensor>`.
 - **voltage** (*Optional*): Use the voltage value of the sensor in V (RMS).
   All options from :ref:`Sensor <config-sensor>`.
+- **energy** (*Optional*): Use the total energy value of the sensor in Wh.
+  All options from :ref:`Sensor <config-sensor>`.
 - **update_interval** (*Optional*, :ref:`config-time`): The interval to check the
   sensor. Defaults to ``60s``.
 - **uart_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the :ref:`UART Component <uart>` if you want
diff --git a/components/sensor/custom.rst b/components/sensor/custom.rst
index 7e26b97d0..6fa2d7eb4 100644
--- a/components/sensor/custom.rst
+++ b/components/sensor/custom.rst
@@ -3,7 +3,7 @@ Custom Sensor Component
 
 .. seo::
     :description: Instructions for setting up Custom C++ sensors with ESPHome.
-    :image: language-cpp.png
+    :image: language-cpp.svg
     :keywords: C++, Custom
 
 .. warning::
diff --git a/components/sensor/dsmr.rst b/components/sensor/dsmr.rst
index 8f4360385..fad03ef67 100644
--- a/components/sensor/dsmr.rst
+++ b/components/sensor/dsmr.rst
@@ -3,10 +3,10 @@ DSMR Component
 
 .. seo::
     :description: Instructions for setting up DSMR Meter component in ESPHome.
-    :image: dsmr.png
+    :image: dsmr.svg
 
 Component/Hub
-*************
+-------------
 
 The DSMR component connects to Dutch Smart Meters which comply to DSMR (Dutch Smart Meter
 Requirements), also known as ‘Slimme meter’ or ‘P1 port’.
@@ -46,11 +46,22 @@ Configuration variables:
 - **gas_mbus_id** (*Optional*, int): The id of the gas meter. Defaults to ``1``.
 - **crc_check** (*Optional*, boolean): Specifies if the CRC check must be done. This is required to be set to false for
   older DSMR versions as they do not provide a CRC. Defaults to ``true``.
+- **max_telegram_length** (*Optional*, integer): The size of the buffer used for reading DSMR telegrams. Increase
+  if you are reading from a smart meter that sends large telegrams. Defaults to ``1500``.
 - **uart_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the UART hub.
+- **request_pin** (*Optional*, :ref:`Pin Schema <config-pin_schema>`): The pin that can be used for controlling
+  the P1 port's Data Request pin. Defaults to not using a Data Request pin.
+  See :ref:`Using the P1 Data Request pin <sensor-dsmr-request_pin>`.
+- **request_interval** (*Optional*, :ref:`config-time`): The minimum time between two telegram readings.
+  Defaults to ``0ms``, meaning that the pace at which the smart meter sends its data determines the update frequency.
+  This works best in combination with a ``request_pin``, but this option will work without one too.
+- **receive_timeout** (*Optional*, :ref:`config-time`): The timeout on incoming data while reading a telegram.
+  When no new data arrive within the given timeout, the device will consider the current telegram a loss and
+  starts looking for the header of the next telegram. Defaults to ``200ms``.
 - **id** (*Optional*, :ref:`config-id`): Manually specify the ID of the DSMR if you have multiple components.
 
 Sensor
-******
+------
 
 .. note:: Not all sensors are available on all devices.
 
@@ -206,9 +217,8 @@ Luxembourg
   - **id** (*Optional*, :ref:`config-id`): Set the ID of this sensor for use in lambdas.
   - All other options from :ref:`Sensor <config-sensor>`.
 
-
 Text Sensor
-***********
+-----------
 
 Configuration variables:
 
@@ -289,7 +299,7 @@ Belgium
   - All other options from :ref:`Text Sensor <config-text_sensor>`.
 
 Older DSMR meters support
-*************************
+-------------------------
 
 Version 2.2 is supported with the following configuration:
 
@@ -322,6 +332,90 @@ Version 2.2 is supported with the following configuration:
           name: "gas delivered raw"
 
 
+.. _sensor-dsmr-request_pin:
+
+P1 Data Request pin
+-------------------
+
+From the P1 companion guide: The P1 port is activated (start sending data) by setting "Data Request" line high
+(to +5V). While receiving data, the requesting OSM must keep the "Data Request" line activated (set to +5V).
+To stop receiving data OSM needs to drop "Data Request" line (set it to "high impedance" mode). Data transfer
+will stop immediately in such case.
+
+**Advantages when using a request pin:**
+
+- After reading a telegram, the dsmr component will stop the data transfer until the telegram has been
+  fully processed. This separates retrieving and processing data and can thus be seen as a form of
+  hardware flow control.
+- The interval at which sensor readings must be updated can be controlled cleanly by only starting a data
+  transfer when needed. This configuration option ``request_interval`` can be used to define this interval.
+
+**Required hardware support**
+
+Many DSMR reader circuits link the +5V pin of the P1 port directly to its Data Request pin. Doing this will
+make the smart meter send telegrams at a pace as defined by the smart meter firmware. For example many
+DSMR v5 meters will send a telegram every second.
+*Circuits that use this type of wiring cannot make use of the* ``request_pin`` *option.*
+
+However, when a circuit is used that allows switching the Data Request pin between +5V and high impedance
+mode from a GPIO, then this GPIO can be configured as the ``request_pin``.
+
+Best results have been achieved by using an optocoupler circuit to handle the switching. Direct GPIO output
+or a transistor-based circuit are not feasible options. Here's an example circuit design:
+
+.. figure:: images/dsmr-request-pin-circuit-example.png
+
+.. _sensor-dsmr-improving_reader_results:
+
+Improving reader results
+------------------------
+
+When telegrams are sometimes missed or when you get a lot of CRC errors, then you might have to do some
+changes to get better reader results.
+
+It is recommended to set the ``rx_buffer_size`` option of the UART bus to at least the maximum telegram size,
+which defaults to 1500 bytes. The default UART read buffer is quite small an can easily overflow, causing
+bytes of data getting lost.
+
+.. code-block:: yaml
+
+    # Example configuration
+    uart:
+      pin: D7
+      baud_rate: 115200
+      rx_buffer_size: 1700
+
+    dsmr:
+      max_telegram_length: 1700
+
+It's best when a hardware UART is used for reading the P1 data. Whether or not hardware UART is used can
+be checked in the config dump that you get when connecting to the API logger. Example logging output:
+
+.. code-block:: text
+
+    [02:38:37][C][uart.arduino_esp8266:095]: UART Bus:
+    [02:38:37][C][uart.arduino_esp8266:097]:   RX Pin: GPIO13
+    [02:38:37][C][uart.arduino_esp8266:099]:   RX Buffer Size: 1500
+    [02:38:37][C][uart.arduino_esp8266:101]:   Baud Rate: 115200 baud
+    [02:38:37][C][uart.arduino_esp8266:102]:   Data Bits: 8
+    [02:38:37][C][uart.arduino_esp8266:103]:   Parity: NONE
+    [02:38:37][C][uart.arduino_esp8266:104]:   Stop bits: 1
+    [02:38:37][C][uart.arduino_esp8266:106]:   Using hardware serial interface.
+                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When using an ESP8266, then GPIO13 (e.g. pin D7 on a D1 Mini) can be used for hardware RX. However, to
+actually make it work, serial logging must be disabled to keep the hardware UART available for D7.
+
+.. code-block:: yaml
+
+    # Example configuration for ESP8266
+    logger:
+      baud_rate: 0
+      level: DEBUG
+
+    uart:
+      pin: GPIO13
+      baud_rate: 115200
 
 See Also
 --------
diff --git a/components/sensor/duty_cycle.rst b/components/sensor/duty_cycle.rst
index eb691c216..9bed5b9c2 100644
--- a/components/sensor/duty_cycle.rst
+++ b/components/sensor/duty_cycle.rst
@@ -3,7 +3,7 @@ Duty Cycle Sensor
 
 .. seo::
     :description: Instructions for setting up duty cycle sensors in ESPHome
-    :image: percent.png
+    :image: percent.svg
 
 The duty cycle sensor allows you to measure for what percentage of time a signal
 on a GPIO pin is HIGH or LOW.
diff --git a/components/sensor/esp32_hall.rst b/components/sensor/esp32_hall.rst
index e49bb0884..00cf7a13d 100644
--- a/components/sensor/esp32_hall.rst
+++ b/components/sensor/esp32_hall.rst
@@ -3,7 +3,7 @@ ESP32 Hall Sensor
 
 .. seo::
     :description: Instructions for setting up the integrated hall-effect sensor of the ESP32.
-    :image: magnet.png
+    :image: magnet.svg
     :keywords: esp32, hall
 
 The ``esp32_hall`` sensor platform allows you to use the integrated
diff --git a/components/sensor/havells_solar.rst b/components/sensor/havells_solar.rst
index 7cfb0d496..9e6992007 100644
--- a/components/sensor/havells_solar.rst
+++ b/components/sensor/havells_solar.rst
@@ -3,7 +3,7 @@ Havells Solar
 
 .. seo::
     :description: Instructions for setting up Havells inverter reading on modbus.
-    :image: images/havellsgti5000d.jpg
+    :image: havellsgti5000d_s.jpg
     :keywords: Havells Enviro, Havells GTI
 
 The ``Havells Inverter`` sensor platform allows you to use Havells inverter data reading on modbus
diff --git a/components/sensor/hlw8012.rst b/components/sensor/hlw8012.rst
index 9a98959ed..cae261c94 100644
--- a/components/sensor/hlw8012.rst
+++ b/components/sensor/hlw8012.rst
@@ -3,7 +3,7 @@ HLW8012 Power Sensor
 
 .. seo::
     :description: Instructions for setting up HLW8012 power sensors for the Sonoff Pow R1
-    :image: hlw8012.png
+    :image: hlw8012.svg
     :keywords: HLW8012, CSE7759, BL0937, Sonoff Pow R1
 
 The ``hlw8012`` sensor platform allows you to use your HLW8012 voltage/current and power sensors
diff --git a/components/sensor/hm3301.rst b/components/sensor/hm3301.rst
index 544e75476..d6f71e7f5 100644
--- a/components/sensor/hm3301.rst
+++ b/components/sensor/hm3301.rst
@@ -3,7 +3,7 @@ The Grove - Laser PM2.5 Sensor (HM3301)
 
 .. seo::
     :description: Instructions for setting up HM3301 Particulate matter sensor
-    :image: hm3301.png
+    :image: hm3301.jpg
 
 The ``HM3301`` sensor platform allows you to use your HM3301 particulate matter sensor
 (`more info <http://wiki.seeedstudio.com/Grove-Laser_PM2.5_Sensor-HM3301>`__)
diff --git a/components/sensor/homeassistant.rst b/components/sensor/homeassistant.rst
index 67bb02a34..35f8c5d44 100644
--- a/components/sensor/homeassistant.rst
+++ b/components/sensor/homeassistant.rst
@@ -3,7 +3,7 @@ Home Assistant Sensor
 
 .. seo::
     :description: Instructions for setting up Home Assistant sensors with ESPHome that import states from your Home Assistant instance.
-    :image: home-assistant.png
+    :image: home-assistant.svg
 
 The ``homeassistant`` sensor platform allows you to create sensors that import
 states from your Home Assistant instance using the :doc:`native API </components/api>`.
diff --git a/components/sensor/hx711.rst b/components/sensor/hx711.rst
index 0cb322d43..22f17c39d 100644
--- a/components/sensor/hx711.rst
+++ b/components/sensor/hx711.rst
@@ -3,7 +3,7 @@ HX711 Load Cell Amplifier
 
 .. seo::
     :description: Instructions for setting up HX711 load cell amplifiers with ESPHome
-    :image: hx711.png
+    :image: hx711.jpg
     :keywords: HX711
 
 The ``hx711`` sensor platform allows you to use your HX711
diff --git a/components/sensor/images/dsmr-request-pin-circuit-example.png b/components/sensor/images/dsmr-request-pin-circuit-example.png
new file mode 100755
index 000000000..d900af748
Binary files /dev/null and b/components/sensor/images/dsmr-request-pin-circuit-example.png differ
diff --git a/components/sensor/index.rst b/components/sensor/index.rst
index adb63a483..595e3c54d 100644
--- a/components/sensor/index.rst
+++ b/components/sensor/index.rst
@@ -3,7 +3,7 @@ Sensor Component
 
 .. seo::
     :description: Instructions for setting up sensor components in ESPHome.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 ESPHome has support for many different sensors. Each of them is a
 platform of the ``sensor`` domain and each sensor has several base
diff --git a/components/sensor/integration.rst b/components/sensor/integration.rst
index 15f22b323..5b6ef472d 100644
--- a/components/sensor/integration.rst
+++ b/components/sensor/integration.rst
@@ -3,7 +3,7 @@ Integration Sensor
 
 .. seo::
     :description: Instructions for setting up sensors that integrate values over time.
-    :image: sigma.png
+    :image: sigma.svg
 
 The ``integration`` sensor is a helper sensor that can integrate values from other sensors over
 time. This can for example be useful to integrate the values of a water flow sensor (in m^3/s) over
diff --git a/components/sensor/ltr390.rst b/components/sensor/ltr390.rst
index 29826ca65..7933ed997 100644
--- a/components/sensor/ltr390.rst
+++ b/components/sensor/ltr390.rst
@@ -3,7 +3,7 @@ LTR390 UV and Ambient Light Sensor
 
 .. seo::
     :description: Instructions for setting up LTR390 UV and light sensor
-    :image: images/ltr390-full.jpg
+    :image: ltr390.jpg
 
 The ``ltr390`` sensor platform  allows you to use your LTR390 UV and ambient
 light sensor
diff --git a/components/sensor/max31856.rst b/components/sensor/max31856.rst
index cf966fa02..24669e62f 100644
--- a/components/sensor/max31856.rst
+++ b/components/sensor/max31856.rst
@@ -3,7 +3,7 @@ MAX31856 Thermocouple Temperature Sensor
 
 .. seo::
     :description: Instructions for setting up MAX31856 Thermocouple temperature sensors.
-    :image: max31865.png
+    :image: max31865.jpg
 
 The ``MAX31856`` temperature sensor allows you to use your MAX31856 Thermocouple
 temperature sensor (`datasheet <https://datasheets.maximintegrated.com/en/ds/MAX31856.pdf>`__) with ESPHome
diff --git a/components/sensor/mcp3008.rst b/components/sensor/mcp3008.rst
index ccb8f0976..0b05680b0 100644
--- a/components/sensor/mcp3008.rst
+++ b/components/sensor/mcp3008.rst
@@ -4,7 +4,7 @@ MCP3008 I/O Expander
 .. seo::
     :description: Instructions for setting up MCP3008 10 Bit Analog to Digital Converter in ESPHome.
     :keywords: MCP3008
-    :image: images/mcp3008.jpg
+    :image: mcp3008.jpg
 
 The Microchip Technology Inc. MCP3008
 devices are successive approximation 10-bit Analog-to-Digital (A/D) converters with on-board sample and
diff --git a/components/sensor/modbus_controller.rst b/components/sensor/modbus_controller.rst
index e55a19cc7..6e384fb01 100644
--- a/components/sensor/modbus_controller.rst
+++ b/components/sensor/modbus_controller.rst
@@ -14,29 +14,38 @@ Configuration variables:
 - **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
 - **name** (**Required**, string): The name of the sensor.
 - **register_type** (**Required**): type of the modbus register.
-    - coil: coils are also called discrete outout. Coils are 1-bit registers (on/off values) that are used to control discrete outputs. Read and Write access
-    - discrete_input: discrete input register (read only coil) are similar to coils but can only be read.
-    - holding: Holding Registers - Holding registers are the most universal 16-bit register. Read and Write access
-    - read: Read Input Registers - registers are 16-bit registers used for input, and may only be read
+    - coil: coils are also called discrete output. Coils are 1-bit registers (on/off values) that are used to control discrete outputs. Read and Write access. Modbus function code 1 (Read Coil Status) will be used
+    - discrete_input: discrete input register (read only coil) are similar to coils but can only be read. Modbus function code 2 (Read Input Status) will be used.
+    - holding: Holding Registers - Holding registers are the most universal 16-bit register. Read and Write access. Modbus function code 3 (Read Holding Registers) will be used.
+    - read: Read Input Registers - registers are 16-bit registers used for input, and may only be read. Modbus function code 4 (Read Input Registers) will be used.
 - **address**: (**Required**, int): start address of the first register in a range
 - **value_type**: (**Required**): datatype of the mod_bus register data. The default data type for modbus is a 16 bit integer in big endian format (MSB first)
-    - U_WORD (unsigned float from 1 register =16bit
-    - S_WORD (signed float from one register)
-    - U_DWORD (unsigned float from 2 registers = 32bit)
-    - S_DWORD (unsigned float from 2 registers = 32bit)
-    - U_DWORD_R (unsigend float from 2 registers low word first )
-    - S_DWORD_R (sigend float from 2 registers low word first )
-    - U_QWORD (unsigned float from 4 registers = 64bit
-    - S_QWORD (signed float from 4 registers = 64bit
-    - U_QWORD_R (unsigend float from 4 registers low word first )
-    - S_QWORD_R (sigend float from 4 registers low word first )
+    - U_WORD (unsigned 16 bit integer from 1 register = 16bit)
+    - S_WORD (signed 16 bit integer from 1 register = 16bit)
+    - U_DWORD (unsigned 32 bit integer from 2 registers = 32bit)
+    - S_DWORD (signed 32 bit integer from 2 registers = 32bit)
+    - U_DWORD_R (unsigned 32 bit integer from 2 registers low word first)
+    - S_DWORD_R (signed 32 bit integer from 2 registers low word first)
+    - U_QWORD (unsigned 64 bit integer from 4 registers = 64bit)
+    - S_QWORD (unsigned 64 bit integer from 4 registers = 64bit)
+    - U_QWORD_R (unsigned 64 bit integer from 4 registers low word first)
+    - U_QWORD_R signed 64 bit integer from 4 registers low word first)
+    - FP32 (32 bit IEEE 754 floating point from 2 registers)
+    - FP32_R (32 bit IEEE 754 floating point - same as FP32 but low word first)s
 
 - **bitmask**: (*Optional*) some values are packed in a response. The bitmask can be used to extract a value from the response.  For example, if the high byte value register 0x9013 contains the minute value of the current time. To only exctract this value use bitmask: 0xFF00.  The result will be automatically right shifted by the number of 0 before the first 1 in the bitmask.  For 0xFF00 (0b1111111100000000) the result is shifted 8 posistions.  More than one sensor can use the same address/offset if the bitmask is different.
 - **skip_updates**: (*Optional*, int): By default all sensors of of a modbus_controller are updated together. For data points that don't change very frequently updates can be skipped. A value of 5 would only update this sensor range in every 5th update cycle
   Note: The modbus_controller groups component by address ranges to reduce number of transactions. All compoents with the same address will be updated in one request. skip_updates applies for all components in the same range.
-- **register_count**: (*Optional*): only required for uncommon response encodings
-  The number of registers this data point spans. Default is 1
-- **force_new_range**: (*Optional*, boolean): If possible sensors with sequential addresses are grouped together and requested in one range. Setting `foce_new_range: true` enforces the start of a new range at that address.
+- **register_count**: (*Optional*): only required for uncommon response encodings or to :ref:`optimize modbus communications<modbus_register_count>`
+  The number of registers this data point spans. Overrides the defaults determined by ``value_type``.
+  If no value for ``register_count`` is provided, it is calculated based on the register type.
+
+  The default size for 1 register is 16 bits (1 Word). Some devices are not adhering to this convention and have registers larger than 16 bits.  In this case ``register_count`` and  ``response_size`` must be set. For example, if your modbus device uses 1 registers for a FP32 value instead the default of two set ``register_count: 1`` and ``response_size: 4``.
+- **response_size**:  (*Optional*): Size of the response for the register in bytes. Defaults to register_count*2.
+- **force_new_range**: (*Optional*, boolean): If possible sensors with sequential addresses are grouped together and requested in one range. Setting ``force_new_range: true`` enforces the start of a new range at that address.
+- **custom_data** (*Optional*, list of bytes): raw bytes for modbus command. This allows using non-standard commands. If ``custom_data`` is used ``address`` and ``register_type`` can't be used. 
+  custom data must contain all required bytes including the modbus device address. The crc is automatically calculated and appended to the command.
+  See :ref:`modbus_custom_data` how to use ``custom_command``
 - **lambda** (*Optional*, :ref:`lambda <config-lambda>`):
   Lambda to be evaluated every update interval to get the new value of the sensor.
 - **offset**: (*Optional*, int): only required for uncommon response encodings
@@ -119,7 +128,7 @@ Parameters passed into the lambda
 - **x** (float): The parsed float value of the modbus data
 
 - **data** (std::vector<uint8_t): vector containing the complete raw modbus response bytes for this sensor
-      note: because the response contains data for all registers in the same range you have to use `data[item->offset]` to get the first response byte for your sensor.
+      note: because the response contains data for all registers in the same range you have to use ``data[item->offset]`` to get the first response byte for your sensor.
 - **item** (const pointer to a SensorItem derived object):  The sensor object itself.
 
 Possible return values for the lambda:
@@ -127,6 +136,131 @@ Possible return values for the lambda:
  - ``return <FLOATING_POINT_NUMBER>;`` the new value for the sensor.
  - ``return NAN;`` if the state should be considered invalid to indicate an error (advanced).
 
+.. _modbus_custom_data:
+
+Using custom_data
+-----------------
+
+``custom_data`` can be used to create an arbitrary modbus command. Combined with a lambda any response can be handled. 
+This example re-implements the command to read the registers 0x156 (Total active energy) and 0x158 Total (reactive energy) from a SDM-120.
+SDM-120 returns the values as floats using 32 bits in 2 registers. 
+
+    .. code-block:: yaml
+
+        modbus:
+          send_wait_time: 200ms
+          uart_id: mod_uart
+          id: mod_bus
+
+        modbus_controller:
+          - id: sdm
+            address: 2
+            modbus_id: mod_bus
+            command_throttle: 100ms
+            setup_priority: -10
+            update_interval: 30s
+        sensors:
+          - platform: modbus_controller
+            modbus_controller_id: sdm
+            name: "Total active energy"
+            id: total_energy
+            #    address: 0x156
+            #    register_type: "read"
+            ## reimplement using custom_command
+            # 0x2 : modbus device address
+            # 0x4 : modbus function code
+            # 0x1 : high byte of modbus register address
+            # 0x56: low byte of modbus register address
+            # 0x00: high byte of total number of registers requested 
+            # 0x02: low byte of total number of registers requested
+            custom_command: [ 0x2, 0x4, 0x1, 0x56,0x00, 0x02]
+            value_type: FP32
+            unit_of_measurement: kWh
+            accuracy_decimals: 1
+
+          - platform: modbus_controller
+            modbus_controller_id: sdm
+            name: "Total reactive energy"
+            #   address: 0x158
+            #   register_type: "read"
+            custom_command: [0x2, 0x4, 0x1, 0x58, 0x00, 0x02]
+            ## the command returns an float value using 4 bytes
+            lambda: |-
+              ESP_LOGD("Modbus Sensor Lambda","Got new data" );
+              union {
+                float float_value;
+                uint32_t raw;
+              } raw_to_float;
+              if (data.size() < 4 ) {
+                ESP_LOGE("Modbus Sensor Lambda", "invalid data size %d",data.size());
+                return NAN;
+              }
+              raw_to_float.raw =   data[0] << 24 | data[1] << 16 | data[2] << 8 |  data[3];
+              ESP_LOGD("Modbus Sensor Lambda", "FP32 = 0x%08X => %f", raw_to_float.raw, raw_to_float.float_value);
+              return raw_to_float.float_value;
+            unit_of_measurement: kVArh
+            accuracy_decimals: 1
+
+.. _modbus_register_count:
+
+.. note:: **Optimize modbus communications**
+
+    ``register_count`` can also be used to skip a register in consecutive range. 
+    
+    An example is a SDM meter: 
+    
+    .. code-block:: yaml
+
+        - platform: modbus_controller
+            name: "Voltage Phase 1"
+            address: 0
+            register_type: "read"
+            value_type: FP32
+
+        - platform: modbus_controller
+            name: "Voltage Phase 2"
+            address: 2
+            register_type: "read"
+            value_type: FP32
+
+        - platform: modbus_controller
+            name: "Voltage Phase 3"
+            address: 4
+            register_type: "read"
+            value_type: FP32
+
+          - platform: modbus_controller
+            name: "Current Phase 1"
+            address: 6
+            register_type: "read"
+            value_type: FP32
+            accuracy_decimals: 1
+
+    Maybe you don’t care about the Voltage value for Phase 2 and Phase 3 (or you have a SDM-120). 
+    Of course, you can delete the sensors your don’t care about. But then you have a gap in the addresses. The configuration above will generate one modbus  command `read multiple registers from 0 to 6`. If you remove the registers at address 2 and 4 then 2 commands will be generated `read register 0` and `read register 6`.
+    To avoid the generation of multiple commands and reduce the amount of uart communication ``register_count`` can be used to fill the gaps 
+
+    .. code-block:: yaml
+
+        - platform: modbus_controller
+            name: "Voltage Phase 1"
+            address: 0
+            unit_of_measurement: "V"
+            register_type: "read"
+            value_type: FP32
+            register_count: 6
+
+          - platform: modbus_controller
+            name: "Current Phase 1"
+            address: 6
+            register_type: "read"
+            value_type: FP32
+
+    Because `register_count: 6` is used for the first register the command “read registers from 0 to 6” can still be used but the values in between are ignored. 
+    **Calculation:** FP32 is a 32 bit value and uses 2 registers. Therefore, to skip the 2 FP32 registers the size of these 2 registers must be added to the default size for the first register.
+    So we have 2 for address 0, 2 for address 2 and 2 for address 4 then ``register_count`` must be 6.
+
+
 See Also
 --------
 - :doc:`/components/modbus_controller`
diff --git a/components/sensor/pmsa003i.rst b/components/sensor/pmsa003i.rst
index 1db24db1d..4a33dc47a 100644
--- a/components/sensor/pmsa003i.rst
+++ b/components/sensor/pmsa003i.rst
@@ -3,7 +3,7 @@ PMSA003I Particulate Matter Sensor
 
 .. seo::
     :description: Instructions for setting up PMSX003 Particulate matter sensors
-    :image: images/pmsa003i-full.jpg
+    :image: pmsa003i-full.jpg
 
 The ``pmsa003i`` sensor platform  allows you to use your Plantower PMSA003I
 particulate matter sensor
diff --git a/components/sensor/pmsx003.rst b/components/sensor/pmsx003.rst
index f04b294f2..e7fb05fa9 100644
--- a/components/sensor/pmsx003.rst
+++ b/components/sensor/pmsx003.rst
@@ -3,7 +3,7 @@ PMSX003 Particulate Matter Sensor
 
 .. seo::
     :description: Instructions for setting up PMSX003 Particulate matter sensors
-    :image: pmsx003.png
+    :image: pmsx003.svg
 
 The ``pmsx003`` sensor platform allows you to use your PMS5003, PMS7003, ... particulate matter
 (`datasheet <http://www.aqmd.gov/docs/default-source/aq-spec/resources-page/plantower-pms5003-manual_v2-3.pdf>`__)
@@ -17,6 +17,7 @@ This platform supports three sensor types, which you need to specify using the `
 value:
 
 - ``PMSX003`` for generic PMS5003, PMS7003, ...; these sensors support ``pm_1_0``, ``pm_2_5`` and ``pm_10_0`` output.
+- ``PMS5003S`` for PMS5003ST. These support ``pm_1_0``, ``pm_2_5`` and ``pm_10_0`` and ``formaldehyde``.
 - ``PMS5003T`` for PMS5003T. These support ``pm_2_5``, ``temperature`` and ``humidity``.
 - ``PMS5003ST`` for PMS5003ST. These support ``pm_2_5``, ``temperature``, ``humidity`` and ``formaldehyde``.
 
@@ -68,7 +69,7 @@ Configuration variables:
   All options from :ref:`Sensor <config-sensor>`.
 - **humidity** (*Optional*): Use the humidity value in % for the ``PMS5003T`` and ``PMS5003ST``.
   All options from :ref:`Sensor <config-sensor>`.
-- **formaldehyde** (*Optional*): Use the formaldehyde (HCHO) concentration in µg per cubic meter for the ``PMS5003ST``.
+- **formaldehyde** (*Optional*): Use the formaldehyde (HCHO) concentration in µg per cubic meter for the ``PMS5003S`` and ``PMS5003ST``.
   All options from :ref:`Sensor <config-sensor>`.
 - **uart_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the :ref:`UART Component <uart>` if you want
   to use multiple UART buses.
diff --git a/components/sensor/pulse_counter.rst b/components/sensor/pulse_counter.rst
index 48c50d5a1..3acba1982 100644
--- a/components/sensor/pulse_counter.rst
+++ b/components/sensor/pulse_counter.rst
@@ -3,7 +3,7 @@ Pulse Counter Sensor
 
 .. seo::
     :description: Instructions for setting up pulse counter sensors.
-    :image: pulse.png
+    :image: pulse.svg
 
 The pulse counter sensor allows you to count the number of pulses and the frequency of a signal
 on any pin.
diff --git a/components/sensor/pulse_meter.rst b/components/sensor/pulse_meter.rst
index df6213ec5..f8cfa45d1 100644
--- a/components/sensor/pulse_meter.rst
+++ b/components/sensor/pulse_meter.rst
@@ -3,7 +3,7 @@ Pulse Meter Sensor
 
 .. seo::
     :description: Instructions for setting up pulse meter sensors.
-    :image: pulse.png
+    :image: pulse.svg
 
 The pulse meter sensor allows you to count the number and frequency of pulses on any pin. It is intended to be a drop-in replacement
 for :doc:`integration sensor </components/sensor/pulse_counter>`, but offering better resolution.
diff --git a/components/sensor/pulse_width.rst b/components/sensor/pulse_width.rst
index 67d9bc2a4..38bff673f 100644
--- a/components/sensor/pulse_width.rst
+++ b/components/sensor/pulse_width.rst
@@ -3,7 +3,7 @@ Pulse Width Sensor
 
 .. seo::
     :description: Instructions for setting up pulse width sensors in ESPHome
-    :image: pulse.png
+    :image: pulse.svg
 
 The ``pulse_width`` sensor allows you to measure how long a given digital signal
 is HIGH. For example this can be used to measure PWM signals to transmit some
diff --git a/components/sensor/pzem004t.rst b/components/sensor/pzem004t.rst
index a87af2a34..2e339e37a 100644
--- a/components/sensor/pzem004t.rst
+++ b/components/sensor/pzem004t.rst
@@ -3,7 +3,7 @@ Peacefair PZEM-004T Energy Monitor
 
 .. seo::
     :description: Instructions for setting up PZEM-004 and PZEM-004T V1 power monitors.
-    :image: pzem-004.jpg
+    :image: pzem004t.svg
     :keywords: PZEM-004T, PZEM-004
 
 .. note::
@@ -20,7 +20,7 @@ ESPHome.
 
 .. warning::
 
-    This page refers to version V1 of the PZEM-004T, which has been out of stock for a while. 
+    This page refers to version V1 of the PZEM-004T, which has been out of stock for a while.
     The PZEM-004, however, is still working (and selling) with this protocol and does not use modbus.
     For using the newer V3 variant of this sensor please see :doc:`pzemac <pzemac>`.
 
@@ -64,14 +64,14 @@ Configuration variables:
 
 Hardware considerations:
 ------------------------
-These devices have optocouplers on the UART port and the resistors mounted on the board have been designed to work with 5V devices. 
-ESPs need a `Level Shifter <https://www.adafruit.com/product/1875>`__ to be compatible with TTL levels. 
+These devices have optocouplers on the UART port and the resistors mounted on the board have been designed to work with 5V devices.
+ESPs need a `Level Shifter <https://www.adafruit.com/product/1875>`__ to be compatible with TTL levels.
 
 .. note::
 
     You need a IC level shifter and not a `Mosfet-based <https://www.sparkfun.com/products/12009>`__ level shifter, because you need
     to power the optocoupler's LEDs without an additional resistor in the path.
-   
+
 If prefer, you could change the value of the optocoupler's resistors by following `this <https://gregwareblog.wordpress.com/2020/12/13/home-power-monitoring-pzem-004/>`__ or `this <https://www.instructables.com/Power-Peacefair-PZEM-004-ESP8266-Arduino-Nano/>`__ guide.
 
 Your ESP shall be powered by an external power supply and cannot be connected to the PZEM for power.
diff --git a/components/sensor/pzemac.rst b/components/sensor/pzemac.rst
index ebec5df7a..90f8a8896 100644
--- a/components/sensor/pzemac.rst
+++ b/components/sensor/pzemac.rst
@@ -3,7 +3,7 @@ Peacefair PZEM-004T V3 Energy Monitor
 
 .. seo::
     :description: Instructions for setting up PZEM-004T power monitors.
-    :image: pzemac.png
+    :image: pzem-ac.png
     :keywords: PZEM-004T V3
 
 .. note::
diff --git a/components/sensor/pzemdc.rst b/components/sensor/pzemdc.rst
index b89343e96..9e76a1fa4 100644
--- a/components/sensor/pzemdc.rst
+++ b/components/sensor/pzemdc.rst
@@ -3,7 +3,7 @@ Peacefair PZEM-00X DC Energy Monitor
 
 .. seo::
     :description: Instructions for setting up DC PZEM power monitors.
-    :image: pzemdc.png
+    :image: pzem-dc.png
 
 .. note::
 
diff --git a/components/sensor/resistance.rst b/components/sensor/resistance.rst
index 0f132be72..21d42c2c4 100644
--- a/components/sensor/resistance.rst
+++ b/components/sensor/resistance.rst
@@ -3,7 +3,7 @@ Resistance Sensor
 
 .. seo::
     :description: Instructions for setting up resistance sensors in ESPHome
-    :image: omega.png
+    :image: omega.svg
 
 The ``resistance`` platform is a helper sensor that allows you to convert readings
 from a voltage sensor (such as the :doc:`ADC Sensor <adc>`) into resistance readings
diff --git a/components/sensor/sdm_meter.rst b/components/sensor/sdm_meter.rst
index f47bd9adc..8a5338229 100644
--- a/components/sensor/sdm_meter.rst
+++ b/components/sensor/sdm_meter.rst
@@ -3,7 +3,7 @@ Eastron SDM Energy Monitor
 
 .. seo::
     :description: Instructions for setting up SDM power monitors.
-    :image: images/sdm220m-full.png
+    :image: sdm220m.png
     :keywords: SDM220M, SDM220, SDM630
 
 The ``sdm_meter`` sensor platform allows you to use Eastron SDM modbus energy monitors
diff --git a/components/sensor/sdp3x.rst b/components/sensor/sdp3x.rst
index 3e09ea7b5..4bbfd7159 100644
--- a/components/sensor/sdp3x.rst
+++ b/components/sensor/sdp3x.rst
@@ -1,14 +1,14 @@
-SDP3x Differential Pressure Sensor
-==================================
+SDP3x / SDP800 Series Differential Pressure Sensor
+===================================================
 
 .. seo::
-    :description: Instructions for setting up the SDP3x Differential Pressure sensor.
-    :image: images/sdp31.jpg
-    :keywords: SDP3x, SDP31, SDP32
+    :description: Instructions for setting up the SDP3x or SDP800 Series Differential Pressure sensor.
+    :image: sdp31.jpg
+    :keywords: SDP3x, SDP31, SDP32, SDP800 Series, SDP810, SDP810
 
 The SDP3x Differential Pressure sensor allows you to use your SDP3x
 (`datasheet <https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/8_Differential_Pressure/Datasheets/Sensirion_Differential_Pressure_Datasheet_SDP3x_Digital.pdf>`__,
-`sparkfun <https://www.sparkfun.com/products/17874>`__)
+`sparkfun <https://www.sparkfun.com/products/17874>`__) or SDP800 Series (`datasheet <https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/8_Differential_Pressure/Datasheets/Sensirion_Differential_Pressure_Datasheet_SDP8xx_Digital.pdf>`__)
 sensors with ESPHome.
 
 .. figure:: images/sdp31.jpg
@@ -20,7 +20,7 @@ sensors with ESPHome.
 
 .. _Sparkfun: https://www.sparkfun.com/products/17874
 
-To use the sensor, set up an :ref:`I²C Bus <i2c>` and connect the sensor to the specified pins. 
+To use the sensor, set up an :ref:`I²C Bus <i2c>` and connect the sensor to the specified pins.
 
 .. code-block:: yaml
 
@@ -35,6 +35,7 @@ Configuration variables:
 - **name** (**Required**, string): The name for this sensor.
 - **id** (*Optional*, :ref:`config-id`): Set the ID of this sensor for lambdas/multiple sensors.
 - **address** (*Optional*, int): The I²C address of the sensor. Defaults to ``0x21``.
+- **measurement_mode** (*Optional*): The measurement mode of the sensor. Valid options are ``differential_pressure`` and ``mass_flow``. Defaults to ``differential_pressure``.
 - **update_interval** (*Optional*, :ref:`config-time`): The interval to check the sensor. Defaults to ``60s``.
 - All other options from :ref:`Sensor <config-sensor>`.
 
diff --git a/components/sensor/selec_meter.rst b/components/sensor/selec_meter.rst
index 70ad1aa64..392583905 100644
--- a/components/sensor/selec_meter.rst
+++ b/components/sensor/selec_meter.rst
@@ -3,7 +3,7 @@ Selec Energy Monitor
 
 .. seo::
     :description: Instructions for setting up Selec power monitors.
-    :image: images/selec_meter_em2m.jpg
+    :image: selec_meter_em2m.jpg
     :keywords: EM2M
 
 The ``selec_meter`` sensor platform allows you to use Selec Modbus energy monitors
diff --git a/components/sensor/sgp30.rst b/components/sensor/sgp30.rst
index 06100a5fb..448b8431e 100644
--- a/components/sensor/sgp30.rst
+++ b/components/sensor/sgp30.rst
@@ -3,7 +3,7 @@ SGP30 CO₂ and Volatile Organic Compound Sensor
 
 .. seo::
     :description: Instructions for setting up SGP30 CO₂eq and Volatile Organic Compound sensor
-    :image: sgp30.png
+    :image: sgp30.jpg
 
 The ``sgp30`` sensor platform allows you to use your Sensirion SGP30 multi-pixel gas
 (`datasheet <https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/9_Gas_Sensors/Datasheets/Sensirion_Gas_Sensors_SGP30_Datasheet.pdf>`__) sensors or the SVM30 breakout-boards  (`product page <https://www.sensirion.com/en/environmental-sensors/gas-sensors/multi-gas-humidity-temperature-module-svm30/>`__) with ESPHome.
diff --git a/components/sensor/sht4x.rst b/components/sensor/sht4x.rst
index 92fb76643..60205edd2 100644
--- a/components/sensor/sht4x.rst
+++ b/components/sensor/sht4x.rst
@@ -3,7 +3,7 @@ SHT4X Temperature and Humidity Sensor
 
 .. seo::
     :description: Instructions for setting up SHT4X temperature and humidity sensor
-    :image: images/sht4x-full.jpg
+    :image: sht4x.jpg
 
 The ``sht4x`` sensor platform  allows you to use your SHT4X temperature and humidity sensor
 (`datasheet <https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/2_Humidity_Sensors/Datasheets/Sensirion_Humidity_Sensors_SHT4x_Datasheet.pdf>`__, `Adafruit`_) with ESPHome.
diff --git a/components/sensor/sm300d2.rst b/components/sensor/sm300d2.rst
index 286dd9953..2a2d1dc71 100644
--- a/components/sensor/sm300d2.rst
+++ b/components/sensor/sm300d2.rst
@@ -3,7 +3,7 @@ SM300D2 7-in-1 Air Quality Sensor
 
 .. seo::
     :description: Instructions for setting up SM300D2 sensor to work with ESPHome
-    :image: sm300d2-full.jpg
+    :image: sm300d2.jpg
     :keywords: sm300d2
 
 The ``sm300d2`` sensor platform allows you to use the SM300D2 7-in-1 Air Quality Sensor with ESPHome.
diff --git a/components/sensor/t6615.rst b/components/sensor/t6615.rst
index e03b21172..a49e98ebc 100644
--- a/components/sensor/t6615.rst
+++ b/components/sensor/t6615.rst
@@ -3,7 +3,7 @@ T6613/15 CO2 Sensors
 
 .. seo::
     :description: Instructions for setting up T6613 and T6615 sensors for ESPHome
-    :image: images/t6615.png
+    :image: t6615.png
     :keywords: t6613 t6615
 
 The ``t6615`` sensor platform allows you to use T6613 and T6615 family sensors
diff --git a/components/sensor/template.rst b/components/sensor/template.rst
index 342f5d93a..a962f86b7 100644
--- a/components/sensor/template.rst
+++ b/components/sensor/template.rst
@@ -3,7 +3,7 @@ Template Sensor
 
 .. seo::
     :description: Instructions for setting up template sensors with ESPHome.
-    :image: description.png
+    :image: description.svg
 
 The ``template`` sensor platform allows you to create a sensor with templated values
 using :ref:`lambdas <config-lambda>`.
diff --git a/components/sensor/total_daily_energy.rst b/components/sensor/total_daily_energy.rst
index f55271d47..36891f933 100644
--- a/components/sensor/total_daily_energy.rst
+++ b/components/sensor/total_daily_energy.rst
@@ -3,7 +3,7 @@ Total Daily Energy Sensor
 
 .. seo::
     :description: Instructions for setting up sensors that track the total daily energy usage per day and accumulate the power usage.
-    :image: sigma.png
+    :image: sigma.svg
 
 The ``total_daily_energy`` sensor is a helper sensor that can use the energy value of
 other sensors like the :doc:`HLW8012 <hlw8012>`, :doc:`CSE7766 <cse7766>`, :doc:`ATM90E32 <atm90e32>`, etc and integrate
@@ -38,6 +38,9 @@ Configuration variables:
   to integrate over time.
 - **name** (**Required**, string): The name of the sensor.
 - **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
+- **restore** (*Optional*, boolean): Whether to store the intermediate result on the device so
+  that the value can be restored upon power cycle or reboot.
+  Defaults to ``true``.
 - **min_save_interval** (*Optional*, :ref:`config-time`): The minimum time span between saving updated values to storage. This is to keep wearout of memory low. Defaults to ``0s``.
 - **method** (*Optional*, string): The method to use for calculating the total daily energy. One of
   ``trapezoid``, ``left`` or ``right``. Defaults to ``right``.
diff --git a/components/sensor/tx20.rst b/components/sensor/tx20.rst
index 8790d75e9..566e8ca8b 100644
--- a/components/sensor/tx20.rst
+++ b/components/sensor/tx20.rst
@@ -3,7 +3,7 @@ TX20/TX23 Wind Speed/Direction Sensor
 
 .. seo::
     :description: Instructions for setting up TX20/TX23 wind speed and direction sensors
-    :image: images/tx20.jpg
+    :image: tx20.jpg
     :keywords: TX20
 
 The ``tx20`` sensor platform allows you to use your TX20/TX23
diff --git a/components/sensor/uptime.rst b/components/sensor/uptime.rst
index 58fbff2d0..c8ea1a9e6 100644
--- a/components/sensor/uptime.rst
+++ b/components/sensor/uptime.rst
@@ -3,7 +3,7 @@ Uptime Sensor
 
 .. seo::
     :description: Instructions for setting up a sensor that tracks the uptime of the ESP.
-    :image: timer.png
+    :image: timer.svg
 
 The ``uptime`` sensor allows you to track the time the ESP has stayed up for in seconds.
 Time rollovers are automatically handled.
diff --git a/components/sensor/wifi_signal.rst b/components/sensor/wifi_signal.rst
index f2a5b57f5..1fa639678 100644
--- a/components/sensor/wifi_signal.rst
+++ b/components/sensor/wifi_signal.rst
@@ -3,7 +3,7 @@ WiFi Signal Sensor
 
 .. seo::
     :description: Instructions for setting up WiFi signal sensors that track the RSSI connection strength value to the network.
-    :image: network-wifi.png
+    :image: network-wifi.svg
 
 The ``wifi_signal`` sensor platform allows you to read the signal
 strength of the currently connected :doc:`WiFi Access Point </components/wifi>`.
diff --git a/components/servo.rst b/components/servo.rst
index b125e6958..341eae970 100644
--- a/components/servo.rst
+++ b/components/servo.rst
@@ -3,7 +3,7 @@ Servo Component
 
 .. seo::
     :description: Instructions for setting up servos in ESPHome
-    :image: servo.png
+    :image: servo.svg
 
 The ``servo`` component allows you to use servo motors with ESPHome. Servos are
 motor controllers that contain all the electronics necessary for driving the motor and provide
diff --git a/components/spi.rst b/components/spi.rst
index 5839b0547..d6a433ced 100644
--- a/components/spi.rst
+++ b/components/spi.rst
@@ -5,7 +5,7 @@ SPI Bus
 
 .. seo::
     :description: Instructions for setting up an SPI bus in ESPHome
-    :image: spi.png
+    :image: spi.svg
     :keywords: SPI
 
 SPI is a very common high-speed protocol for a lot of devices. The SPI bus usually consists of 4 wires:
diff --git a/components/status_led.rst b/components/status_led.rst
index b0711bab8..28af3bd75 100644
--- a/components/status_led.rst
+++ b/components/status_led.rst
@@ -3,7 +3,7 @@ Status LED
 
 .. seo::
     :description: Instructions for setting up status LEDs in ESPHome to monitor the status of an ESP.
-    :image: led-on.png
+    :image: led-on.svg
 
 The ``status_led`` hooks into all ESPHome components and can indicate the status of
 the device. Specifically, it will:
diff --git a/components/stepper/index.rst b/components/stepper/index.rst
index 78dfbfc80..d31208c17 100644
--- a/components/stepper/index.rst
+++ b/components/stepper/index.rst
@@ -3,7 +3,7 @@ Stepper Component
 
 .. seo::
     :description: Instructions for setting up stepper motor drivers in ESPHome
-    :image: folder-open.png
+    :image: folder-open.svg
     :keywords: stepper motor, stepper driver, a4988
 
 The ``stepper`` component allows you to use stepper motors with ESPHome.
diff --git a/components/sun.rst b/components/sun.rst
index bb40e835b..a87321d44 100644
--- a/components/sun.rst
+++ b/components/sun.rst
@@ -3,7 +3,7 @@ Sun
 
 .. seo::
     :description: Instructions for setting up tracking the sun position in ESPHome.
-    :image: weather-sunny.png
+    :image: weather-sunny.svg
 
 The ``sun`` component allows you to track the sun's position in the sky.
 
diff --git a/components/switch/gpio.rst b/components/switch/gpio.rst
index e9b0c8291..56361bb74 100644
--- a/components/switch/gpio.rst
+++ b/components/switch/gpio.rst
@@ -3,7 +3,7 @@ GPIO Switch
 
 .. seo::
     :description: Instructions for setting up GPIO pin switches in ESPHome that control GPIO outputs.
-    :image: pin.png
+    :image: pin.svg
 
 The ``gpio`` switch platform allows you to use any pin on your node as a
 switch. You can for example hook up a relay to a GPIO pin and use it
diff --git a/components/switch/index.rst b/components/switch/index.rst
index 9d7d36215..531c57623 100644
--- a/components/switch/index.rst
+++ b/components/switch/index.rst
@@ -3,7 +3,7 @@ Switch Component
 
 .. seo::
     :description: Instructions for setting up generic switches in ESPHome.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 The ``switch`` domain includes all platforms that should show up like a
 switch and can only be turned ON or OFF.
diff --git a/components/switch/modbus_controller.rst b/components/switch/modbus_controller.rst
index e2dee0e5b..bd245f921 100644
--- a/components/switch/modbus_controller.rst
+++ b/components/switch/modbus_controller.rst
@@ -3,7 +3,6 @@ Modbus Switch
 
 .. seo::
     :description: Instructions for setting up a modbus_controller device sensor.
-    :image: modbus_controller.png
 
 The ``modbus_controller`` sensor platform creates a sensor from a modbus_controller component
 and requires :doc:`/components/modbus_controller` to be configured.
@@ -22,6 +21,49 @@ Configuration variables:
   To get the value of the coil register 2 can be retrived using address: 2 / offset: 0 or address: 0 / offset 2
 - **bitmask** : some values are packed in a response. The bitmask is used to determined if the result is true or false
 - **skip_updates**: (*Optional*, int): By default all sensors of of a modbus_controller are updated together. For data points that don't change very frequently updates can be skipped. A value of 5 would only update this sensor range in every 5th update cycle
+- **use_write_multiple**: (*Optional*, boolean): By default the modbus command ``Force Single Coil`` (function code 5) is used to send state changes to the device. If your device only supports ``Force Multiple Coils`` (function code 15) set this option to true.
+- **custom_data** (*Optional*, list of bytes): raw bytes for modbus command. This allows using non-standard commands. If ``custom_data`` is used ``address`` and ``register_type`` can't be used.
+  custom data must contain all required bytes including the modbus device address. The crc is automatically calculated and appended to the command.
+  See :ref:`modbus_custom_data` how to use ``custom_command``
+- **lambda** (*Optional*, :ref:`lambda <config-lambda>`):
+  Lambda to be evaluated every update interval to read the status of the switch.
+- **write_lambda** (*Optional*, :ref:`lambda <config-lambda>`): Lambda called before send.
+  Lambda is evaluated before the modbus write command is created.
+
+**Parameters passed into write_lambda**
+
+- **x** (float): The float value to be sent to the modbus device
+
+- **payload** (`std::vector<uint8_t>&payload`): empty vector for the payload. If payload is set in the lambda it is sent as a custom command and must include all required bytes for a modbus request
+      note: because the response contains data for all registers in the same range you have to use ``data[item->offset]`` to get the first response byte for your sensor.
+- **item** (const pointer to a Switch derived object):  The sensor object itself.
+
+Possible return values for the lambda:
+
+ - ``return <true / false>;`` the new value for the sensor.
+ - ``return <anything>; and fill payload with data`` if the payload is added from the lambda then these bytes will be sent
+
+**Example**
+
+.. code-block:: yaml
+
+    switch:
+      - platform: modbus_controller
+        modbus_controller_id: epever
+        id: enable_load_test
+        register_type: coil
+        address: 2
+        name: "enable load test mode"
+        write_lambda: |-
+          ESP_LOGD("main","Modbus Switch incoming state = %f",x);
+          // return false ; // use this to just change the value
+          payload.push_back(0x1);  // device address
+          payload.push_back(0x5);  // force single coil
+          payload.push_back(0x00); // high byte address of the coil
+          payload.push_back(0x6);  // low byte address of the coil
+          payload.push_back(0xFF); // ON = 0xFF00 OFF=0000
+          payload.push_back(0x00);
+
 
 
 **Example**
diff --git a/components/switch/output.rst b/components/switch/output.rst
index b846feb86..a5b600578 100644
--- a/components/switch/output.rst
+++ b/components/switch/output.rst
@@ -3,7 +3,7 @@ Generic Output Switch
 
 .. seo::
     :description: Instructions for setting up generic output switches in ESPHome that control an output component.
-    :image: upload.png
+    :image: upload.svg
 
 The ``output`` switch platform allows you to use any output component as a switch.
 
diff --git a/components/switch/restart.rst b/components/switch/restart.rst
index 57f243c09..15dcabb65 100644
--- a/components/switch/restart.rst
+++ b/components/switch/restart.rst
@@ -3,7 +3,7 @@ Restart Switch
 
 .. seo::
     :description: Instructions for setting up switches that can remotely reboot the ESP in ESPHome.
-    :image: restart.png
+    :image: restart.svg
 
 The ``restart`` switch platform allows you to restart your node remotely
 through Home Assistant.
@@ -32,5 +32,5 @@ See Also
 - :doc:`shutdown`
 - :doc:`safe_mode`
 - :doc:`template`
-- :apiref:`restart/restart_switch.h`
+- :apiref:`restart/switch/restart_switch.h`
 - :ghedit:`Edit`
diff --git a/components/switch/safe_mode.rst b/components/switch/safe_mode.rst
index c3168e191..17ad39c44 100644
--- a/components/switch/safe_mode.rst
+++ b/components/switch/safe_mode.rst
@@ -3,7 +3,7 @@ Safe Mode Switch
 
 .. seo::
     :description: Instructions for setting up switches that can remotely reboot the ESP in ESPHome into safe mode.
-    :image: restart.png
+    :image: restart.svg
 
 The ``safe_mode`` switch allows you to remotely reboot your node into :ref:`Safe Mode <config-ota>`. This is useful in certain situations
 where a misbehaving component is preventing Over-The-Air updates from completing successfully.
diff --git a/components/switch/shutdown.rst b/components/switch/shutdown.rst
index e843b4c65..814ba446e 100644
--- a/components/switch/shutdown.rst
+++ b/components/switch/shutdown.rst
@@ -3,7 +3,7 @@ Shutdown Switch
 
 .. seo::
     :description: Instructions for setting up switches that can remotely shut down the ESP.
-    :image: power_settings.png
+    :image: power_settings.svg
 
 The ``shutdown`` switch platform allows you to shutdown your node remotely
 through Home Assistant. It does this by putting the node into deep sleep mode with no
diff --git a/components/switch/template.rst b/components/switch/template.rst
index b47b30324..fe39a3c69 100644
--- a/components/switch/template.rst
+++ b/components/switch/template.rst
@@ -3,7 +3,7 @@ Template Switch
 
 .. seo::
     :description: Instructions for setting up template switches that can execute arbitrary actions when turned on or off.
-    :image: description.png
+    :image: description.svg
 
 The ``template`` switch platform allows you to create simple switches out of just actions and
 an optional value lambda. Once defined, it will automatically appear in Home Assistant
diff --git a/components/switch/uart.rst b/components/switch/uart.rst
index 4aefa9344..cf1518a03 100644
--- a/components/switch/uart.rst
+++ b/components/switch/uart.rst
@@ -3,7 +3,7 @@ UART Switch
 
 .. seo::
     :description: Instructions for setting up UART switches in ESPHome that can output arbitrary UART sequences when activated.
-    :image: uart.png
+    :image: uart.svg
 
 The ``uart`` switch platform allows you to send a pre-defined sequence of bytes on a
 :doc:`UART bus </components/uart>` when triggered.
diff --git a/components/text_sensor/ble_scanner.rst b/components/text_sensor/ble_scanner.rst
index 4fccf2d37..3d21c3df1 100644
--- a/components/text_sensor/ble_scanner.rst
+++ b/components/text_sensor/ble_scanner.rst
@@ -3,7 +3,7 @@ ESP32 Bluetooth Low Energy Scanner
 
 .. seo::
     :description: Instructions for setting up BLE text sensors for the ESP32.
-    :image: bluetooth.png
+    :image: bluetooth.svg
     :keywords: ESP32
 
 The ``ble_scanner`` text sensor platform lets you track reachable BLE devices.
diff --git a/components/text_sensor/homeassistant.rst b/components/text_sensor/homeassistant.rst
index 08ab13580..ed9ce523b 100644
--- a/components/text_sensor/homeassistant.rst
+++ b/components/text_sensor/homeassistant.rst
@@ -3,7 +3,7 @@ Home Assistant Text Sensor
 
 .. seo::
     :description: Instructions for setting up Home Assistant text sensors with ESPHome that import states from your Home Assistant instance.
-    :image: home-assistant.png
+    :image: home-assistant.svg
 
 The ``homeassistant`` text sensor platform allows you to create a sensors that import
 states from your Home Assistant instance using the :doc:`native API </components/api>`.
diff --git a/components/text_sensor/index.rst b/components/text_sensor/index.rst
index 5a23856b5..d5379c67d 100644
--- a/components/text_sensor/index.rst
+++ b/components/text_sensor/index.rst
@@ -3,7 +3,7 @@ Text Sensor Component
 
 .. seo::
     :description: Instructions for setting up text sensors that represent their state as a string of text.
-    :image: folder-open.png
+    :image: folder-open.svg
 
 Text sensors are a lot like normal :doc:`sensors </components/sensor/index>`.
 But where the "normal" sensors only represent sensors that output **numbers**, this
@@ -142,6 +142,25 @@ Search the current value of the text sensor for a string, and replace it with an
 
 The arguments are a list of substitutions, each in the form ``TO_FIND -> REPLACEMENT``.
 
+``map``
+*******
+
+Lookup the current value of the text sensor in a list, and return the matching item if found. 
+Does not change the value of the text sensor if the current value wasn't found.
+
+
+.. code-block:: yaml
+
+    # Example configuration entry
+    - platform: template
+      # ...
+      filters:
+        - map:
+          - high -> On
+          - low -> Off
+
+The arguments are a list of substitutions, each in the form ``LOOKUP -> REPLACEMENT``.
+
 ``lambda``
 **********
 
diff --git a/components/text_sensor/modbus_controller.rst b/components/text_sensor/modbus_controller.rst
index d531f132b..e5aada311 100644
--- a/components/text_sensor/modbus_controller.rst
+++ b/components/text_sensor/modbus_controller.rst
@@ -3,7 +3,6 @@ Modbus Text Sensor
 
 .. seo::
     :description: Instructions for setting up a modbus_controller modbus text sensor.
-    :image: modbus_controller.png
 
 The ``modbus_controller`` sensor platform creates a text sensor from a modbus_controller component
 and requires :doc:`/components/modbus_controller` to be configured.
@@ -28,6 +27,9 @@ Configuration variables:
      - ``HEXBYTES``:  2 byte hex string. 0x2011 will be sent as "2011".
      - ``COMMA``: Byte values as integers, delimited by a coma. 0x2011 will be sent as "32,17"
 - **force_new_range**: (*Optional*, boolean): If possible sensors with sequential addresses are grouped together and requested in one range. Setting `foce_new_range: true` enforces the start of a new range at that address.
+- **custom_data** (*Optional*, list of bytes): raw bytes for modbus command. This allows using non-standard commands. If ``custom_data`` is used ``address`` and ``register_type`` can't be used.
+  custom data must contain all required bytes including the modbus device address. The crc is automatically calculated and appended to the command.
+  See :ref:`modbus_custom_data` how to use ``custom_command``
 - **lambda** (*Optional*, :ref:`lambda <config-lambda>`):
   Lambda to be evaluated every update interval to get the new value of the sensor
 - **offset**: (*Optional*, int): not required in most cases
@@ -39,7 +41,7 @@ Parameters passed into the lambda
 - **x** (std:string): The parsed float value of the modbus data
 
 - **data** (std::vector<uint8_t): vector containing the complete raw modbus response bytes for this sensor
-      note: because the response contains data for all registers in the same range you have to use `data[item->offset]` to get the first response byte for your sensor.
+      note: because the response contains data for all registers in the same range you have to use ``data[item->offset]`` to get the first response byte for your sensor.
 - **item** (const pointer to a SensorItem derived object):  The sensor object itself.
 
 Possible return values for the lambda:
diff --git a/components/text_sensor/template.rst b/components/text_sensor/template.rst
index 3f50cd28d..60994ed8c 100644
--- a/components/text_sensor/template.rst
+++ b/components/text_sensor/template.rst
@@ -3,7 +3,7 @@ Template Text Sensor
 
 .. seo::
     :description: Instructions for setting up template text sensors in ESPHome
-    :image: description.png
+    :image: description.svg
 
 The ``template`` text sensor platform allows you to create a text sensor with templated values
 using :ref:`lambdas <config-lambda>`.
diff --git a/components/text_sensor/tuya.rst b/components/text_sensor/tuya.rst
new file mode 100644
index 000000000..49c1a32ad
--- /dev/null
+++ b/components/text_sensor/tuya.rst
@@ -0,0 +1,35 @@
+Tuya Text Sensor
+================
+
+.. seo::
+    :description: Instructions for setting up a Tuya device sensor.
+    :image: tuya.png
+
+The ``tuya`` text sensor platform creates a sensor from a tuya component
+and requires :doc:`/components/tuya` to be configured.
+
+You can create the text sensor as follows:
+
+.. code-block:: yaml
+
+    # Create a sensor
+    text_sensor:
+      - platform: "tuya"
+        name: "MyTextSensor"
+        sensor_datapoint: 18
+
+Configuration variables:
+------------------------
+
+- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
+- **name** (**Required**, string): The name of the sensor.
+- **sensor_datapoint** (**Required**, int): The datapoint id number of the sensor.
+- All other options from :ref:`Text Sensor <config-text_sensor>`.
+
+See Also
+--------
+
+- :doc:`/components/tuya`
+- :doc:`/components/text_sensor/index`
+- :apiref:`tuya/text_sensor/tuya_text_sensor.h`
+- :ghedit:`Edit`
diff --git a/components/text_sensor/version.rst b/components/text_sensor/version.rst
index 3d9a44c1d..606de874a 100644
--- a/components/text_sensor/version.rst
+++ b/components/text_sensor/version.rst
@@ -3,7 +3,7 @@ Version Text Sensor
 
 .. seo::
     :description: Instructions for setting up version text sensors.
-    :image: new-box.png
+    :image: new-box.svg
 
 The ``version`` text sensor platform exposes the ESPHome version the firmware
 was compiled against as a text sensor.
diff --git a/components/text_sensor/wifi_info.rst b/components/text_sensor/wifi_info.rst
index 28ea7f6ce..127c98a04 100644
--- a/components/text_sensor/wifi_info.rst
+++ b/components/text_sensor/wifi_info.rst
@@ -3,7 +3,7 @@ WiFi Info Text Sensor
 
 .. seo::
     :description: Instructions for setting up WiFi info text sensors.
-    :image: network-wifi.png
+    :image: network-wifi.svg
 
 The ``wifi_info`` text sensor platform exposes different WiFi information
 via text sensors.
diff --git a/components/time.rst b/components/time.rst
index 36be7588f..6e418db43 100644
--- a/components/time.rst
+++ b/components/time.rst
@@ -5,7 +5,7 @@ Time
 
 .. seo::
     :description: Instructions for setting up real time clock sources in ESPHome like network based time.
-    :image: clock-outline.png
+    :image: clock-outline.svg
     :keywords: GPS, NTP, RTC, SNTP
 
 The ``time`` component allows you to set up real time clock time sources for ESPHome.
diff --git a/components/tuya.rst b/components/tuya.rst
index 1ea533f78..b14446926 100644
--- a/components/tuya.rst
+++ b/components/tuya.rst
@@ -60,6 +60,70 @@ Configuration variables:
 
 - **ignore_mcu_update_on_datapoints** (*Optional*, list): A list of datapoints to ignore MCU updates for.  Useful for certain broken/erratic hardware and debugging.
 
+Automations:
+
+- **on_datapoint_update**: (*Optional*): An automation to perform when a Tuya datapoint update is received. See :ref:`tuya-on_datapoint_update`.
+
+Tuya Automation
+---------------
+
+.. _tuya-on_datapoint_update:
+
+``on_datapoint_update``
+***********************
+
+This automation will be triggered when a a Tuya datapoint update is received. 
+A variable ``x`` is passed to the automation for use in lambdas. 
+The type of ``x`` variable is depending on ``datapoint_type`` configuration variable:
+
+- *raw*: ``x`` is ``std::vector<uint8_t>``
+- *string*: ``x`` is ``std::string``
+- *bool*: ``x`` is ``bool``
+- *int*: ``x`` is ``int``
+- *uint*: ``x`` is ``uint32_t``
+- *enum*: ``x`` is ``uint8_t``
+- *bitmask*: ``x`` is ``uint32_t``
+- *any*: ``x`` is :apistruct:`tuya::TuyaDatapoint`
+
+.. code-block:: yaml
+
+    tuya:
+      on_datapoint_update:
+        - sensor_datapoint: 6
+          datapoint_type: raw
+          then:
+            - lambda: |-
+                ESP_LOGD("main", "on_datapoint_update %s", hexencode(x).c_str());
+                id(voltage).publish_state((x[0] << 8 | x[1]) * 0.1);
+                id(current).publish_state((x[3] << 8 | x[4]) * 0.001);
+                id(power).publish_state((x[6] << 8 | x[7]) * 0.1);
+        - sensor_datapoint: 7 # sample dp
+          datapoint_type: string
+          then:
+            - lambda: |-
+                ESP_LOGD("main", "on_datapoint_update %s", x.c_str());
+        - sensor_datapoint: 8 # sample dp
+          datapoint_type: bool
+          then:
+            - lambda: |-
+                ESP_LOGD("main", "on_datapoint_update %s", ONOFF(x)); 
+        - sensor_datapoint: 6
+          datapoint_type: any # this is optional
+          then:
+            - lambda: |-
+                if (x.type == tuya::TuyaDatapointType::RAW) {
+                  ESP_LOGD("main", "on_datapoint_update %s", hexencode(x.value_raw).c_str());
+                } else {
+                  ESP_LOGD("main", "on_datapoint_update %hhu", x.type);
+                }
+
+Configuration variables:
+
+- **sensor_datapoint** (*Required*, int): The datapoint id number of the sensor.
+- **datapoint_type** (*Required*, string): The datapoint type one of *raw*, *string*, *bool*, *int*, *uint*, *enum*, *bitmask* or *any*.
+- See :ref:`Automation <automation>`.
+
+
 See Also
 --------
 
@@ -69,5 +133,6 @@ See Also
 - :doc:`/components/climate/tuya`
 - :doc:`/components/binary_sensor/tuya`
 - :doc:`/components/sensor/tuya`
+- :doc:`/components/text_sensor/tuya`
 - :apiref:`tuya/tuya.h`
 - :ghedit:`Edit`
diff --git a/components/uart.rst b/components/uart.rst
index 1f0486aca..3c98d7b8f 100644
--- a/components/uart.rst
+++ b/components/uart.rst
@@ -5,7 +5,7 @@ UART Bus
 
 .. seo::
     :description: Instructions for setting up a UART serial bus on ESPs
-    :image: uart.png
+    :image: uart.svg
     :keywords: UART, serial bus
 
 UART is a common serial protocol for a lot of devices. For example, when uploading a binary to your ESP
@@ -51,8 +51,8 @@ Configuration variables:
 ------------------------
 
 - **baud_rate** (**Required**, int): The baud rate of the UART bus.
-- **tx_pin** (*Optional*, :ref:`config-pin`): The pin to send data to from the ESP's perspective.
-- **rx_pin** (*Optional*, :ref:`config-pin`): The pin to receive data on from the ESP's perspective.
+- **tx_pin** (*Optional*, :ref:`config-pin`): The pin to send data to from the ESP's perspective. Use the full pin schema and set ``inverted: true`` to invert logic levels.
+- **rx_pin** (*Optional*, :ref:`config-pin`): The pin to receive data on from the ESP's perspective. Use the full pin schema and set ``inverted: true`` to invert logic levels.
 - **rx_buffer_size** (*Optional*, int): The size of the buffer used for receiving UART messages. Increase if you use an integration that needs to read big payloads from UART. Defaults to ``256``.
 - **data_bits** (*Optional*, int): The number of data bits used on the UART bus. Options: 5 to 8. Defaults to 8.
 - **parity** (*Optional*): The parity used on the UART bus. Options: ``NONE``, ``EVEN``, ``ODD``. Defaults to ``NONE``.
@@ -60,10 +60,6 @@ Configuration variables:
 - **id** (*Optional*, :ref:`config-id`): Manually specify the ID for this UART hub if you need multiple UART hubs.
 - **debug** (*Optional*, mapping): Options for debugging communication on the UART hub, see :ref:`uart-debugging`.
 
-ESP32 options:
-
-- **invert** (*Optional*, boolean): Invert the logic levels of the RX and TX pins. Options: ``true`` or ``false``. Defaults to ``false``.
-
 .. _uart-hardware_uarts:
 
 Hardware UARTs
@@ -128,9 +124,14 @@ of the debugging feature.
         direction: BOTH
         dummy_receiver: false
         after:
-          bytes: 60
+          delimiter: "\n"
         sequence:
-          - lambda: UARTDebug::log_hex(direction, bytes, ':');
+          - lambda: UARTDebug::log_string(direction, bytes);
+
+    # Minimal configuration example, logs hex strings by default
+    uart:
+      baud_rate: 9600
+      debug:
 
 - **direction** (*Optional*, enum): The direction of communication to debug, one of: "RX" (receive, incoming),
   "TX" (send, outgoing) or "BOTH". Defaults to "BOTH".
@@ -142,14 +143,14 @@ of the debugging feature.
 - **after** (*Optional*, mapping): The debugger accumulates bytes of communication. This option defines when
   to trigger publishing the accumulated bytes. The possible options are:
 
-  - **bytes** (*Optional*, int): Trigger after accumulating the specified number of bytes. Defaults to 256.
+  - **bytes** (*Optional*, int): Trigger after accumulating the specified number of bytes. Defaults to 150.
   - **timeout** (*Optional*, :ref:`config-time`): Trigger after no communication has been seen during the
     specified timeout, while one or more bytes have been accumulated. Defaults to 100ms.
   - **delimiter** (*Optional*, string or list of bytes): Trigger after the specified sequence of bytes is
     detected in the communication.
 
-- **sequence** (**Required**, :ref:`Action <config-action>`): Action(s) to perform for publishing debugging data. The
-  actions can make use of the following variables:
+- **sequence** (*Optional*, :ref:`Action <config-action>`): Action(s) to perform for publishing debugging data.
+  Defaults to an action that logs the bytes in hex format. The actions can make use of the following variables:
 
   - **direction**: ``uart::UART_DIRECTION_RX`` or ``uart::UART_DIRECTION_TX``
   - **bytes**: ``std::vector<uint8_t>`` containing the accumulated bytes
diff --git a/components/web_server.rst b/components/web_server.rst
index ebe569eef..9c1c83b7f 100644
--- a/components/web_server.rst
+++ b/components/web_server.rst
@@ -3,7 +3,7 @@ Web Server Component
 
 .. seo::
     :description: Instructions for setting up a web server in ESPHome.
-    :image: http.png
+    :image: http.svg
     :keywords: web server, http, REST API
 
 The ``web_server`` component creates a simple web server on the node that can be accessed
@@ -50,6 +50,8 @@ Configuration variables:
   - **username** (**Required**, string): The username to use for authentication.
   - **password** (**Required**, string): The password to check for authentication.
 
+- **include_internal** (*Optional*, boolean): Whether ``internal`` entities should be displayed on the
+  web interface. Defaults to ``false``.
 - **ota** (*Optional*, boolean): Turn on or off the OTA feature inside webserver. Strongly not suggested without enabled authentication settings. Default: `true`
 - **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
 
diff --git a/components/wifi.rst b/components/wifi.rst
index 641dcb85c..c466e2f3c 100644
--- a/components/wifi.rst
+++ b/components/wifi.rst
@@ -3,7 +3,7 @@ WiFi Component
 
 .. seo::
     :description: Instructions for setting up the WiFi configuration for your ESP node in ESPHome.
-    :image: network-wifi.png
+    :image: network-wifi.svg
     :keywords: WiFi, WLAN, ESP8266, ESP32
 
 This core ESPHome component sets up WiFi connections to access points
@@ -190,6 +190,16 @@ Configuration variables:
 
 - **ssid** (*Optional*, string): The SSID or WiFi network name.
 - **password** (*Optional*, string): The password to use for authentication. Leave empty for no password.
+- **manual_ip** (*Optional*): Manually configure the static IP of the node when using this network. Note that
+  when using different static IP addresses on each network, it is required to set ``use_address``, as ESPHome
+  cannot infer to which network the node is connected.
+
+  - **static_ip** (**Required**, IPv4 address): The static IP of your node.
+  - **gateway** (**Required**, IPv4 address): The gateway of the local network.
+  - **subnet** (**Required**, IPv4 address): The subnet of the local network.
+  - **dns1** (*Optional*, IPv4 address): The main DNS server to use.
+  - **dns2** (*Optional*, IPv4 address): The backup DNS server to use.
+
 - **eap** (*Optional*): See :ref:`eap`.
 - **channel** (*Optional*, int): The channel of the network (1-14). If given, only connects to networks
   that are on this channel.
diff --git a/conf.py b/conf.py
index bfa2c3903..e41b1b57e 100644
--- a/conf.py
+++ b/conf.py
@@ -67,9 +67,9 @@ author = "Otto Winter"
 # built documents.
 #
 # The short X.Y version.
-version = "2021.11"
+version = "2021.12"
 # The full version, including alpha/beta/rc tags.
-release = "2021.11.4"
+release = "2021.12.0"
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/cookbook/arduino_port_extender.rst b/cookbook/arduino_port_extender.rst
index 03c49d73e..3635b5d89 100644
--- a/cookbook/arduino_port_extender.rst
+++ b/cookbook/arduino_port_extender.rst
@@ -3,7 +3,7 @@ Arduino Port Expander
 
 .. seo::
     :description: Instructions on using an Arduino board, like the Pro Mini for expanding ports of an ESPHome node
-    :image: arduino_pro_mini.jpg
+    :image: arduino_logo.svg
     :keywords: Arduino port expander extender ESPHome
 
 With this sketch you can control pins of a remote Arduino board through ESPHome. The Arduino acts as a port
diff --git a/cookbook/display_time_temp_oled.rst b/cookbook/display_time_temp_oled.rst
index e8ea37642..ea3317f12 100644
--- a/cookbook/display_time_temp_oled.rst
+++ b/cookbook/display_time_temp_oled.rst
@@ -3,7 +3,6 @@ Time & Temperature on OLED Display
 
 .. seo::
     :description: Instructions for setting up a display in ESPHome to show sensor values from Home Assistant
-    :image: display_time_temp_oled_1.jpg
     :keywords: Display
 
 .. figure:: images/display_time_temp_oled_1.jpg
diff --git a/cookbook/endstop-cover.rst b/cookbook/endstop-cover.rst
index 501c15155..eafc4c86e 100644
--- a/cookbook/endstop-cover.rst
+++ b/cookbook/endstop-cover.rst
@@ -3,7 +3,7 @@ Template Cover with Endstops
 
 .. seo::
     :description: An example of how to integrate covers with endstops in ESPHome.
-    :image: window-open.jpg
+    :image: window-open.svg
 
 The following is an example configuration for controlling covers (like window blinds etc)
 with ESPHome. This guide assumes that the cover is set up with two endstops at the top
diff --git a/cookbook/garage-door.rst b/cookbook/garage-door.rst
index 319cb8683..542bf4d14 100644
--- a/cookbook/garage-door.rst
+++ b/cookbook/garage-door.rst
@@ -3,7 +3,7 @@ Simple Garage Door
 
 .. seo::
     :description: Instructions for setting up a simple garage door in ESPHome.
-    :image: window-open.png
+    :image: window-open.svg
 
 The following is a possible configuration file for garage doors that are controlled by two relays:
 One for opening and another one for closing the garage door. When either one of them is turned on
diff --git a/cookbook/infostrip.rst b/cookbook/infostrip.rst
index ec6c1d9a3..323a97114 100644
--- a/cookbook/infostrip.rst
+++ b/cookbook/infostrip.rst
@@ -3,7 +3,7 @@ Infostripe
 
 .. seo::
     :description: Simple visualisation of Home Assistant states using a Neopixel stripe
-    :image: infostrip-detai.jpg
+    :image: /cookbook/images/infostrip-detail.jpg
     :keywords: Neopixel
 
 Showing the current status of sensor states using a Neopixel (WS2812B) strip is a simple way to communicate states to the user.
diff --git a/cookbook/leak-detector-m5stickC.rst b/cookbook/leak-detector-m5stickC.rst
index f42a737f3..378cbe518 100644
--- a/cookbook/leak-detector-m5stickC.rst
+++ b/cookbook/leak-detector-m5stickC.rst
@@ -4,7 +4,6 @@ ESP32 Water Leak Detector (with notification)
 
 .. seo::
     :description: Water leak detector with ESPHome on an M5StickC ESP32
-    :image: images/leak-detector-m5stickC_dry.jpg
     :keywords: Leak Detector M5StickC M5Stack M5Atom
 
 Using the ESP32's capacitive touch GPIOs, it's relatively easy to build a water leak detector using ESPHome.  M5StickC was chosen as a platform due to the integrated Grove connector for clean connections and the fact it's well housed.  The built-in display is a bonus, but not strictly necessary.  Notifications are performed via HomeAssistant's 'alert' and 'notify' facilities, which send via Pushover to iOS & Android.
diff --git a/cookbook/sonoff-basic-light-switch.rst b/cookbook/sonoff-basic-light-switch.rst
index 6fa6bab26..f1de674cf 100644
--- a/cookbook/sonoff-basic-light-switch.rst
+++ b/cookbook/sonoff-basic-light-switch.rst
@@ -3,7 +3,6 @@ DIY Light switch using a Sonoff Basic
 
 .. seo::
     :description: An example of how to integrate a light switch into Home Assistant using ESPHome
-    :image: sonoff_light_switch.png
     :keywords: Relay, Sonoff Basic, Sonoff Dual Dual R1, Light, HASS, Home Assistant, ESPHome
 
 .. note::
diff --git a/cookbook/sonoff-dual-light-switch.rst b/cookbook/sonoff-dual-light-switch.rst
index 60a224058..3612fccac 100644
--- a/cookbook/sonoff-dual-light-switch.rst
+++ b/cookbook/sonoff-dual-light-switch.rst
@@ -3,7 +3,6 @@ DIY Light switch using a Sonoff Dual
 
 .. seo::
     :description: An example of how to integrate a dual light switch into Home Assistant using ESPHome
-    :image: sonoff_light_switch.png
     :keywords: Relay, Sonoff Dual Dual R1, Light, HASS, Home Assistant, ESPHome
 
 .. note::
diff --git a/cookbook/sonoff-fishpond-pump.rst b/cookbook/sonoff-fishpond-pump.rst
index 8091a8228..0a9a63a00 100644
--- a/cookbook/sonoff-fishpond-pump.rst
+++ b/cookbook/sonoff-fishpond-pump.rst
@@ -3,7 +3,7 @@ Sonoff Fish Pond Pump
 
 .. seo::
     :description: Making an automated fish pond pump with timing and auto stop safety with Sonoff Basic ESP8266 chip
-    :image: images/sonoff-fishpond-pump-installed.jpg
+    :image: cookbook-sonoff-fishpond-pump.jpg
     :keywords: sonoff, esp8266, home automation, ESPHome, hass, home assistant
 
 .. figure:: images/sonoff-fishpond.jpg
diff --git a/cookbook/sonoff-light-switch.rst b/cookbook/sonoff-light-switch.rst
index c5e72a171..e6cf29a9a 100644
--- a/cookbook/sonoff-light-switch.rst
+++ b/cookbook/sonoff-light-switch.rst
@@ -3,7 +3,6 @@ Sonoff Light switch options
 
 .. seo::
     :description: A series of options on using Sonoff devices as a light switch within ESPHome
-    :image: sonoff_light_switch.jpg
     :keywords: Relay, Sonoff Basic, Sonoff Dual Dual R1, Light, HASS, Home Assistant, ESPHome
 
 There are a number of options for using Sonoff Devices as light switches, including purpose built ones
diff --git a/cookbook/teckin_sb50.rst b/cookbook/teckin_sb50.rst
index acdbb379e..53133dba8 100644
--- a/cookbook/teckin_sb50.rst
+++ b/cookbook/teckin_sb50.rst
@@ -3,7 +3,7 @@ TECKIN SB50 LED Bulb
 
 .. seo::
     :description: ESPHome configuration for Teckin SB50 LED Bulb.
-    :image: images/teckin_sb50.jpg
+    :image: teckin_sb50.jpg
     :keywords: Teckin SB50
 
 .. figure:: images/teckin_sb50.jpg
diff --git a/cookbook/tracer-an.rst b/cookbook/tracer-an.rst
index 3ccb1ea41..9828a30e2 100644
--- a/cookbook/tracer-an.rst
+++ b/cookbook/tracer-an.rst
@@ -2,7 +2,7 @@ EPEVER® MPPT Solar Charge Controller Tracer-AN Series
 =====================================================
 .. seo::
     :description: ESPHome configuration for EPEVER® MPPT Solar Charge Controller Tracer-AN Series
-    :image: images/mages/tracer-an.jpg
+    :image: tracer-an.jpg
     :keywords: EPEVER Tracer
 
 .. figure:: images/tracer-an.jpg
@@ -33,7 +33,7 @@ Below is the ESPHome configuration file that will get you up and running. This a
       arduino_version: latest
       platformio_options:
         ## larger stack size required with all registers enable_load_test
-        ## reduce registers or wait for integration of 2.0.0 arduinoespressif32 
+        ## reduce registers or wait for integration of 2.0.0 arduinoespressif32
         ## not yet working needs 2.0
         build_flags:
           - -DCONFIG_ARDUINO_LOOP_STACK_SIZE=32768
@@ -136,7 +136,7 @@ Below is the ESPHome configuration file that will get you up and running. This a
 
     mqtt:
       id: mqtt_client
-    
+
     uart:
       id: mod_bus
       tx_pin: 19
@@ -163,7 +163,7 @@ Below is the ESPHome configuration file that will get you up and running. This a
       tracer-real-time: !include tracer-real-time.yaml
       tracer-stats: !include tracer-stats.yaml
       #tracer-settings: !include tracer-settings.yaml
-      
+
     sensor:
       - platform: template
         accuracy_decimals: 0
@@ -305,7 +305,7 @@ Below is the ESPHome configuration file that will get you up and running. This a
 
 The definitions for most sensors is included using Packages
 
-Rated Datum registers 
+Rated Datum registers
 
 tracer-rated-datum.yaml
 
@@ -624,7 +624,7 @@ tracer-real-time.yaml
 
     Statistic registers
     tracer-stats.yaml
-    
+
     .. code-block:: yaml
 
     sensor:
diff --git a/cookbook/uart_text_sensor.rst b/cookbook/uart_text_sensor.rst
index 5a578aa29..5278d8fb5 100644
--- a/cookbook/uart_text_sensor.rst
+++ b/cookbook/uart_text_sensor.rst
@@ -3,7 +3,7 @@ Custom UART Text Sensor
 
 .. seo::
     :description: Instructions for setting up a custom uart text sensor.
-    :image: language-cpp.png
+    :image: language-cpp.svg
 
 Lots of devices communicate using the UART protocol. If you want to read 
 lines from uart to a Text Sensor you can do so using this code example.
diff --git a/devices/esp32.rst b/devices/esp32.rst
index 0ecaafb1e..2e236bc04 100644
--- a/devices/esp32.rst
+++ b/devices/esp32.rst
@@ -3,7 +3,7 @@ Generic ESP32
 
 .. seo::
     :description: Information about how to use generic ESP32 boards in ESPHome.
-    :image: esp32.png
+    :image: esp32.svg
     :keywords: ESP32
 
 All devices based on the original ESP32 are supported by ESPHome. Simply select ``ESP32`` when
diff --git a/devices/esp8266.rst b/devices/esp8266.rst
index a2cf4c7d2..92045866d 100644
--- a/devices/esp8266.rst
+++ b/devices/esp8266.rst
@@ -3,7 +3,7 @@ Generic ESP8266
 
 .. seo::
     :description: Instructions for using generic ESP8266s with ESPHome.
-    :image: esp8266.png
+    :image: esp8266.svg
     :keywords: ESP8266
 
 All ESP8266-based devices are supported by ESPHome. Simply select ``ESP8266`` when
diff --git a/devices/sonoff.rst b/devices/sonoff.rst
index 9bb2eca46..e0ec5fe0e 100644
--- a/devices/sonoff.rst
+++ b/devices/sonoff.rst
@@ -3,7 +3,7 @@ Generic Sonoff
 
 .. seo::
     :description: Instructions for using generic Sonoff devices with ESPHome.
-    :image: sonoff.png
+    :image: sonoff.svg
 
 In principle ESPHome supports all Sonoff devices, but as these devices are quite cheap
 and shipping from China takes a long time, I've only set up dedicated guides for the
diff --git a/guides/automations.rst b/guides/automations.rst
index c474b2140..6fd3ad228 100644
--- a/guides/automations.rst
+++ b/guides/automations.rst
@@ -5,7 +5,7 @@ Automations and Templates
 
 .. seo::
     :description: Getting started guide for automations in ESPHome.
-    :image: auto-fix.png
+    :image: auto-fix.svg
 
 Automations and templates are two very powerful aspects of ESPHome. Automations
 allow you to perform actions under certain conditions and templates are a way to easily
diff --git a/guides/configuration-types.rst b/guides/configuration-types.rst
index c75032db6..16b63c774 100644
--- a/guides/configuration-types.rst
+++ b/guides/configuration-types.rst
@@ -3,7 +3,7 @@ Configuration Types
 
 .. seo::
     :description: Documentation of different configuration types in ESPHome
-    :image: settings.png
+    :image: settings.svg
 
 ESPHome’s configuration files have several configuration types. This
 page describes them.
diff --git a/guides/contributing.rst b/guides/contributing.rst
index 75e8be922..336cae91f 100644
--- a/guides/contributing.rst
+++ b/guides/contributing.rst
@@ -3,7 +3,7 @@ Contributing
 
 .. seo::
     :description: Getting started guide for contributing to the ESPHome project
-    :image: github-circle.png
+    :image: github-circle.svg
 
 Contributions to the ESPHome suite are very welcome! All the code for the projects
 is hosted on GitHub and you can find the sources here:
diff --git a/guides/diy.rst b/guides/diy.rst
index 03fc7cffc..45d99603c 100644
--- a/guides/diy.rst
+++ b/guides/diy.rst
@@ -3,7 +3,7 @@ DIY Examples
 
 .. seo::
     :description: Community curated list of DIY creations and custom code for ESPHome.
-    :image: earth.png
+    :image: earth.svg
 
 This is a curated list of awesome creations with ESPHome containing various
 custom components, blog posts, videos and sample configurations. It should serve as a means of
diff --git a/guides/faq.rst b/guides/faq.rst
index a0592bb8e..574fc56d7 100644
--- a/guides/faq.rst
+++ b/guides/faq.rst
@@ -3,7 +3,7 @@ Frequently Asked Questions
 
 .. seo::
     :description: Frequently asked questions in ESPHome.
-    :image: question_answer.png
+    :image: question_answer.svg
 
 Tips for using ESPHome
 ----------------------
diff --git a/guides/getting_started_command_line.rst b/guides/getting_started_command_line.rst
index 525696804..cd574c44f 100644
--- a/guides/getting_started_command_line.rst
+++ b/guides/getting_started_command_line.rst
@@ -3,7 +3,7 @@ Getting Started with ESPHome
 
 .. seo::
     :description: Getting Started guide for installing ESPHome using the command line and creating a basic configuration.
-    :image: console.png
+    :image: console.svg
 
 ESPHome is the perfect solution for creating custom firmwares for
 your ESP8266/ESP32 boards. In this guide we’ll go through how to set up a
diff --git a/guides/getting_started_hassio.rst b/guides/getting_started_hassio.rst
index 00f8643ab..2569063d9 100644
--- a/guides/getting_started_hassio.rst
+++ b/guides/getting_started_hassio.rst
@@ -3,7 +3,7 @@ Getting Started with ESPHome and Home Assistant
 
 .. seo::
     :description: Getting Started guide for installing ESPHome Dashboard as a Home Assistant add-on and creating a basic configuration.
-    :image: home-assistant.png
+    :image: home-assistant.svg
 
 ESPHome is the perfect solution for creating custom firmware for
 your ESP8266/ESP32 boards. In this guide we’ll go through how to setup a
diff --git a/guides/migrate_espeasy.rst b/guides/migrate_espeasy.rst
index bfc61a8ec..6eba19454 100644
--- a/guides/migrate_espeasy.rst
+++ b/guides/migrate_espeasy.rst
@@ -3,7 +3,7 @@ Migrating from ESPEasy
 
 .. seo::
     :description: Migration guide for installing ESPHome on ESPs running ESPEasy.
-    :image: espeasy.png
+    :image: espeasy.svg
 
 Migrating from previous ESPEasy setups is very easy. You just need to have
 ESPHome create a binary for you and then upload that in the ESPEasy web interface.
diff --git a/guides/migrate_espurna.rst b/guides/migrate_espurna.rst
index 6de6d808c..3d5b82a44 100644
--- a/guides/migrate_espurna.rst
+++ b/guides/migrate_espurna.rst
@@ -3,7 +3,7 @@ Migrating from ESPurna
 
 .. seo::
     :description: Migration guide for installing ESPHome on ESPs running ESPurna.
-    :image: espurna.png
+    :image: espurna.svg
 
 Migrating from previous ESPurna setups is very easy. You just need to have
 ESPHome create a binary for you and then upload that in the ESPurna web interface.
diff --git a/guides/migrate_sonoff_tasmota.rst b/guides/migrate_sonoff_tasmota.rst
index d7b7c9172..a0ada06e4 100644
--- a/guides/migrate_sonoff_tasmota.rst
+++ b/guides/migrate_sonoff_tasmota.rst
@@ -3,7 +3,7 @@ Migrating from Sonoff Tasmota
 
 .. seo::
     :description: Migration guide for installing ESPHome on ESPs running Sonoff Tasmota.
-    :image: tasmota.png
+    :image: tasmota.svg
 
 Migrating from previous Sonoff Tasmota setups is very easy. You just need to have
 ESPHome create a binary for you and then upload that in the Tasmota web interface.
diff --git a/guides/supporters.rst b/guides/supporters.rst
index b7a1fcb23..360c5e91e 100644
--- a/guides/supporters.rst
+++ b/guides/supporters.rst
@@ -190,6 +190,7 @@ Contributors
 - `Farzad E. (@dnetguru) <https://github.com/dnetguru>`__
 - `DrZoid (@docteurzoidberg) <https://github.com/docteurzoidberg>`__
 - `Dominik (@DomiStyle) <https://github.com/DomiStyle>`__
+- `Mark Dietzer (@Doridian) <https://github.com/Doridian>`__
 - `Jiang Sheng (@doskoi) <https://github.com/doskoi>`__
 - `Robert Schütz (@dotlambda) <https://github.com/dotlambda>`__
 - `Daniel Hyles (@DotNetDann) <https://github.com/DotNetDann>`__
@@ -335,6 +336,7 @@ Contributors
 - `Jej (@jej) <https://github.com/jej>`__
 - `Jérôme Laban (@jeromelaban) <https://github.com/jeromelaban>`__
 - `Jesse Hills (@jesserockz) <https://github.com/jesserockz>`__
+- `Yuval Brik (@jhamhader) <https://github.com/jhamhader>`__
 - `Jim Bauwens (@jimbauwens) <https://github.com/jimbauwens>`__
 - `Jérémy JOURDIN (@JJK801) <https://github.com/JJK801>`__
 - `Jonathan Jefferies (@jjok) <https://github.com/jjok>`__
@@ -359,6 +361,7 @@ Contributors
 - `Jasper van der Neut - Stulen (@jvanderneutstulen) <https://github.com/jvanderneutstulen>`__
 - `João Vitor M. Roma (@jvmr1) <https://github.com/jvmr1>`__
 - `Jack Wozny (@jwozny) <https://github.com/jwozny>`__
+- `Jozef Zuzelka (@jzlka) <https://github.com/jzlka>`__
 - `Kris (@K-r-i-s-t-i-a-n) <https://github.com/K-r-i-s-t-i-a-n>`__
 - `Harald Nagel (@k7hpn) <https://github.com/k7hpn>`__
 - `kaegi (@kaegi) <https://github.com/kaegi>`__
@@ -403,6 +406,7 @@ Contributors
 - `lcavalli (@lcavalli) <https://github.com/lcavalli>`__
 - `lein1013 (@lein1013) <https://github.com/lein1013>`__
 - `Riku Lindblad (@lepinkainen) <https://github.com/lepinkainen>`__
+- `Leon Loopik (@Lewn) <https://github.com/Lewn>`__
 - `Luca Gugelmann (@lgugelmann) <https://github.com/lgugelmann>`__
 - `Juraj Liso (@LiJu09) <https://github.com/LiJu09>`__
 - `Lazar Obradovic (@lobradov) <https://github.com/lobradov>`__
@@ -449,6 +453,7 @@ Contributors
 - `Me No Dev (@me-no-dev) <https://github.com/me-no-dev>`__
 - `Alexandr Zarubkin (@me21) <https://github.com/me21>`__
 - `Joseph Mearman (@Mearman) <https://github.com/Mearman>`__
+- `mechanarchy (@mechanarchy) <https://github.com/mechanarchy>`__
 - `Bas (@Mechazawa) <https://github.com/Mechazawa>`__
 - `Mechotronic (@Mechotronic) <https://github.com/Mechotronic>`__
 - `MeIchthys (@meichthys) <https://github.com/meichthys>`__
@@ -458,12 +463,12 @@ Contributors
 - `Michael Gorven (@mgorven) <https://github.com/mgorven>`__
 - `mhentschke (@mhentschke) <https://github.com/mhentschke>`__
 - `Michaël Arnauts (@michaelarnauts) <https://github.com/michaelarnauts>`__
+- `michaelmeller (@michaelmeller) <https://github.com/michaelmeller>`__
 - `micw (@micw) <https://github.com/micw>`__
 - `Pauline Middelink (@middelink) <https://github.com/middelink>`__
 - `Mikko Tervala (@MikkoTervala) <https://github.com/MikkoTervala>`__
 - `mikosoft83 (@mikosoft83) <https://github.com/mikosoft83>`__
 - `Minideezel (@minideezel) <https://github.com/minideezel>`__
-- `mipa87 (@mipa87) <https://github.com/mipa87>`__
 - `André Klitzing (@misery) <https://github.com/misery>`__
 - `Matthew Edwards (@mje-nz) <https://github.com/mje-nz>`__
 - `Maarten (@mjkl-gh) <https://github.com/mjkl-gh>`__
@@ -471,7 +476,6 @@ Contributors
 - `mknjc (@mknjc) <https://github.com/mknjc>`__
 - `Maurice Makaay (@mmakaay) <https://github.com/mmakaay>`__
 - `mmanza (@mmanza) <https://github.com/mmanza>`__
-- `mnaz (@mnaz) <https://github.com/mnaz>`__
 - `Michael Nieß (@mniess) <https://github.com/mniess>`__
 - `Matt N. (@mnoorenberghe) <https://github.com/mnoorenberghe>`__
 - `monkeyclass (@monkeyclass) <https://github.com/monkeyclass>`__
@@ -639,6 +643,7 @@ Contributors
 - `Stephen Tierney (@sjtrny) <https://github.com/sjtrny>`__
 - `Niklas Wagner (@Skaronator) <https://github.com/Skaronator>`__
 - `Rafael Treviño (@skasi7) <https://github.com/skasi7>`__
+- `Sebastian Lövdahl (@slovdahl) <https://github.com/slovdahl>`__
 - `Luca Zimmermann (@soundstorm) <https://github.com/soundstorm>`__
 - `Sourabh Jaiswal (@sourabhjaiswal) <https://github.com/sourabhjaiswal>`__
 - `Philip Allgaier (@spacegaier) <https://github.com/spacegaier>`__
@@ -677,7 +682,6 @@ Contributors
 - `Spencer Hachmeister (@TheHackmeister) <https://github.com/TheHackmeister>`__
 - `thejonesyboy (@thejonesyboy) <https://github.com/thejonesyboy>`__
 - `TheJulianJES (@TheJulianJES) <https://github.com/TheJulianJES>`__
-- `Jozef Zuzelka (@TheKuko) <https://github.com/TheKuko>`__
 - `Mateusz Soszyński (@TheLastGimbus) <https://github.com/TheLastGimbus>`__
 - `Zixuan Wang (@TheNetAdmin) <https://github.com/TheNetAdmin>`__
 - `Dominik Bruhn (@theomega) <https://github.com/theomega>`__
@@ -756,4 +760,4 @@ Contributors
 - `ZTX18 (@ZTX18) <https://github.com/ZTX18>`__
 - `Christian Zufferey (@zuzu59) <https://github.com/zuzu59>`__
 
-*This page was last updated November 29, 2021.*
+*This page was last updated December 12, 2021.*
diff --git a/images/pmsa003i-full.jpg b/images/pmsa003i-full.jpg
new file mode 100644
index 000000000..9adbd3bbb
Binary files /dev/null and b/images/pmsa003i-full.jpg differ
diff --git a/index.rst b/index.rst
index 61bbecf8d..44158b5bf 100644
--- a/index.rst
+++ b/index.rst
@@ -7,7 +7,7 @@
     :description: ESPHome Homepage - Reimagining DIY Home Automation. ESPHome is a framework that
       tries to provide the best possible use experience for using ESP8266 and ESP32 microcontrollers
       for Home Automation. Just write a simple YAML configuration file and get your own customized firmware.
-    :image: logo.png
+    :image: logo.svg
 
 .. image:: /images/logo-text.svg
 
@@ -283,7 +283,7 @@ Environmental
     RuuviTag, components/sensor/ruuvitag, ruuvitag.jpg, Temperature & Humidity & Accelerometer
     SCD30, components/sensor/scd30, scd30.jpg, CO2 & Temperature & Humidity
     SCD4X, components/sensor/scd4x, scd4x.jpg, CO2 & Temperature & Humidity
-    SDP3x, components/sensor/sdp3x, sdp31.jpg, Pressure
+    SDP3x / SDP800 Series, components/sensor/sdp3x, sdp31.jpg, Pressure
     SHT3X-D, components/sensor/sht3xd, sht3xd.jpg, Temperature & Humidity
     SHT4X, components/sensor/sht4x, sht4x.jpg, Temperature & Humidity
     SHTCx, components/sensor/shtcx, shtc3.jpg, Temperature & Humidity
@@ -405,6 +405,7 @@ Output Components
     SM16716, components/output/sm16716, sm16716.svg
     SM2135, components/output/sm2135, sm2135.svg
     MCP4725, components/output/mcp4725, mcp4725.jpg
+    BLE Binary Output, components/output/ble_client, bluetooth.svg
     Modbus Output, components/output/modbus_controller, modbus.png
     Custom Output, components/output/custom, language-cpp.svg
     Template Output, components/output/template, description.svg
@@ -457,6 +458,15 @@ Switch Components
     BLE Client Switch, components/switch/ble_client, bluetooth.svg
     Nextion Switch, components/switch/nextion, nextion.jpg
 
+Button Components
+-----------------
+
+.. imgtable::
+
+    Button Core, components/button/index, folder-open.svg
+    Template Button, components/button/template, description.svg
+    Restart Button, components/button/restart, restart.svg
+
 Fan Components
 --------------
 
@@ -523,6 +533,7 @@ Text Sensor Components
     Template Text Sensor, components/text_sensor/template, description.svg
     Custom Text Sensor, components/text_sensor/custom, language-cpp.svg
     Nextion Text Sensor, components/text_sensor/nextion, nextion.jpg
+    Tuya Text Sensor, components/text_sensor/tuya, tuya.png
 
 Climate Components
 ------------------
diff --git a/seo.py b/seo.py
index 1255a66cf..f8efb19f4 100644
--- a/seo.py
+++ b/seo.py
@@ -1,4 +1,5 @@
 import re
+from pathlib import Path
 
 from docutils import nodes
 from docutils.parsers.rst import Directive, directives
@@ -124,8 +125,16 @@ class SEODirective(Directive):
 
         image = self.options.get("image")
         if image is not None:
+            local_img = image
             if not image.startswith("/"):
+                local_img = f"/images/{image}"
                 image = "/_images/" + image
+            p = Path(__file__).parent / local_img[1:]
+            if not p.is_file():
+                raise ValueError(f"File {p} for seo tag does not exist {self.state.document}")
+            
+            if image.endswith(".svg"):
+                image = image[:-len(".svg")] + ".png"
             self.options["image"] = env.config.html_baseurl + image
         return [SEONode(**self.options)]
 
diff --git a/svg2png.py b/svg2png.py
index fe5165aeb..95c31e5e8 100644
--- a/svg2png.py
+++ b/svg2png.py
@@ -9,8 +9,6 @@ import sys
 
 to_p = Path("svg2png")
 to_p.mkdir(exist_ok=True)
-for f in to_p.glob("*.png"):
-    f.unlink()
 
 images = [
     f
@@ -27,23 +25,19 @@ def worker():
             break
 
         to = to_p / item.with_suffix(".png").name
+        if to.is_file():
+            q.task_done()
+            continue
         args = [
             "inkscape",
-            "-z",
-            "-e",
-            str(to.absolute()),
+            f"--export-filename={to.absolute()}",
             "-w",
             "800",
-            "-background",
-            "white",
+            "--export-background=white",
             str(item.absolute()),
         ]
         print("Running:  {}".format(" ".join(shlex.quote(x) for x in args)))
-        proc = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-        if b"Bitmap saved as" not in proc.stdout:
-            print("Error!")
-            print(proc.stdout)
-            sys.exit(1)
+        subprocess.check_call(args)
 
         q.task_done()
 
diff --git a/svg2png/canbus.png b/svg2png/canbus.png
new file mode 100644
index 000000000..6257437b0
Binary files /dev/null and b/svg2png/canbus.png differ
diff --git a/svg2png/dsmr.png b/svg2png/dsmr.png
new file mode 100644
index 000000000..8fb3bd434
Binary files /dev/null and b/svg2png/dsmr.png differ
diff --git a/svg2png/external_components.png b/svg2png/external_components.png
new file mode 100644
index 000000000..91ff7f773
Binary files /dev/null and b/svg2png/external_components.png differ
diff --git a/svg2png/fingerprint.png b/svg2png/fingerprint.png
new file mode 100644
index 000000000..3f5524f72
Binary files /dev/null and b/svg2png/fingerprint.png differ
diff --git a/svg2png/improv.png b/svg2png/improv.png
new file mode 100644
index 000000000..2ac6dac8b
Binary files /dev/null and b/svg2png/improv.png differ
diff --git a/svg2png/made-for-esphome-black-on-transparent.png b/svg2png/made-for-esphome-black-on-transparent.png
new file mode 100644
index 000000000..967538bd7
Binary files /dev/null and b/svg2png/made-for-esphome-black-on-transparent.png differ
diff --git a/svg2png/made-for-esphome-black-on-white.png b/svg2png/made-for-esphome-black-on-white.png
new file mode 100644
index 000000000..06edeec48
Binary files /dev/null and b/svg2png/made-for-esphome-black-on-white.png differ
diff --git a/svg2png/made-for-esphome-white-on-black.png b/svg2png/made-for-esphome-white-on-black.png
new file mode 100644
index 000000000..44d61983a
Binary files /dev/null and b/svg2png/made-for-esphome-white-on-black.png differ
diff --git a/svg2png/made-for-esphome-white-on-transparent.png b/svg2png/made-for-esphome-white-on-transparent.png
new file mode 100644
index 000000000..f6713d636
Binary files /dev/null and b/svg2png/made-for-esphome-white-on-transparent.png differ
diff --git a/svg2png/midea.png b/svg2png/midea.png
new file mode 100644
index 000000000..04f7026ca
Binary files /dev/null and b/svg2png/midea.png differ
diff --git a/svg2png/restart-alert.png b/svg2png/restart-alert.png
new file mode 100644
index 000000000..d1d12de9f
Binary files /dev/null and b/svg2png/restart-alert.png differ
diff --git a/svg2png/sm2135.png b/svg2png/sm2135.png
new file mode 100644
index 000000000..a91a8701e
Binary files /dev/null and b/svg2png/sm2135.png differ
diff --git a/web-api/index.rst b/web-api/index.rst
index e09e4d538..4136fd079 100644
--- a/web-api/index.rst
+++ b/web-api/index.rst
@@ -3,7 +3,7 @@ Web Server API
 
 .. seo::
     :description: Migration guide for installing ESPHome on ESPs running ESPEasy.
-    :image: espeasy.png
+    :image: espeasy.svg
 
 Since version 1.3, ESPHome includes a built-in web server that can be used to view states
 and send commands. In addition to the web-frontend available under the root index of the