More custom component guides

This commit is contained in:
Otto Winter 2018-11-27 17:05:23 +01:00
parent 6dc1d15ffa
commit fe4551f14c
No known key found for this signature in database
GPG Key ID: DB66C0BE6013F97E
5 changed files with 260 additions and 17 deletions

View File

@ -4,8 +4,12 @@ Custom Binary Sensor
This integration can be used to create custom binary sensors in esphomelib
using the C++ (Arduino) API.
Please first read :doc:`/esphomeyaml/components/sensor/custom`, the same principles apply here and binary sensors are
very similar to sensors internally.
Please first read :doc:`/esphomeyaml/components/sensor/custom` guide,
the same principles apply here and binary sensors are very similar
to sensors internally.
The example below is an example of a custom binary sensor; this custom sensor is essentially the
same as the gpio binary sensor.
.. code-block:: cpp
@ -19,15 +23,14 @@ very similar to sensors internally.
void setup() override {
// This will be called by App.setup()
pinMode(5, INPUT);
}
void update() override {
// This will be called every "update_interval" milliseconds.
// Publish an OFF state
publish_state(false);
// Publish an ON state
publish_state(false);
bool state = digitalRead(5)
publish_state(state);
}
};
@ -46,8 +49,8 @@ And in YAML:
- platform: custom
lambda: |-
auto my_custom_sensor = new MyCustomBinarySensor();
App.register_component(my_sensor);
return {my_sensor};
App.register_component(my_custom_sensor);
return {my_custom_sensor};
binary_sensors:
name: "My Custom Binary Sensor"
@ -61,6 +64,8 @@ Configuration variables:
- All options from :ref:`Binary Sensor <config-binary_sensor>` and :ref:`MQTT Component <config-mqtt-component>`.
See :cpp:class:`binary_sensor::BinarySensor`
See Also
--------

View File

@ -0,0 +1,94 @@
Custom Output
=============
This integration can be used to create custom binary and float :doc:`outputs </esphomeyaml/components/output/index>`
in esphomelib using the C++ (Arduino) API.
Please first read :doc:`/esphomeyaml/components/sensor/custom` guide, the same principles apply here.
The example below is an example of a custom float output; this custom output is essentially the
same as the :doc:`ESP8266 software PWM output </esphomeyaml/components/output/esp8266_pwm>`.
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomFloatOutput : public Component, public output::FloatOutput {
public:
void setup() override {
// This will be called by App.setup()
pinMode(5, OUTPUT);
}
void write_state(float state) override {
// state is the amount this output should be on, from 0.0 to 1.0
// we need to convert it to an integer first
int value = state * 1024;
analogWrite(5, value);
}
};
// Custom binary output, for exposing binary states
class MyCustomBinaryOutput : public Component, public output::BinaryOutput {
public:
void setup() override {
// This will be called by App.setup()
pinMode(5, OUTPUT);
}
void write_state(bool state) override {
digitalWrite(5, state);
}
};
(Store this file in your configuration directory, for example ``my_output.h``)
And in YAML:
.. code-block:: yaml
# Example configuration entry
esphomeyaml:
includes:
- my_output.h
output:
- platform: custom
type: float
lambda: |-
auto my_custom_float_output = new MyCustomFloatOutput();
App.register_component(my_custom_float_output);
return {my_custom_float_output};
outputs:
id: custom_float
- platform: custom
type: binary
lambda: |-
auto my_custom_binary_output = new MyCustomBinaryOutput();
App.register_component(my_custom_binary_output);
return {my_custom_binary_output};
outputs:
id: custom_binary
Configuration variables:
- **type** (**Required**, string): The type of output. One of ``binary`` and ``float``.
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
output(s).
- **outputs** (**Required**, list): A list of outputs to initialize. The length here
must equal the number of items in the ``return`` statement of the ``lambda``.
- All options from :ref:`Output <config-output>`.
See :cpp:class:`output::BinaryOutput` and :cpp:class`output::FloatOutput`.
See Also
--------
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/components/output/custom.rst>`__
.. disqus::

View File

@ -82,8 +82,9 @@ Let's now also take a closer look at this line, which you might not be too used
class MyCustomSensor : public Component, public sensor::Sensor {
What this line is essentially saying is that we're defining our own class that's called ``MyCustomSensor``
which is also a subclass of ``Component`` and ``Sensor`` (in the namespace ``sensor::``).
As described before, these two "parent" classes have special semantics that we will make use of.
which is also a subclass of :cpp:class:`Component` and :cpp:class:`sensor::Sensor`
(in the namespace ``sensor::``). As described before, these two "parent" classes have
special semantics that we will make use of.
We *could* go implement our own sensor code now by replacing the contents of ``setup()`` and ``loop()``.
In ``setup()`` we would initialize the sensor and in ``loop()`` we would read out the sensor and publish
@ -93,10 +94,10 @@ However, there's a small problem with that approach: ``loop()`` gets called very
If we would publish a new state each time that method is called we would quickly make the node unresponsive
since the MQTT protocol wasn't really designed for 60 messages per second.
So this fix this, we will use an alternative class to ``Component``: ``PollingComponent``. This class
is for situations where you have something that should get called repeatedly with some **update interval**.
In the code above, we can simply replace ``Component`` by ``PollingComponent`` and ``loop()`` by a special
method ``update()`` which will be called with an interval we can specify.
So this fix this, we will use an alternative class to :cpp:class:`Component`: :cpp:class`PollingComponent`.
This class is for situations where you have something that should get called repeatedly with some **update interval**.
In the code above, we can simply replace :cpp:class:`Component` by :cpp:class:`PollingComponent` and
``loop()`` by a special method ``update()`` which will be called with an interval we can specify.
.. code-block:: cpp
@ -114,11 +115,11 @@ method ``update()`` which will be called with an interval we can specify.
};
Our code has slightly changed, as explained above we're now inheriting from ``PollingComponent`` instead of
just ``Component``. Additionally, we now have a new line: the constructor. You also don't really need to
Our code has slightly changed, as explained above we're now inheriting from :cpp:class:`PollingComponent` instead of
just :cpp:class:`Component`. Additionally, we now have a new line: the constructor. You also don't really need to
know much about constructors here, so to simplify let's just say this is where we "initialize" the custom sensor.
In this constructor we're telling the compiler that we want ``PollingComponent`` to be instantiated with an
In this constructor we're telling the compiler that we want :cpp:class:`PollingComponent` to be instantiated with an
*update interval* of 15s, or 15000 milliseconds (esphomelib uses milliseconds internally).
Let's also now make our sensor actually publish values in the ``update()`` method:

View File

@ -0,0 +1,72 @@
Custom Switch
=============
This integration can be used to create custom switches in esphomelib
using the C++ (Arduino) API.
Please first read :doc:`/esphomeyaml/components/sensor/custom` guide,
the same principles apply here.
The example below is an example of a custom switch; this custom switch is essentially the
same as the gpio switch implementation.
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
// namespace is called 'switch_' because 'switch' is a reserved keyword
class MyCustomSwitch : public Component, public switch_::Switch {
public:
void setup() override {
// This will be called by App.setup()
pinMode(5, INPUT);
}
void write_state(bool state) override {
// This will be called every time the user requests a state change.
digitalWrite(5, state);
// Acknowledge new state by publishing it
publish_state(state);
}
};
(Store this file in your configuration directory, for example ``my_switch.h``)
And in YAML:
.. code-block:: yaml
# Example configuration entry
esphomeyaml:
includes:
- my_switch.h
switch:
- platform: custom
lambda: |-
auto my_custom_switch = new MyCustomSwitch();
App.register_component(my_custom_switch);
return {my_custom_switch};
switches:
name: "My Custom Switches"
Configuration variables:
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
switch(es).
- **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:`Switch <config-switch>` and :ref:`MQTT Component <config-mqtt-component>`.
See :cpp:class:`switch_::Switch`
See Also
--------
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/components/switch/custom.rst>`__
.. disqus::

View File

@ -0,0 +1,71 @@
Custom Text Sensor
==================
This integration can be used to create custom text sensors in esphomelib
using the C++ (Arduino) API.
Please first read :doc:`/esphomeyaml/components/sensor/custom` guide,
the same principles apply here and text sensors are very similar
to sensors internally.
The example below is an example of a custom text sensor which constantly publishes
the message "Hello World!".
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomTextSensor : public PollingComponent, public text_sensor::TextSensor {
public:
// constructor
MyCustomTextSensor() : PollingComponent(15000) {}
void setup() override {
// This will be called by App.setup()
}
void update() override {
// This will be called every "update_interval" milliseconds.
// Publish state
publish_state("Hello World!");
}
};
(Store this file in your configuration directory, for example ``my_text_sensor.h``)
And in YAML:
.. code-block:: yaml
# Example configuration entry
esphomeyaml:
includes:
- my_text_sensor.h
text_sensor:
- platform: custom
lambda: |-
auto my_custom_sensor = new MyCustomTextSensor();
App.register_component(my_custom_sensor);
return {my_custom_sensor};
text_sensors:
name: "My Custom Text Sensor"
Configuration variables:
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
text sensor(s).
- **text_sensors** (**Required**, list): A list of text sensors to initialize. The length here
must equal the number of items in the ``return`` statement of the ``lambda``.
- All options from :ref:`Text Sensor <config-text_sensor>` and :ref:`MQTT Component <config-mqtt-component>`.
See :cpp:class:`text_sensor::TextSensor`
See Also
--------
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/components/text_sensor/custom.rst>`__
.. disqus::