Merge branch 'custom-sensor' into next

This commit is contained in:
Otto Winter 2019-01-06 18:20:21 +01:00
commit aad3f5a133
No known key found for this signature in database
GPG Key ID: DB66C0BE6013F97E
39 changed files with 1086 additions and 266 deletions

View File

@ -119,3 +119,13 @@ Triggers
:members:
:protected-members:
:undoc-members:
.. doxygenclass:: binary_sensor::BinarySensorCondition
:members:
:protected-members:
:undoc-members:
.. doxygenclass:: binary_sensor::CustomBinarySensorConstructor
:members:
:protected-members:
:undoc-members:

View File

@ -17,6 +17,7 @@ MQTTClientComponent
:undoc-members:
.. doxygentypedef:: mqtt::mqtt_callback_t
.. doxygentypedef:: mqtt::mqtt_json_callback_t
.. doxygenstruct:: mqtt::MQTTMessage
:members:
@ -83,3 +84,13 @@ Actions
:members:
:protected-members:
:undoc-members:
.. _api-custom_mqtt_device:
CustomMQTTDevice
****************
.. doxygenclass:: mqtt::CustomMQTTDevice
:members:
:protected-members:
:undoc-members:

View File

@ -26,7 +26,7 @@ API Reference
.. cpp:namespace:: nullptr
.. doxygenenum:: PCF8574GPIOMode
.. doxygenenum:: io::PCF8574GPIOMode
.. doxygenclass:: io::PCF8574Component
:members:

View File

@ -37,6 +37,11 @@ GPIOSwitch
:protected-members:
:undoc-members:
.. doxygenclass:: switch_::SwitchCondition
:members:
:protected-members:
:undoc-members:
MQTTSwitchComponent
*******************

View File

@ -64,7 +64,7 @@ New Features
triggered when an active WiFi and MQTT connection existed. Large parts of the WiFi and MQTT clients has now
been rewritten to allow for automations to be executed asynchronously, while the device is still connecting to WiFi.
- The HassIO add-on now has a new ``password`` option with which you can secure your installation. See
- The Hass.io add-on now has a new ``password`` option with which you can secure your installation. See
:doc:`/esphomeyaml/guides/getting_started_hassio`. 🔒
- Binary Sensors now have filters too. They can now be used to debounce any binary sensor and do some more
@ -81,7 +81,7 @@ New Features
:ref:`esphomeyaml.on_shutdown <esphomeyaml-on_shutdown>` with which you can do some advanced cleanup/setup
on boot and shutdown of the node.
- All HassIO add-on builds have now been more or less completely automated using a private Gitlab server. You
- All Hass.io add-on builds have now been more or less completely automated using a private Gitlab server. You
can find all the new docker files `here <https://github.com/OttoWinter/esphomeyaml/tree/master/docker>`__.
- Added a new ``build_path`` option in the ``esphomeyaml`` section with which you can customize where

View File

@ -110,7 +110,7 @@ Other notable changes
- Fixed HTU21D readings only working in very verbose mode
- Sometimes the ESP would create a WiFi hotspot even though it was not configured to do so. That should be fixed now.
- You can now also have conditional actions. See :ref:`if_action`.
- The esphomeyaml dashboard and HassIO add-on now can be configured with a password.
- The esphomeyaml dashboard and Hass.io add-on now can be configured with a password.
- Fixed YAML anchors not working (you can now prefix keys with ``.`` to make esphomeyaml ignore them)
- Made Dallas and DHT temperature sensor a bit more reliable by making the code a bit more efficient and thus resolving some timing issues.
- A ``heartbeat`` filter has been added to :ref:`binary sensors <binary_sensor-filters>`.

View File

@ -0,0 +1,74 @@
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` 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
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomBinarySensor : public PollingComponent, public binary_sensor::BinarySensor {
public:
// constructor
MyCustomBinarySensor() : PollingComponent(15000) {}
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
bool state = digitalRead(5)
publish_state(state);
}
};
(Store this file in your configuration directory, for example ``my_binary_sensor.h``)
And in YAML:
.. code-block:: yaml
# Example configuration entry
esphomeyaml:
includes:
- my_binary_sensor.h
binary_sensor:
- platform: custom
lambda: |-
auto my_custom_sensor = new MyCustomBinarySensor();
App.register_component(my_custom_sensor);
return {my_custom_sensor};
binary_sensors:
name: "My Custom Binary Sensor"
Configuration variables:
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
binary sensor(s).
- **binary_sensors** (**Required**, list): A list of binary sensors to initialize. The length here
must equal the number of items in the ``return`` statement of the ``lambda``.
- All options from :ref:`Binary Sensor <config-binary_sensor>` and :ref:`MQTT Component <config-mqtt-component>`.
See :cpp:class:`binary_sensor::BinarySensor`
See Also
--------
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/components/binary_sensor/custom.rst>`__
.. disqus::

View File

@ -260,6 +260,24 @@ presses.
then:
- logger.log: "Single Short Clicked"
.. _binary_sensor-is_on_off_condition:
``binary_sensor.is_on`` / ``binary_sensor.is_off Condition
**********************************************************
This :ref:`condition <config-condition>` passes if the given binary sensor is on/off.
.. code-block:: yaml
# in a trigger:
on_...:
if:
condition:
binary_sensor.is_on: my_binary_sensor
# same goes for is_off
then:
- script.execute: my_script
lambda calls
************

View File

@ -165,7 +165,7 @@ Configuration variables:
.. note::
To use fonts you will need to have the python ``pillow`` package installed, as esphomeyaml uses that package
to translate the truetype files into an internal format. If you're running this as a HassIO add-on or with
to translate the truetype files into an internal format. If you're running this as a Hass.io add-on or with
the official esphomeyaml docker image, it should already be installed. Otherwise you need to install it using
``pip2 install pillow``.
@ -334,7 +334,7 @@ Configuration variables:
.. note::
To use images you will need to have the python ``pillow`` package installed.
If you're running this as a HassIO add-on or with the official esphomeyaml docker image, it should already be
If you're running this as a Hass.io add-on or with the official esphomeyaml docker image, it should already be
installed. Otherwise you need to install it using ``pip2 install pillow``.
And then later in code:

View File

@ -44,6 +44,11 @@ Advanced options:
but you can customize this behavior using this option.
- **use_custom_code** (*Optional*, boolean): Whether to configure the project for writing custom components.
This sets up some flags so that custom code should compile correctly
- **includes** (*Optional*, list of files): A list of files to include in the main (auto-generated) sketch file
for custom components. The paths in this list are relative to the directory where the YAML configuration file
is in.
- **libraries** (*Optional*, list of libraries): A list of `platformio libraries <https://platformio.org/lib>`__
to include in the project. See `platformio lib install <https://docs.platformio.org/en/latest/userguide/lib/cmd_install.html>`__.
Automations:

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

@ -74,20 +74,6 @@ To measure the VCC voltage, set ``pin:`` to ``VCC`` and make sure nothing is con
pin: VCC
name: "VCC Voltage"
Next, you need to add a line at the top of your C++ project source code. Unfortunately, esphomelib can't do this
automatically for you because of how the compiler is linking the esphomelib library. Open up the
``<NODE_NAME>/src/main.cpp`` file and insert the ``ADC_MODE`` line like this:
.. code:: cpp
using namespace esphomelib;
// Enable measuring VCC
ADC_MODE(ADC_VCC);
void setup() {
// ...
See Also
--------

View File

@ -34,38 +34,35 @@ If you have any problems, I'm here to help: https://discord.gg/KhAMKrd
Step 1: Custom Sensor Definition
--------------------------------
At this point, you might have a main source file like this:
To create your own custom sensor, you just have to create your own C++ class. If you've never heard of that
before, don't worry, at the end of this guide you can just copy the example source code and modify it to your needs
- learning the intricacies of C++ classes won't be required.
Before you can create your own custom sensors, let's first take a look at the basics: How sensors (and components)
are structured in the esphomelib ecosystem.
In esphomelib, a **sensor** is some hardware device (like a BMP180) that periodically
sends out numbers, for example a temperature sensor that periodically publishes its temperature **state**.
Another important abstraction in esphomelib is the concept of a **component**. In esphomelib,
a **component** is an object with a *lifecycle* managed by the :cpp:class:`Application` class.
What does this mean? Well if you've coded in Arduino before you might know the two special methods
``setup()`` and ``loop()``. ``setup()`` is called one time when the node boots up and ``loop()`` is called
very often and this is where you can do things like read out sensors etc.
Components have something similar to that: They also have ``setup()`` and ``loop()`` methods which will be
called by the application kind of like the arduino functions.
So, let's now take a look at some code: This is an example of a custom component class (called ``MyCustomSensor`` here):
.. code-block:: cpp
// ...
using namespace esphomelib;
void setup() {
// ===== DO NOT EDIT ANYTHING BELOW THIS LINE =====
// ========== AUTO GENERATED CODE BEGIN ===========
App.set_name("livingroom");
App.init_log();
// ...
// =========== AUTO GENERATED CODE END ============
// ========= YOU CAN EDIT AFTER THIS LINE =========
App.setup();
}
void loop() {
App.loop();
}
To create your own custom sensor, you just have define a C++ class that extends ``Component`` and ``Sensor`` like this:
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
class CustomSensor : public Component, public sensor::Sensor {
class MyCustomSensor : public Component, public sensor::Sensor {
public:
CustomSensor(const std::string &name) : Sensor(name) {}
void setup() override {
// This will be called by App.setup()
}
@ -74,262 +71,240 @@ To create your own custom sensor, you just have define a C++ class that extends
}
};
void setup() {
// ...
In the first two lines, we're importing esphomelib so you can use the APIs and telling the compiler that
we want to use the esphomelib "namespace" (you don't need to know what this is now, it's basically just
there to have a clean, well-structured codebase).
Additionally, you need to change an internal flag that changes how esphomeyaml compiles files.
The only downside is that this will make build times *a tiny bit* slower:
.. code-block:: yaml
esphomeyaml:
# ...
use_custom_code: True
You've just created your first esphomelib sensor 🎉. It doesn't do very much right now and is never registered,
but it's a first step.
Let's now take a look at how a sensor works in esphomelib: A sensor is some hardware device (like a BMP180)
that sends out new values like temperatures.
Like any Component in esphomelib, if it's registered in the Application, ``setup()`` will be called for you when
``App.setup()`` is run. ``setup()`` is also the place where you should do hardware initialization like setting
``pinMode()``. Next, every time ``App.loop()`` is called, your component will also receive a ``loop()`` call.
This is the place where you should do stuff like querying a sensor for a new value like you might be used
to do in an Arduino sketch.
Let's now also take a closer look at this line, which you might not be too used to when writing pure C code:
Let's now also take a closer look at this line, which you might not be too used to when writing Arduino code:
.. code-block:: cpp
class CustomSensor : public Component, public sensor::Sensor {
class MyCustomSensor : public Component, public sensor::Sensor {
What this line is essentially saying is that we're defining our own class that's called ``CustomSensor``
which is also a subclass of ``Component`` and ``Sensor`` (in the namespace ``sensor::``).
``Component`` is there so that we can register it in our application and so that we will receive ``setup()``
and ``loop()`` calls. We're also inheriting from the ``Sensor`` class so that our custom sensor can send sensor
values to the frontend (like MQTT).
What this line is essentially saying is that we're defining our own class that's called ``MyCustomSensor``
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.
As most sensors really just setup some pins and then check the sensor every x seconds,
there's another abstraction that we'll use to simplify our code: ``PollingSensorComponent``.
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
the latest values.
However, there's a small problem with that approach: ``loop()`` gets called very often (about 60 times per second).
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 :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
class CustomSensor : public sensor::PollingSensorComponent {
class MyCustomSensor : public PollingComponent, public sensor::Sensor {
public:
CustomSensor(const std::string &name, uint32_t update_interval)
: sensor::PollingSensorComponent(name, update_interval) {}
// constructor
MyCustomSensor() : PollingComponent(15000) {}
void setup() override {
// This will be called by App.setup()
}
void update() override {
// This will be called every `update_interval` milliseconds.
// This will be called every "update_interval" milliseconds.
}
};
What ``PollingSensorComponent`` (and ``PollingComponent``) does is essentially
just replace the ``loop()`` method and will call ``update()`` instead every ``update_interval`` milliseconds.
Because with most sensors, you really don't need to get the latest values with every single ``loop()``
call (which can be called many times per second). If we forward the ``update_interval`` in our *constructor*
(line 3), ``PollingSensorComponent`` will call ``update()`` for us every ``update_interval``
milliseconds, so that we don't have to do time checking ourselves.
You don't really need to know about C++ constructors for now, but I would definitely recommend reading up on them
in the Internet.
Let's also now make our sensor actually *output* values (42 for now):
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 :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:
.. code-block:: cpp
// class CustomSensor ...
// class MyCustomSensor ...
// ... previous code
void update() override {
publish_state(42.0); // 42°C
publish_state(42.0);
}
std::string unit_of_measurement() override { return "°C"; }
int8_t accuracy_decimals() override { return 2; } // 2 decimal places of accuracy.
};
Every time ``update`` is called we will now **push** a new value to the frontend.
The front-end will then relay those values to MQTT and finally to Home Assistant.
Additionally, we created a function that tells the sensor what unit of measurement the
value is in, this is not strictly required and only used for a nice output in Home Assistant.
Every time ``update`` is called we will now **publish** a new value to the frontend.
The rest of esphomelib will then take care of processing this value and ultimately publishing it
to the outside world (for example using MQTT).
Step 2: Registering the custom sensor
-------------------------------------
Now we have our Custom Sensor set up, but unfortunately it doesn't do much right now.
Actually ... it does nothing because it's never registered in the App,
so esphomelib can't know about it. Let's change that.
Actually ... it does nothing because it's never included nor instantiated.
First, create a new file called ``my_custom_sensor.h`` in your configuration directory and copy the source code
from above into that file.
In your global ``setup()`` method, after you've setup all other components, do the following:
Then in the YAML config, *include* that file in the top-level ``esphomeyaml`` section like this:
.. code-block:: yaml
.. code:: cpp
esphomeyaml:
# ... [Other options]
includes:
- my_custom_sensor.h
void setup() {
// ...
// =========== AUTO GENERATED CODE END ============
// ========= YOU CAN EDIT AFTER THIS LINE =========
Next, create a new ``custom`` sensor platform entry like this:
auto *custom_sensor = new CustomSensor("My Custom Sensor", 5000); // update every 5000ms or every 5 seconds.
App.register_component(custom_sensor);
App.register_sensor(custom_sensor);
.. code-block:: yaml
App.setup();
}
# Example configuration entry
sensor:
- platform: custom
lambda: |-
auto my_sensor = new MyCustomSensor();
App.register_component(my_sensor);
return {my_sensor};
sensors:
name: "My Custom Sensor"
Let's break this down:
- First, we specify a :ref:`lambda <config-lambda>` that will be used to **instantiate** our sensor class. This will
be called on boot to register our sensor in esphomelib.
- In this lambda, we're first creating a new instance of our custom class (``new MyCustomSensor()``) and then
assigning it to a variable called ``my_sensor``. Note: This uses a feature in the C++ standard, ``auto``, to make our
lives easier. We could also have written ``MyCustomSensor *my_sensor = new MyCustomSensor()``
- Next, as our custom class inherits from Component, we need to **register** it - otherwise esphomelib will not know
about it and won't call our ``setup()`` and ``update`` methods!
- Finally, we ``return`` the custom sensor - don't worry about the curly braces ``{}``, we'll cover that later.
- After that, we just let *esphomeyaml* know about our newly created sensor too using the ``sensors:`` block. Additionally,
here we're also assigning the sensor a name.
Now all that's left to do is upload the code and let it run :)
If you have Home Assistant MQTT discovery setup, it will even automatically show up in the frontend 🎉
(with the entity id ``sensor.custom_sensor_example``)
.. figure:: images/custom-ui.png
:align: center
:width: 60%
Let's go through the code for registering our custom sensor. First, we're creating a new CustomSensor
instance with the update interval of 5000ms using the ``new`` C++ syntax (important!) and assigning it to a
variable ``custom_sensor`` (using C++11 ``auto`` type specifier to make it simpler).
.. code-block:: cpp
auto *custom_sensor = new CustomSensor(5000);
Next, we *register* the component in esphomelib's Application instance so that it can call the component's
``setup()`` and ``loop()``.
.. code-block:: cpp
App.register_component(custom_sensor);
// you could also write this, it's a bit shorter and works the same way.
// auto *custom_sensor = App.register_component(new CustomSensor(5000));
App.register_sensor(custom_sensor);
Lastly, we're registering the *sensor* with ``register_sensor``, this will automatically set up a
bunch of callbacks so that it can publish state changes to MQTT when you call ``publish_new_value()``,
create automatic MQTT discovery messages and setup a moving average over the sensor values
(adjust these as you would with any other sensor).
Step 3: BMP180 support
----------------------
Let's finally make this custom sensor useful by adding the BMP180 aspect into it! A great feature of
esphomelib is that you can just use all existing arduino libraries, amazing right? Now for this example we'll
Let's finally make this custom sensor useful by adding the BMP180 aspect into it! Sure, printing ``42`` is a nice number
but it won't help with home automation :D
A great feature of esphomelib is that you don't need to code everything yourself. You can use any existing arduino
library to do the work for you! Now for this example we'll
use the `Adafruit BMP085 Library <https://platformio.org/lib/show/525/Adafruit%20BMP085%20Library>`__
library by Adafruit.
library to implement support for the BMP085 sensor. But you can find other libraries too on the
`platformio library index <https://platformio.org/lib>`__
First we'll need to add the library to our platformio dependencies. To do so, put the following in
the ``common`` section of your ``platformio.ini``:
First we'll need to add the library to our project dependencies. To do so, put ``Adafruit BMP085 Library``
in your global ``libraries``:
.. code-block:: ini
.. code-block:: yaml
[common]
lib_deps = Adafruit BMP085 Library
build_flags =
upload_flags =
esphomeyaml:
includes:
- my_custom_sensor.h
libraries:
- "Adafruit BMP085 Library"
Next, include the library at the top of you main sketch file (``<NODE_NAME>/src/main.cpp``):
Next, include the library at the top of your custom sensor file you created previously:
.. code-block:: cpp
#include "esphomelib/application.h"
#include <Adafruit_BMP085.h>
#include "esphomelib.h"
#include "Adafruit_BMP085.h"
using namespace esphomelib;
// ...
Then update our sensor for BMP180 support:
Then update the sensor for BMP180 support:
.. code-block:: cpp
// ...
class BMP180Sensor : public sensor::PollingSensorComponent {
class MyCustomSensor : public PollingComponent, public sensor::Sensor {
public:
Adafruit_BMP085 bmp;
BMP180Sensor(const std::string &name, uint32_t update_interval)
: sensor::PollingSensorComponent(name, update_interval) {
}
MyCustomSensor() : PollingComponent(15000) { }
void setup() override {
bmp.begin();
}
void update() override {
int pressure = bmp.readPressure(); // in Pa, or 1/100 hPa
int pressure = bmp.readPressure(); // library returns value in in Pa, which equals 1/100 hPa
publish_state(pressure / 100.0); // convert to hPa
}
std::string unit_of_measurement() override { return "hPa"; }
int8_t accuracy_decimals() override { return 2; } // 2 decimal places of accuracy.
};
void setup() {
// ...
auto *custom_sensor = new BMP180Sensor("My BMP180 sensor", 5000);
App.register_component(custom_sensor);
App.register_sensor(custom_sensor);
App.setup();
}
// ...
There's not too much going on there. First, we define the variable ``bmp`` of type ``Adafruit_BMP085``
inside our class as a class member. In ``setup()`` we initialize the library and in ``update()`` we read the
pressure and send it out to MQTT.
inside our class as a class member. This is the object the adafruit library exposes and through which
we will communicate with the sensor.
In our custom ``setup()`` function we're *initializing* the library (using ``.begin()``) and in
``update()`` we're reading the pressure and publishing it using ``publish_state``.
For esphomeyaml we can use the previous YAML. So now if you upload the firmware, you'll see the sensor
reporting actual pressure values! Hooray 🎉!
Step 4: Additional Overrides
----------------------------
There's a slight problem with our code: It does print the values fine, **but** if you look in Home Assistant
you'll see a) the value has no **unit** attached to it and b) the value will be rounded to the next integer.
This is because esphomelib doesn't know these infos, it's only passed a floating point value after all.
We *could* fix that in our custom sensor class (by overriding the ``unit_of_measurement`` and ``accuracy_decimals``
methods), but here we have the full power of esphomeyaml, so let's use that:
.. code-block:: yaml
# Example configuration entry
sensor:
- platform: custom
lambda: |-
auto my_sensor = new MyCustomSensor();
App.register_component(my_sensor);
return {my_sensor};
sensors:
name: "My Custom Sensor"
unit_of_measurement: hPa
accuracy_decimals: 2
You've now successfully created your first custom sensor component 🎉 Happy coding!
Bonus: Sensors With Multiple Output Values
------------------------------------------
The ``PollingSensorComponent`` doesn't fit every use-case. Sometimes, (as with the BMP180),
The ``Sensor`` class doesn't fit every use-case. Sometimes, (as with the BMP180),
a sensor can expose multiple values (temperature *and* pressure, for example).
Doing so in esphomelib is a bit more difficult. Basically, we will have to change our sensor
model to have *one component* that reads out the values and *one sensor class* for each value
we want to expose.
model to have a **component** that reads out the values and then multiple **sensors** that represent
the individual sensor measurements.
Let's look at what that could look like in code:
.. code-block:: cpp
// An empty sensor subclass that will "proxy" the temperature values
class BMP280TemperatureSensor : public sensor::Sensor {
public:
BMP280TemperatureSensor(const std::string &name) : sensor::Sensor(name) {}
std::string unit_of_measurement() override { return "°C"; }
int8_t accuracy_decimals() override { return 1; }
};
// An empty sensor subclass that will "proxy" the pressure values
class BMP280PressureSensor : public sensor::Sensor {
public:
BMP280PressureSensor(const std::string &name) : sensor::Sensor(name) {}
std::string unit_of_measurement() override { return "hPa"; }
int8_t accuracy_decimals() override { return 2; }
};
class BMP180Component : public PollingComponent {
class MyCustomSensor : public PollingComponent {
public:
Adafruit_BMP085 bmp;
BMP280TemperatureSensor *temperature_sensor;
BMP280PressureSensor *pressure_sensor;
sensor::Sensor *temperature_sensor = new sensor::Sensor();
sensor::Sensor *pressure_sensor = new sensor::Sensor();
BMP180Component(const std::string &temperature_name, const std::string &pressure_name, uint32_t update_interval)
: PollingComponent(update_interval) {
this->temperature_sensor = new BMP280TemperatureSensor(temperature_name);
this->pressure_sensor = new BMP280PressureSensor(pressure_name);
}
MyCustomSensor() : PollingComponent(15000) { }
void setup() override {
bmp.begin();
@ -337,48 +312,64 @@ Let's look at what that could look like in code:
void update() override {
// This is the actual sensor reading logic.
int pressure = bmp.readPressure();
pressure_sensor->publish_state(pressure / 100.0);
float temperature = bmp.readTemperature();
temperature_sensor->publish_state(temperature);
int pressure = bmp.readPressure();
pressure_sensor->publish_state(pressure / 100.0);
}
};
void setup() {
// ...
The code here has changed a bit:
auto *custom_bmp180 = new BMP180Component("BMP180 Temperature", "BMP180 Pressure", 5000);
// The BMP180Component is a *component*, so it needs to be registered.
App.register_component(custom_bmp180);
- Because the values are no longer published by our custom class, ``MyCustomSensor`` no longer inherits
from ``Sensor``.
- The class has two new members: ``temperature_sensor`` and ``pressure_sensor``. These will be used to
publish the values.
- In our ``update()`` method we're now reading out the temperature *and* pressure. These values are then
published with the temperature and pressure sensor instances we declared before.
// But the temperature&pressure classes are *sensors*, so each of them needs to be registered
App.register_sensor(custom_bmp180->temperature_sensor);
App.register_sensor(custom_bmp180->pressure_sensor);
App.setup();
}
Our YAML configuration needs an update too:
That's a lot of code :P Basically, what it boils down to is you have one central component ``BMP180Component``
which handles the communication with the BMP180 and a ``Sensor`` subclass for each value you want to expose.
.. code-block:: yaml
Most of the magic happens inside the ``update()`` function. Here, the values are read from the BMP180 and are
sent to esphomelib via the pressure/temperature sensor proxies we set up in the constructor.
# Example configuration entry
sensor:
- platform: custom
lambda: |-
auto my_sensor = new MyCustomSensor();
App.register_component(my_sensor);
return {my_sensor->temperature_sensor, my_sensor->pressure_sensor};
The only other thing you need to change is the registering inside ``setup()``.
Because ``BMP180Component`` is a *component* (because it has a lifecycle through the ``setup()`` and ``loop()`` methods),
it needs to be registered with ``App.register_component(...)``. However, as it's now not a subclass
of ``Sensor`` anymore, it cannot be registered as a sensor.
sensors:
- name: "My Custom Temperature Sensor"
unit_of_measurement: °C
accuracy_decimals: 1
- name: "My Custom Pressure Sensor"
unit_of_measurement: hPa
accuracy_decimals: 2
But because the ``BMP280TemperatureSensor`` and ``BMP280PressureSensor`` *are* subclasses of sensors,
they do need to be registered so that esphomelib can do all the magic stuff like setting up MQTT discovery
for them. That's why we call ``App.register_sensor`` for each sensor we created in the end.
In ``lambda`` the return statement has changed: Because we have *two* sensors now we must tell esphomeyaml
about both of them. We do this by returning them as an array of values in the curly braces.
``sensors:`` has also changed a bit: Now that we have multiple sensors, each of them needs an entry here.
Note that the number of arguments you put in the curly braces *must* match the number of sensors you define in the YAML
``sensors:`` block - *and* they must be in the same order.
Configuration variables:
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
sensor(s).
- **sensors** (**Required**, list): A list of sensors to initialize. The length here
must equal the number of items in the ``return`` statement of the ``lambda``.
- All options from :ref:`Sensor <config-sensor>` and :ref:`MQTT Component <config-mqtt-component>`.
See Also
--------
- `Full source code <https://github.com/OttoWinter/esphomelib/blob/master/examples/custom-bmp180-sensor/custom-bmp180-sensor.cpp>`__
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/components/sensor/custom.rst>`__
.. disqus::

View File

@ -289,6 +289,33 @@ with ``x``.
Configuration variables: See :ref:`Automation <automation>`.
.. _sensor-in_range_condition:
``sensor.in_range`` Condition
*****************************
This condition passes if the state of the given sensor is inside a range.
Define the range with ``above`` and ``below``. If only one of them is defined, the interval is half-open.
So for example ``above: 5`` with no below would mean the range from 5 to positive infinity.
.. code-block:: yaml
# in a trigger:
on_...:
if:
condition:
sensor.in_range:
id: my_sensor
above: 50.0
then:
- script.execute: my_script
Configuration variables:
- **above** (*Optional*, float): The minimum for the condition.
- **below** (*Optional*, float): The maximum for the condition.
lambda calls
************

View File

@ -0,0 +1,15 @@
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomSensor : public PollingComponent, public sensor::Sensor {
public:
MyCustomSensor() : PollingComponent(15000) {}
void setup() override {
// This will be called by App.setup()
}
void update() override {
publish_state(42.0);
}
};

View File

@ -47,7 +47,7 @@ Converting from W to kW
Some sensors such as the :doc:`HLW8012 <hlw8012>` expose their power sensor with a unit of measurement of
``W``. To have your readings in ``kW``, use a filter:
.. code::
.. code-block:: yaml
sensor:
# The power sensor to convert, can be any power sensor

View File

@ -46,13 +46,6 @@ Configuration variables:
- **deceleration** (*Optional*, float): The same as ``acceleration``, but for when the motor is decelerating
shortly before reaching the set position. Defaults to ``inf`` (immediate deceleration).
.. note::
Esphomelib's core loop only runs 60 times per second by default to conserve power. But this also means it's limited
to 60 steps per second. To have higher step rater, you have to open up the ``<NODE_NAME>/src/main.cpp`` file,
scroll down to the ``void loop()`` section and remove the ``delay(16);`` line.
.. note::
If the stepper is driving in the wrong direction, you can invert the ``dir_pin``:

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

@ -106,6 +106,24 @@ advanced stuff (see the full :doc:`API Reference </api/cover/index>` for more in
// Toggle the switch
id(my_switch).write_state(!id(my_switch).state);
.. _switch-is_on_off_condition:
``switch.is_on`` / ``switch.is_off Condition
********************************************
This :ref:`condition <config-condition>` passes if the given switch is on/off.
.. code-block:: yaml
# in a trigger:
on_...:
if:
condition:
switch.is_on: my_switch
# same goes for is_off
then:
- script.execute: my_script
See Also
--------

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::

View File

@ -87,9 +87,8 @@ See Also
.. toctree::
:maxdepth: 1
:glob:
version
mqtt_subscribe
template
*
.. disqus::

View File

@ -36,7 +36,7 @@ Configuration variables:
.. note::
To use the automatic timezone detection you will need to have the python ``tzlocal`` package installed.
If you're running this as a HassIO add-on or with the official esphomeyaml docker image, it should already
If you're running this as a Hass.io add-on or with the official esphomeyaml docker image, it should already
be installed. Otherwise you need to install it using ``pip2 install tzlocal``.
Use In Lambdas

View File

@ -0,0 +1,110 @@
Generic Custom Component
========================
This integration can be used to create generic custom components in esphomelib
using the C++ (Arduino) API. This integration should be used in cases where
none of esphomelib's abstraction layers (for example the "sensor", "binary sensor",
"switch", etc concepts) work well for your integration.
Please first read :doc:`/esphomeyaml/components/sensor/custom` guide, the same principles apply here.
The example below is an example of a custom component that can do anything you want really.
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomComponent : public Component {
public:
void setup() override {
// This will be called once to set up the component
// think of it as the setup() call in Arduino
pinMode(5, INPUT);
pinMode(6, OUTPUT);
}
void loop() override {
// This will be called very often after setup time.
// think of it as the loop() call in Arduino
if (digitalRead(5)) {
digitalWrite(6, HIGH);
// You can also log messages
ESP_LOGD("custom", "The GPIO pin 5 is HIGH!");
}
}
};
In many cases however components should communicate with other appliances using the network.
That's why there is :cpp:class:`mqtt::CustomMQTTDevice`. It is a helper class to create
custom components that communicate using MQTT.
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomComponent : public Component, public mqtt::CustomMQTTDevice {
public:
void setup() override {
// This will be called once to set up the component
// think of it as the setup() call in Arduino
pinMode(6, OUTPUT);
subscribe("the/topic", &MyCustomComponent::on_message);
// also supports JSON messages
subscribe_json("the/json/topic", &MyCustomComponent::on_json_message);
}
void on_message(const std::string &payload) {
if (payload == "ON") {
digitalWrite(6, HIGH);
publish("the/other/topic", "Hello World!");
} else {
digitalWrite(6, LOW);
publish("the/other/topic", 42);
}
}
void on_json_message(JsonObject &root) {
if (!root.containsKey("key"))
return;
int value = root["key"];
// do something with Json Object
// publish JSON using lambda syntax
publish_json("the/other/json/topic", [=](JsonObject &root2) {
root2["key"] = "Hello World";
});
}
};
(Store this file in your configuration directory, for example ``my_custom_component.h``)
And in YAML:
.. code-block:: yaml
# Example configuration entry
esphomeyaml:
includes:
- my_custom_component.h
custom_component:
- lambda: |-
auto my_custom = new MyCustomComponent();
return {my_custom};
Configuration variables:
- **lambda** (**Required**, :ref:`lambda <config-lambda>`): The lambda to run for instantiating the
binary sensor(s).
See :cpp:class:`Component` and :cpp:class:`mqtt::CustomMQTTDevice`.
See Also
--------
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/custom/custom_component.rst>`__
.. disqus::

View File

@ -0,0 +1,38 @@
Custom I²C Device
=================
Lots of devices communicate using the i2c protocol. If you want to integrate
a device into esphomelib that uses this protocol you can pretty much use almost
all Arduino-based code because the ``Wire`` library is also available in esphomelib.
See the other custom component guides for how to register components and make
them publish values.
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomComponent : public Component {
public:
void setup() override {
// Initialize the device here. Usually Wire.begin() will be called in here,
// though that call is unnecessary if you have an 'i2c:' entry in your config
Wire.begin();
}
void loop() override {
// Example: write the value 0x42 to register 0x78 of device with address 0x21
Wire.beginTransmission(0x21);
Wire.write(0x78);
Wire.write(0x42);
Wire.endTransmission();
}
};
See Also
--------
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/custom/i2c.rst>`__
.. disqus::

View File

@ -0,0 +1,7 @@
Custom
======
.. toctree::
:glob:
*

View File

@ -0,0 +1,39 @@
Custom SPI Device
=================
Lots of devices communicate using the SPI protocol. If you want to integrate
a device into esphomelib that uses this protocol you can pretty much use almost
all Arduino-based code because the ``SPI`` library is also available in esphomelib.
See the other custom component guides for how to register components and make
them publish values.
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomComponent : public Component {
public:
void setup() override {
SPI.pins(SCK_PIN, MISO_PIN, MOSI_PIN);
SPI.begin();
pinMode(CS_PIN, OUTPUT);
}
void loop() override {
digitalWrite(CS_PIN, LOW);
SPI.beginTransaction(...);
SPI.write(0x42);
digitalWrite(CS_PIN, HIGH);
}
};
See Also
--------
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/custom/spi.rst>`__
.. disqus::

View File

@ -0,0 +1,59 @@
Custom UART Device
==================
Lots of devices communicate using the UART protocol. If you want to integrate
a device into esphomelib that uses this protocol you can pretty much use almost
all Arduino-based code because esphomelib has a nice abstraction over the UART bus.
See the other custom component guides for how to register components and make
them publish values.
.. code-block:: cpp
#include "esphomelib.h"
using namespace esphomelib;
class MyCustomComponent : public Component, public UARTDevice {
public:
MyCustomComponent(UARTComponent *parent) : UARTDevice(parent) {}
void setup() override {
// nothing to do here
}
void loop() override {
// Use Arduino API to read data, for example
String line = readString();
int i = parseInt();
while (available()) {
char c = read();
}
// etc
}
};
And in YAML:
.. code-block:: yaml
# Example configuration entry
esphomeyaml:
includes:
- my_custom_component.h
uart:
id: uart_bus
tx_pin: D0
rx_pin: D1
baud_rate: 9600
custom_component:
- lambda: |-
auto my_custom = new MyCustomComponent(id(uart_bus));
return {my_custom};
See Also
--------
- `Edit this page on GitHub <https://github.com/OttoWinter/esphomedocs/blob/current/esphomeyaml/custom/uart.rst>`__
.. disqus::

View File

@ -47,7 +47,7 @@ For this guide you will need:
- An USB to UART Bridge for flashing the device. These can be bought on Amazon for less than 5 dollars.
Note that the bridge *must* be 3.3V compatible. Otherwise you will destroy your Sonoff.
- Jumper wires to connect the UART bridge to the header pins.
- Computer running esphomeyaml or HassIO add-on.
- Computer running esphomeyaml or Hass.io add-on.
- Screwdriver to open up the Sonoff 4CH.
Have everything? Great! Then you can start.

View File

@ -46,7 +46,7 @@ For this guide you will need:
- Sonoff S20 😉
- An USB to UART Bridge for flashing the device. These can be bought on Amazon for less than 5 dollars.
Note that the bridge *must* be 3.3V compatible. Otherwise you will destroy your S20.
- Computer running esphomeyaml HassIO add-on.
- Computer running esphomeyaml Hass.io add-on.
- Screwdriver to open up the S20.
- Soldering iron and a few header pins to connect the UART interface.

View File

@ -333,8 +333,10 @@ All Actions
- :ref:`delay <delay_action>`
- :ref:`lambda <lambda_action>`
- :ref:`if <if_action>`
- :ref:`while <while_action>`
- :ref:`component.update <component-update_action>`
- :ref:`script.execute <script-execute_action>`
- :ref:`script.stop <script-stop_action>`
- :ref:`logger.log <logger-log_action>`
- :ref:`mqtt.publish <mqtt-publish_action>`
- :ref:`mqtt.publish_json <mqtt-publish_json_action>`
@ -356,6 +358,18 @@ All Actions
- :ref:`deep_sleep.enter <deep_sleep-enter_action>`
- :ref:`deep_sleep.prevent <deep_sleep-prevent_action>`
.. _config-condition:
All Conditions
--------------
- :ref:`and <and_condition>`
- :ref:`or <or_condition>`
- :ref:`lambda <lambda_condition>`
- :ref:`binary_sensor.is_on / binary_sensor.is_off <binary_sensor-is_on_off_condition>`
- :ref:`switch.is_on / switch.is_off <switch-is_on_off_condition>`
- :ref:`sensor.in_range <sensor-in_range_condition>`
.. _delay_action:
``delay`` Action
@ -424,12 +438,47 @@ turns on a light for 5 seconds. Otherwise, the light is turned off immediately.
Configuration options:
- **if** (**Required**): The condition to check which branch to take.
- **if** (**Required**, :ref:`config-condition`): The condition to check which branch to take.
- **then** (*Optional*, :ref:`config-action`): The action to perform if the condition evaluates to true.
Defaults to doing nothing.
- **else** (*Optional*, :ref:`config-action`): The action to perform if the condition evaluates to false.
Defaults to doing nothing.
.. _while_action:
``while`` Action
----------------
This actions repeats a sequence of actions until a condition is no longer met.
For example, below you can see a configuration that will blink an LED as long as a template
switch is on.
.. code-block:: yaml
switch:
- platform: gpio
pin: D1
id: blinking_pin
- platform: template
name: Blink LED
id: blink
optimistic: true
turn_on_action:
- while:
condition:
switch.is_on: blink
then:
- switch.turn_on: blinking_pin
- delay: 500ms
- switch.turn_off: blinking_pin
- delay: 500ms
Configuration options:
- **if** (**Required**, :ref:`config-condition`): The condition to check whether to continue evaluation.
- **then** (**Optional**, :ref:`config-action`): The action to perform if the condition evaluates to true.
.. _component-update_action:
@ -477,6 +526,89 @@ execute the script with a single call.
then:
- script.execute: my_script
.. _script-stop_action:
``script.stop`` Action
----------------------
This action allows you to stop a given script during execution. Please note this is only
useful right now if your script contains a ``delay`` action.
.. code-block:: yaml
# Example configuration entry
script:
- id: my_script
then:
- switch.turn_on: my_switch
- delay: 1s
- switch.turn_off: my_switch
# in a trigger:
on_...:
then:
- script.stop: my_script
.. _and_condition:
``and`` Condition
-----------------
This condition passes if and only if all of the conditions pass.
.. code-block:: yaml
# in a trigger:
on_...:
if:
condition:
and:
- condition_a:
- condition_b:
then:
- script.execute: my_script
.. _or_condition:
``or`` Condition
----------------
This condition passes if at least one condition passes.
.. code-block:: yaml
# in a trigger:
on_...:
if:
condition:
or:
- condition_a:
- condition_b:
then:
- script.execute: my_script
.. _lambda_condition:
``lambda`` Condition
--------------------
This condition passes if the given :ref:`lambda <config-lambda>` returns ``true``.
.. code-block:: yaml
# in a trigger:
on_...:
if:
condition:
lambda: |-
if (id(my_sensor).value > 30.0) {
return true;
} else {
return false;
}
then:
- script.execute: my_script
See Also
--------

View File

@ -141,6 +141,34 @@ There are several ways of doing this. See below examples to see how you can spec
update_interval: never # never update
update_interval: 0ms # update in every loop() iteration
.. _config-substitutions:
Substitutions
-------------
If you're using many ESPs in your home and have many similar configuration files, it can
be cumbersome to keep all files up to date. There are already some ways to minimize
repeating yourself in the configuration using the ``!include`` and ``!secret`` YAML
directives.
If you want to go one step further and reduce duplication even further, you can use
``substitutions`` in esphomeyaml's config. Substitutions allow you define top-level
variables which are then replaced everywhere in your configuration which are then
substituted with their value using the bash-style ``${}`` syntax.
.. code-block:: yaml
substitutions:
devicename: livingroom
esphomeyaml:
name: $devicename
# ...
switch:
- platform: ...
name: ${devicename} switch
See Also
--------

View File

@ -372,13 +372,13 @@ it in the configuration. Specifically, it may contain these fields:
- ``DEPENDENCIES``: Other components that are required to be in the user's configuration if this platform/component
is loaded:
.. code::
.. code-block:: python
DEPENDENCIES = ['i2c']
- ``ESP_PLATFORMS``: Provide a whitelist of platforms this integration works on. Default is work on all platforms.
.. code::
.. code-block:: python
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]

View File

@ -12,6 +12,8 @@ Tips for using esphomeyaml
``!include``, ``!secret``. So you can store all your secret WiFi passwords and so on
in a file called ``secrets.yaml`` within the directory where the configuration file is.
For even more configuration templating, take a look at :ref:`config-substitutions`.
2. If you want to see how esphomeyaml interprets your configuration, run
.. code-block:: bash
@ -52,9 +54,10 @@ the ESP. This can sometimes fail (driver missing, inside docker container, ...).
Starting with esphomelib 1.9.0, the esphomelib suite provides
`esphomeflasher <https://github.com/OttoWinter/esphomeflasher>`__, a tool to flash ESPs over USB.
First, you need to get the firmware file to flash. For HassIO add-on based installs you can
use the ``COMPILE`` button and then press ``Download Binary``. For command line based installs you
can access the file under ``<CONFIG_DIR>/<NODE_NAME>/.pioenvs/<NODE_NAME>/firmware.bin``.
First, you need to get the firmware file to flash. For Hass.io add-on based installs you can
use the ``COMPILE`` button (click the overflow icon with the three dots) and then press
``Download Binary``. For command line based installs you can access the file under
``<CONFIG_DIR>/<NODE_NAME>/.pioenvs/<NODE_NAME>/firmware.bin``.
Then, install esphomeflasher by going to the `releases page <https://github.com/OttoWinter/esphomeflasher/releases>`__
and downloading one of the pre-compiled binaries. Open up the application and select the serial port
@ -144,7 +147,7 @@ It's simple. Run:
# From docker:
docker pull ottowinter/esphomeyaml:latest
And in HassIO, there's a simple UPDATE button when there's an update available as with all add-ons
And in Hass.io, there's a simple UPDATE button when there's an update available as with all add-ons
.. _faq-beta:
@ -165,7 +168,7 @@ by installing the esphomeyaml beta:
# In each command:
docker run [...] -it ottowinter/esphomeyaml:rc livingroom.yaml run
And for HassIO, you will see a "esphomeyaml Beta" Add-On for the beta channel.
And for Hass.io, you will see a "esphomeyaml Beta" Add-On for the beta channel.
The beta docs can be viewed at `https://beta.esphomelib.com <https://beta.esphomelib.com>`__
@ -179,7 +182,7 @@ Installing the latest bleeding edge version of esphomelib is also quite easy. It
if there was a bug somewhere and I didn't feel like building & pushing a whole new release out (this often
takes up to 2 hours!). To install the dev version of esphomeyaml:
- In HassIO: In the esphomeyaml add-on repository there's also a second add-on called ``esphomeyaml-edge``.
- In Hass.io: In the esphomeyaml add-on repository there's also a second add-on called ``esphomeyaml-edge``.
Install that and stop the stable version (both can't run at the same time without port collisions).
- From ``pip``: Run ``pip install git+git://github.com/OttoWinter/esphomeyaml.git``
- From docker: Run ``docker pull ottowinter/esphomeyaml:dev`` and use ``ottowinter/esphomeyaml:dev`` in all
@ -187,7 +190,7 @@ takes up to 2 hours!). To install the dev version of esphomeyaml:
Next, if you want to use the latest version of the esphomelib C++ framework too:
.. code::
.. code-block:: yaml
# Sample configuration entry
esphomeyaml:

View File

@ -23,7 +23,7 @@ Installing esphomeyaml is very easy. All you need to do is have `Python
Alternatively, theres also a docker image available for easy
installation (the docker hub image is only available for amd64 right now; if you have
an RPi, please install esphomelib through ``pip`` or use :doc:`the HassIO add-on <getting_started_hassio>`:
an RPi, please install esphomelib through ``pip`` or use :doc:`the Hass.io add-on <getting_started_hassio>`:
.. code-block:: bash
@ -172,7 +172,7 @@ Bonus: esphomeyaml dashboard
Starting with version 1.6.0, esphomeyaml features a dashboard that you can use to
easily manage your nodes from a nice web interface. It was primarily designed for
:doc:`the HassIO add-on <getting_started_hassio>`, but also works with a simple command.
:doc:`the Hass.io add-on <getting_started_hassio>`, but also works with a simple command.
To start the esphomeyaml dashboard, simply start esphomeyaml with the following command
(with ``config/`` pointing to a directory where you want to store your configurations)

View File

@ -1,13 +1,13 @@
Getting Started with esphomeyaml through HassIO
===============================================
Getting Started with esphomeyaml through Hass.io
================================================
.. seo::
:description: Getting Started guide for installing esphomeyaml as a HassIO Add-on and creating a basic configuration.
:description: Getting Started guide for installing esphomeyaml as a Hass.io Add-on and creating a basic configuration.
:image: home-assistant.png
esphomeyaml is the perfect solution for creating custom firmwares for
your ESP8266/ESP32 boards. In this guide well go through how to setup a
basic "node" by use of the HassIO add-on.
basic "node" by use of the Hass.io add-on.
But first, here's a very quick introduction of how esphomeyaml works:
esphomeyaml is a *tool* which reads in YAML configuration files (just like Home Assistant)
@ -19,7 +19,7 @@ Assistant's UI.
Installation
------------
Installing the esphomeyaml HassIO add-on is easy. Just navigate to the HassIO
Installing the esphomeyaml Hass.io add-on is easy. Just navigate to the Hass.io
panel in your Home Assistant frontend and add the esphomeyaml add-on repository:
https://github.com/OttoWinter/esphomeyaml
@ -57,7 +57,7 @@ there are three basic actions you can perform:
.. warning::
The HassIO Add-On is currently not capable of discovering new USB ports after the add-on
The Hass.io Add-On is currently not capable of discovering new USB ports after the add-on
has started due to some docker restrictions. Please go to the add-on details page
and restart the add-on if a new USB device is not automatically found.
@ -84,11 +84,11 @@ Now go ahead and use one of the :ref:`devices guides <devices>` to extend your c
intend to flash an esphomeyaml firmware onto. Then proceed with uploading the first firmware using the
upload button.
HassIO add-on options
*********************
Hass.io add-on options
**********************
Since version 1.8.0, you can optionally specify a password to use for all traffic to esphomeyaml
using the ``password`` option in the HassIO add-on page. By default, this is an empty string
using the ``password`` option in the Hass.io add-on page. By default, this is an empty string
(which means no password), but you can enter any string in there to set your password.

View File

@ -14,7 +14,7 @@ Getting Binary
First follow the guides for the :ref:`different supported devices <devices>` and create a configuration
file. Then, generate and download the binary:
- **Using the HassIO add-on/dashboard**: Just click the ``COMPILE`` button, wait for
- **Using the Hass.io add-on/dashboard**: Just click the ``COMPILE`` button, wait for
the compilation to end and press the ``DOWNLOAD BINARY`` button.
.. figure:: images/download_binary.png

View File

@ -14,7 +14,7 @@ Getting Binary
First follow the guides for the :ref:`different supported devices <devices>` and create a configuration
file. Then, generate and download the binary:
- **Using the HassIO add-on/dashboard**: Just click the ``COMPILE`` button, wait for
- **Using the Hass.io add-on/dashboard**: Just click the ``COMPILE`` button, wait for
the compilation to end and press the ``DOWNLOAD BINARY`` button.
.. figure:: images/download_binary.png

View File

@ -14,7 +14,7 @@ Getting Binary
First follow the guides for the :ref:`different supported devices <devices>` and create a configuration
file. Then, generate and download the binary:
- **Using the HassIO add-on/dashboard**: Just click the ``COMPILE`` button, wait for
- **Using the Hass.io add-on/dashboard**: Just click the ``COMPILE`` button, wait for
the compilation to end and press the ``DOWNLOAD BINARY`` button.
.. figure:: images/download_binary.png

View File

@ -21,7 +21,7 @@ Guides
.. imgtable::
Getting Started through Command Line, guides/getting_started_command_line, console.svg
Getting Started through HassIO Add-On, guides/getting_started_hassio, home-assistant.svg
Getting Started through Hass.io Add-On, guides/getting_started_hassio, home-assistant.svg
Configuration Types, guides/configuration-types, settings.svg
Migrating from Sonoff-Tasmota, guides/migrate_sonoff_tasmota, tasmota.svg
Migrating from ESPurna, guides/migrate_espurna, espurna.svg
@ -136,6 +136,7 @@ Binary Sensor Components
Remote Receiver, components/binary_sensor/remote_receiver, remote.svg
PN532 Tag, components/binary_sensor/pn532, pn532.jpg
RDM6300 Tag, components/binary_sensor/rdm6300, rdm6300.jpg
Custom Binary Sensor, components/binary_sensor/custom, language-cpp.svg
Output Components
-----------------
@ -148,6 +149,7 @@ Output Components
ESP32 LEDC, components/output/ledc, pwm.png
PCA9685, components/output/pca9685, pca9685.jpg
MY9231/MY9291, components/output/my9231, my9231.svg
Custom Output, components/output/custom, language-cpp.svg
Light Components
----------------
@ -180,6 +182,7 @@ Switch Components
Generic Output Switch, components/switch/output, upload.svg
Template Switch, components/switch/template, description.svg
UART Switch, components/switch/uart, uart.svg
Custom Switch, components/switch/custom, language-cpp.svg
Fan Components
--------------
@ -221,6 +224,7 @@ Text Sensor Components
MQTT Subscribe Text, components/text_sensor/mqtt_subscribe, mqtt.png
Version, components/text_sensor/version, new-box.svg
Template Text Sensor, components/text_sensor/template, description.svg
Custom Text Sensor, components/text_sensor/custom, language-cpp.svg
Misc Components
---------------
@ -244,6 +248,16 @@ Misc Components
Stepper, components/stepper/index, stepper.svg
MY9231/MY9291 LED driver, components/my9231, my9231.svg
Additional Custom Components
----------------------------
.. imgtable::
Generic Custom Component, custom/custom_component, language-cpp.svg
Custom I2C Component, custom/i2c, language-cpp.svg
Custom SPI Component, custom/spi, language-cpp.svg
Custom UART Component, custom/uart, language-cpp.svg
.. _cookbook:
Cookbook
@ -272,3 +286,4 @@ documentation for others to copy. See :doc:`Contributing <guides/contributing>`.
devices/index
guides/index
changelog/index
custom/index