Skip to content

Commit

Permalink
Custom stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
OttoWinter committed May 15, 2019
1 parent c1fe08f commit fb22c08
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

html:
sphinx-build -M html . _build $(O)
sphinx-build -M html . _build -j auto -n $(O)

html-strict:
sphinx-build -M html . _build -W $(O)
sphinx-build -M html . _build -W -j auto -n $(O)

cleanhtml:
rm -rf "_build/html/*"
Expand Down
2 changes: 1 addition & 1 deletion changelog/v1.7.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ New Components
- The new :doc:`remote receiver </components/remote_receiver>` and
: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
: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
************
Expand Down
83 changes: 83 additions & 0 deletions components/climate/custom.rst
Original file line number Diff line number Diff line change
@@ -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 changes: 87 additions & 0 deletions components/cover/custom.rst
Original file line number Diff line number Diff line change
@@ -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 changes: 81 additions & 0 deletions components/light/custom.rst
Original file line number Diff line number Diff line change
@@ -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`
3 changes: 3 additions & 0 deletions github.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,6 @@ def setup(app):
app.add_role('ghedit', ghedit_role)
app.add_directive('imgtable', ImageTableDirective)
app.add_directive('pintable', PinTableDirective)
return {"version": "1.0.0",
"parallel_read_safe": True,
"parallel_write_safe": True}
3 changes: 3 additions & 0 deletions index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ Light Components

NeoPixelBus Light, components/light/neopixelbus, 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
:doc:`FastLED Light </components/light/fastled>`.
Expand Down Expand Up @@ -236,6 +237,7 @@ Cover Components
Template Cover, components/cover/template, description.svg
Endstop Cover, components/cover/endstop, electric-switch.svg
Time-Based Cover, components/cover/time_based, timer.svg
Custom Cover, components/cover/custom, language-cpp.svg

Text Sensor Components
----------------------
Expand All @@ -257,6 +259,7 @@ Climate Components

Climate Core, components/climate/index, folder-open.svg
Bang Bang Controller, components/climate/bang_bang, air-conditioner.svg
Custom Climate, components/climate/custom, language-cpp.svg

Misc Components
---------------
Expand Down
4 changes: 3 additions & 1 deletion seo.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,6 @@ def setup(app):
app.add_node(SEONode, html=(seo_visit, seo_depart))
app.add_directive('redirect', RedirectDirective)
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}
4 changes: 4 additions & 0 deletions sitemap.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ def setup(app):
app.connect('html-page-context', add_html_link)
app.connect('build-finished', create_sitemap)
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):
Expand All @@ -18,6 +21,7 @@ def create_sitemap(app, exception):
"""Generates the sitemap.xml from the collected HTML page links"""
root = ET.Element("urlset")
root.set("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9")
app.sitemap_links.sort()

for link in app.sitemap_links:
url = ET.SubElement(root, "url")
Expand Down

0 comments on commit fb22c08

Please sign in to comment.