mirror of
https://github.com/esphome/esphome-docs.git
synced 2024-09-27 04:13:07 +02:00
Custom stuff
This commit is contained in:
parent
c1fe08f927
commit
fb22c082c8
4
Makefile
4
Makefile
@ -4,10 +4,10 @@ ESPHOME_REF = dev
|
|||||||
.PHONY: html html-strict cleanhtml deploy help webserver Makefile netlify netlify-api api netlify-dependencies svg2png copy-svg2png
|
.PHONY: html html-strict cleanhtml deploy help webserver Makefile netlify netlify-api api netlify-dependencies svg2png copy-svg2png
|
||||||
|
|
||||||
html:
|
html:
|
||||||
sphinx-build -M html . _build $(O)
|
sphinx-build -M html . _build -j auto -n $(O)
|
||||||
|
|
||||||
html-strict:
|
html-strict:
|
||||||
sphinx-build -M html . _build -W $(O)
|
sphinx-build -M html . _build -W -j auto -n $(O)
|
||||||
|
|
||||||
cleanhtml:
|
cleanhtml:
|
||||||
rm -rf "_build/html/*"
|
rm -rf "_build/html/*"
|
||||||
|
@ -55,7 +55,7 @@ New Components
|
|||||||
- The new :doc:`remote receiver </components/remote_receiver>` and
|
- The new :doc:`remote receiver </components/remote_receiver>` and
|
||||||
:doc:`remote transmitter </components/remote_transmitter>` components now allows you to use any 433MHz
|
:doc:`remote transmitter </components/remote_transmitter>` components now allows you to use any 433MHz
|
||||||
receivers and senders with ESPHome. Currently, you will need to use the ``raw`` data as described in
|
receivers and senders with ESPHome. Currently, you will need to use the ``raw`` data as described in
|
||||||
:ref:`this guide <finding_remote_codes>`, but in the future more protocols will be supported out of the box.
|
this guide, but in the future more protocols will be supported out of the box.
|
||||||
|
|
||||||
New Features
|
New Features
|
||||||
************
|
************
|
||||||
|
83
components/climate/custom.rst
Normal file
83
components/climate/custom.rst
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
Custom Climate
|
||||||
|
==============
|
||||||
|
|
||||||
|
This integration can be used to create custom switches in ESPHome
|
||||||
|
using the C++ (Arduino) API.
|
||||||
|
|
||||||
|
Please first read :doc:`/components/sensor/custom` guide,
|
||||||
|
the same principles apply here.
|
||||||
|
|
||||||
|
The example below is an example of a custom climate device - all climate devices must override
|
||||||
|
two methods (:apiclass:`Climate <climate::Climate>`):
|
||||||
|
|
||||||
|
- ``traits``: This should return a :apiclass:`ClimateTraits <climate::ClimateTraits>` object
|
||||||
|
representing the capabilities of the climate device.
|
||||||
|
- ``control``: This receives a :apiclass:`ClimateCall <climate::ClimateCall>` object that contains
|
||||||
|
the command the user tried to set.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
#include "esphome.h"
|
||||||
|
|
||||||
|
class MyCustomClimate : public Component, public Climate {
|
||||||
|
public:
|
||||||
|
void setup() override {
|
||||||
|
// This will be called by App.setup()
|
||||||
|
}
|
||||||
|
void control(const ClimateCall &call) override {
|
||||||
|
if (call.get_mode().has_value()) {
|
||||||
|
// User requested mode change
|
||||||
|
ClimateMode mode = *call.get_mode();
|
||||||
|
// Send mode to hardware
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Publish updated state
|
||||||
|
this->mode = mode;
|
||||||
|
this->publish_state();
|
||||||
|
}
|
||||||
|
if (call.get_target_temperature().has_value()) {
|
||||||
|
// User requested target temperature change
|
||||||
|
float temp = *call.get_target_temperature();
|
||||||
|
// Send target temp to climate
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(Store this file in your configuration directory, for example ``my_climate.h``)
|
||||||
|
|
||||||
|
And in YAML:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
# Example configuration entry
|
||||||
|
esphome:
|
||||||
|
includes:
|
||||||
|
- my_switch.h
|
||||||
|
|
||||||
|
climate:
|
||||||
|
- platform: custom
|
||||||
|
lambda: |-
|
||||||
|
auto my_custom_climate = new MyCustomClimate();
|
||||||
|
App.register_component(my_custom_climate);
|
||||||
|
return {my_custom_climate};
|
||||||
|
|
||||||
|
climates:
|
||||||
|
- name: "My Custom Climate"
|
||||||
|
|
||||||
|
Configuration variables:
|
||||||
|
|
||||||
|
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
|
||||||
|
climate(s).
|
||||||
|
- **switches** (**Required**, list): A list of switches to initialize. The length here
|
||||||
|
must equal the number of items in the ``return`` statement of the ``lambda``.
|
||||||
|
|
||||||
|
- All options from :ref:`Climate <config-climate>`.
|
||||||
|
|
||||||
|
See :apiclass:`Climate <climate::Climate>`
|
||||||
|
|
||||||
|
See Also
|
||||||
|
--------
|
||||||
|
|
||||||
|
- :ghedit:`Edit`
|
87
components/cover/custom.rst
Normal file
87
components/cover/custom.rst
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
Custom Cover
|
||||||
|
============
|
||||||
|
|
||||||
|
This integration can be used to create custom covers in ESPHome
|
||||||
|
using the C++ (Arduino) API.
|
||||||
|
|
||||||
|
Please first read :doc:`/components/sensor/custom` guide,
|
||||||
|
the same principles apply here.
|
||||||
|
|
||||||
|
The example below is an example of a custom cover - all covers must override
|
||||||
|
two methods:
|
||||||
|
|
||||||
|
- ``get_traits``: This should return a :apiclass:`CoverTraits <cover::CoverTraits>` object
|
||||||
|
representing the capabilities of the cover.
|
||||||
|
- ``control``: This receives a :apiclass:`CoverCall <cover::CoverCall>` object that contains
|
||||||
|
the command the user tried to set.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
#include "esphome.h"
|
||||||
|
|
||||||
|
class MyCustomCover : public Component, public Cover {
|
||||||
|
public:
|
||||||
|
void setup() override {
|
||||||
|
// This will be called by App.setup()
|
||||||
|
pinMode(5, INPUT);
|
||||||
|
}
|
||||||
|
CoverTraits get_traits() override {
|
||||||
|
auto traits = CoverTraits();
|
||||||
|
traits.set_is_assumed_state(false);
|
||||||
|
traits.set_supports_position(true);
|
||||||
|
traits.set_supports_tilt(false);
|
||||||
|
return traits;
|
||||||
|
}
|
||||||
|
void control(const CoverCall &call) override {
|
||||||
|
// This will be called every time the user requests a state change.
|
||||||
|
if (call.get_position().has_value()) {
|
||||||
|
float pos = *call.get_position();
|
||||||
|
// Write pos (range 0-1) to cover
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Publish new state
|
||||||
|
this->position = pos;
|
||||||
|
this->publish_state();
|
||||||
|
}
|
||||||
|
if (call.get_stop()) {
|
||||||
|
// User requested cover stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(Store this file in your configuration directory, for example ``my_cover.h``)
|
||||||
|
|
||||||
|
And in YAML:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
# Example configuration entry
|
||||||
|
esphome:
|
||||||
|
includes:
|
||||||
|
- my_cover.h
|
||||||
|
|
||||||
|
cover:
|
||||||
|
- platform: custom
|
||||||
|
lambda: |-
|
||||||
|
auto my_custom_cover = new MyCustomCover();
|
||||||
|
App.register_component(my_custom_cover);
|
||||||
|
return {my_custom_cover};
|
||||||
|
|
||||||
|
covers:
|
||||||
|
- name: "My Custom Cover"
|
||||||
|
|
||||||
|
Configuration variables:
|
||||||
|
|
||||||
|
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
|
||||||
|
cover(s).
|
||||||
|
- **covers** (**Required**, list): A list of covers to initialize. The length here
|
||||||
|
must equal the number of items in the ``return`` statement of the ``lambda``.
|
||||||
|
|
||||||
|
- All options from :ref:`Cover <config-cover>`.
|
||||||
|
|
||||||
|
See :apiclass:`Cover <cover::Cover>`
|
||||||
|
|
||||||
|
See Also
|
||||||
|
--------
|
||||||
|
|
||||||
|
- :ghedit:`Edit`
|
81
components/light/custom.rst
Normal file
81
components/light/custom.rst
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
Custom Light Output
|
||||||
|
===================
|
||||||
|
|
||||||
|
This integration can be used to create custom lights in ESPHome
|
||||||
|
using the C++ (Arduino) API.
|
||||||
|
|
||||||
|
Please first read :doc:`/components/sensor/custom` guide,
|
||||||
|
the same principles apply here.
|
||||||
|
|
||||||
|
All internal stuff (like effects, transitions etc) is handled by the light core
|
||||||
|
and cannot be overriden. Light outputs are only responsible for displaying some state
|
||||||
|
when asked to do so.
|
||||||
|
|
||||||
|
The example below is an example of a custom light output.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
#include "esphome.h"
|
||||||
|
|
||||||
|
class MyCustomLightOutput : public Component, public LightOutput {
|
||||||
|
public:
|
||||||
|
void setup() override {
|
||||||
|
// This will be called by App.setup()
|
||||||
|
pinMode(5, INPUT);
|
||||||
|
}
|
||||||
|
LightTraits get_traits() override {
|
||||||
|
// return the traits this light supports
|
||||||
|
auto traits = LightTraits();
|
||||||
|
traits.set_supports_brightness(true);
|
||||||
|
traits.set_supports_rgb(true);
|
||||||
|
traits.set_supports_rgb_white_value(false);
|
||||||
|
traits.set_supports_color_temperature(false);
|
||||||
|
return traits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_state(LightState *state) override {
|
||||||
|
// This will be called by the light to get a new state to be written.
|
||||||
|
float red, green, blue;
|
||||||
|
// use any of the provided current_values methods
|
||||||
|
state->current_values_as_rgb(&red, &green, &blue);
|
||||||
|
// Write red, green and blue to HW
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(Store this file in your configuration directory, for example ``my_light.h``)
|
||||||
|
|
||||||
|
And in YAML:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
# Example configuration entry
|
||||||
|
esphome:
|
||||||
|
includes:
|
||||||
|
- my_cover.h
|
||||||
|
|
||||||
|
light:
|
||||||
|
- platform: custom
|
||||||
|
lambda: |-
|
||||||
|
auto light_out = new MyCustomLightOutput();
|
||||||
|
App.register_component(light_out);
|
||||||
|
return {light_out};
|
||||||
|
|
||||||
|
lights:
|
||||||
|
- name: "My Custom Light"
|
||||||
|
|
||||||
|
Configuration variables:
|
||||||
|
|
||||||
|
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
|
||||||
|
light output(s).
|
||||||
|
- **lights** (**Required**, list): A list of lights to initialize. The length here
|
||||||
|
must equal the number of items in the ``return`` statement of the ``lambda``.
|
||||||
|
|
||||||
|
- All options from :ref:`Light <config-light>`.
|
||||||
|
|
||||||
|
See :apiclass:`Light <light::LightOutput>`
|
||||||
|
|
||||||
|
See Also
|
||||||
|
--------
|
||||||
|
|
||||||
|
- :ghedit:`Edit`
|
@ -265,3 +265,6 @@ def setup(app):
|
|||||||
app.add_role('ghedit', ghedit_role)
|
app.add_role('ghedit', ghedit_role)
|
||||||
app.add_directive('imgtable', ImageTableDirective)
|
app.add_directive('imgtable', ImageTableDirective)
|
||||||
app.add_directive('pintable', PinTableDirective)
|
app.add_directive('pintable', PinTableDirective)
|
||||||
|
return {"version": "1.0.0",
|
||||||
|
"parallel_read_safe": True,
|
||||||
|
"parallel_write_safe": True}
|
||||||
|
@ -188,6 +188,7 @@ Light Components
|
|||||||
|
|
||||||
NeoPixelBus Light, components/light/neopixelbus, color_lens.svg
|
NeoPixelBus Light, components/light/neopixelbus, color_lens.svg
|
||||||
Light Partition, components/light/partition, color_lens.svg
|
Light Partition, components/light/partition, color_lens.svg
|
||||||
|
Custom Light, components/light/custom, language-cpp.svg
|
||||||
|
|
||||||
Looking for WS2811 and similar individually addressable lights? Have a look at the
|
Looking for WS2811 and similar individually addressable lights? Have a look at the
|
||||||
:doc:`FastLED Light </components/light/fastled>`.
|
:doc:`FastLED Light </components/light/fastled>`.
|
||||||
@ -236,6 +237,7 @@ Cover Components
|
|||||||
Template Cover, components/cover/template, description.svg
|
Template Cover, components/cover/template, description.svg
|
||||||
Endstop Cover, components/cover/endstop, electric-switch.svg
|
Endstop Cover, components/cover/endstop, electric-switch.svg
|
||||||
Time-Based Cover, components/cover/time_based, timer.svg
|
Time-Based Cover, components/cover/time_based, timer.svg
|
||||||
|
Custom Cover, components/cover/custom, language-cpp.svg
|
||||||
|
|
||||||
Text Sensor Components
|
Text Sensor Components
|
||||||
----------------------
|
----------------------
|
||||||
@ -257,6 +259,7 @@ Climate Components
|
|||||||
|
|
||||||
Climate Core, components/climate/index, folder-open.svg
|
Climate Core, components/climate/index, folder-open.svg
|
||||||
Bang Bang Controller, components/climate/bang_bang, air-conditioner.svg
|
Bang Bang Controller, components/climate/bang_bang, air-conditioner.svg
|
||||||
|
Custom Climate, components/climate/custom, language-cpp.svg
|
||||||
|
|
||||||
Misc Components
|
Misc Components
|
||||||
---------------
|
---------------
|
||||||
|
4
seo.py
4
seo.py
@ -126,4 +126,6 @@ def setup(app):
|
|||||||
app.add_node(SEONode, html=(seo_visit, seo_depart))
|
app.add_node(SEONode, html=(seo_visit, seo_depart))
|
||||||
app.add_directive('redirect', RedirectDirective)
|
app.add_directive('redirect', RedirectDirective)
|
||||||
app.add_node(RedirectNode, html=(redirect_visit, redirect_depart))
|
app.add_node(RedirectNode, html=(redirect_visit, redirect_depart))
|
||||||
return {'version': '1.0'}
|
return {"version": "1.0.0",
|
||||||
|
"parallel_read_safe": True,
|
||||||
|
"parallel_write_safe": True}
|
||||||
|
@ -7,6 +7,9 @@ def setup(app):
|
|||||||
app.connect('html-page-context', add_html_link)
|
app.connect('html-page-context', add_html_link)
|
||||||
app.connect('build-finished', create_sitemap)
|
app.connect('build-finished', create_sitemap)
|
||||||
app.sitemap_links = []
|
app.sitemap_links = []
|
||||||
|
return {"version": "1.0.0",
|
||||||
|
"parallel_read_safe": True,
|
||||||
|
"parallel_write_safe": True}
|
||||||
|
|
||||||
|
|
||||||
def add_html_link(app, pagename, templatename, context, doctree):
|
def add_html_link(app, pagename, templatename, context, doctree):
|
||||||
@ -18,6 +21,7 @@ def create_sitemap(app, exception):
|
|||||||
"""Generates the sitemap.xml from the collected HTML page links"""
|
"""Generates the sitemap.xml from the collected HTML page links"""
|
||||||
root = ET.Element("urlset")
|
root = ET.Element("urlset")
|
||||||
root.set("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9")
|
root.set("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9")
|
||||||
|
app.sitemap_links.sort()
|
||||||
|
|
||||||
for link in app.sitemap_links:
|
for link in app.sitemap_links:
|
||||||
url = ET.SubElement(root, "url")
|
url = ET.SubElement(root, "url")
|
||||||
|
Loading…
Reference in New Issue
Block a user