Files
ESPEasy/docs/source/Plugin/P180.rst
T

315 lines
18 KiB
ReStructuredText

.. include:: ../Plugin/_plugin_substitutions_p18x.repl
.. _P180_page:
|P180_typename|
==================================================
|P180_shortinfo|
Plugin details
--------------
Type: |P180_type|
Name: |P180_name|
Status: |P180_status|
GitHub: |P180_github|_
Maintainer: |P180_maintainer|
Used libraries: |P180_usedlibraries|
Description
-----------
This plugin offers generic access to I2C devices, by providing a set of commands for reading and writing to an I2C address, manipulating an Enable and Reset GPIO pin, inserting a delay, conditionally stop executing the commands, calculating with the data read from the device, and assigning (intermediate) results to Values 1..4.
This enables the implementation of yet unsupported I2C devices or use I2C devices in builds where the available plugin isn't included.
.. warning:: This plugin is in the 'pro' category of plugins (i.o.w. not really *Easy* to use), and may require in-depth studying of the datasheet for the device, extracting the required commands and calculation(s) for implementing correct usage. (Examples available below)
Configuration
-------------
.. image:: P180_DeviceConfiguration.png
* **Name**: Required by ESPEasy, must be unique among the list of available devices/tasks.
* **Enabled**: The device can be disabled or enabled. When not enabled the device should not use any resources.
I2C options
^^^^^^^^^^^
* **I2C Address (Hex)**: Because of the flexible nature of the plugin, setting the I2C address requires typing the hexadecimal I2C address of the device. This should be in the range 0x01 .. 0x7F.
The available I2C settings here depend on the build used. At least the **Force Slow I2C speed** option is available. This plugin can also be used with an I2C Multiplexer, or use a separate I2C Bus when configured, to allow for multiple sensors on a single ESP. For details see the :ref:`Hardware_page`.
Device Settings
^^^^^^^^^^^^^^^
* **'Enable' GPIO**: Some devices have an Enable pin, that allows the device to be disabled, f.e. to conserve power, or extend the usable lifespan of the device. This can be set by an I2C command (see below).
* **'Reset' GPIO**: Some devices require to be reset, either after power-on, during use, or when not operating properly. This can be controlled by an I2C command (see below).
Output Configuration
^^^^^^^^^^^^^^^^^^^^
* **Output Data Type**: This setting determines the number of available Values, and is also used by f.e. the Domoticz controllers for sending data in the correct format. F.e. when configuring a Temperature & Humidity sensor, it makes sense to choose Temp / Hum here.
* **I2C Init Commands**: A sequence of commands, documented in detail below, that will be used to manipulate the sensor when the plugin is enabled. This can f.e. be used to initialize the sensor, set the **'Enable' GPIO** in the Enabled state, or pulse the **'Reset' GPIO** to reset the device.
* **I2C Exit Commands**: A sequence of commands that will be sent to the device when the plugin is disabled. This can f.e. be used to set the **'Enable' GPIO** in Disabled state, or set the device in a power-down state.
* **Parsing & executing log (INFO)**: When enabled, the command sequences will be logged during parsing and execution at *INFO* level, that's often very helpful when configuring & testing a new I2C device. Should best be disabled for production use to avoid excessive logging output.
Value x I2C Commands
^^^^^^^^^^^^^^^^^^^^
For each Value1 .. Value4 output, depending on the **Output Data Type** setting, a group of settings is available:
* **Value x type**: Here you can select a specific output type for each Value. This shows a selection of the **Output Data Type** selector, but only the single-value types. This will also be used for sending to Domoticz controllers and for MQTT Auto-Discovery.
* **Cache-Name x (optional)**: When set to a unique name (for this task), the parsed & pre-processed command sequence will be stored in a memory-cache, to improve the speed of the plugin in runtime. When not set, the command sequence will be parsed every time the task is run (**Interval** setting or ``taskRun`` command).
* **I2C Commands x**: The sequence of commands to execute for this value. Nothing will be done if this is empty. The corresponding Value output can be set from another I2C Commands sequence. The currently used vs. the available space is shown next to the field. I2C Commands are explained below.
Data Acquisition
^^^^^^^^^^^^^^^^
This group of settings, **Single event with all values** and **Send to Controller** settings are standard available configuration items. Send to Controller is only visible when one or more Controllers are configured.
* **Interval** Interval is optional, and will be set to 0 sec. by default. The data will be collected and optionally sent to any configured controllers using this interval.
Values
^^^^^^
The plugin provides 1 .. 4 Values. The names can be set as desired. A formula can be set to recalculate, f.e. when a temperature has to be presented in ° Fahrenheit instead of ° Celcius: ``%c_c2f%(%value%)``. The number of decimals can be set as desired.
In selected builds, per Value **Stats** options are available, that when enabled, will gather the measured data and present most recent data in a graph, as described here: :ref:`Task Value Statistics: <Task Value Statistics>`
Plugin Commands available
^^^^^^^^^^^^^^^^^^^^^^^^^
.. include:: P180_commands.repl
.. Get Config Values
.. ^^^^^^^^^^^^^^^^^
.. Get Config Values retrieves values or settings from the sensor or plugin, and can be used in Rules, Display plugins, Formula's etc. The square brackets **are** part of the variable. Replace ``<taskname>`` by the **Name** of the task.
.. .. include:: P180_config_values.repl
I2C Commands
------------
I2C Commands (sequences) are available for reading and writing the device on the selected I2C Bus, using the configured I2C address. If the address is not set, the plugin won't start.
The general I2C Command format is: ``<command>[.<dataformat>[.<length>]][.<arguments>....];...``
* The command separator is a semicolon ``;``
* The argument separator is a period ``.``
For ``dataformat`` there are a limited set of options available:
* ``u8``: uint8_t (1 byte)
* ``u16``: uint16_t (2 bytes)
* ``u24``: uint24_t (3 bytes)
* ``u32``: uint32_t (4 bytes)
* ``u16le``: uint16_t (2 bytes, little endian)
* ``u24le``: uint24_t (3 bytes, little endian)
* ``u32le``: uint32_t (4 bytes, little endian)
* ``8``: int8_t (1 byte, signed)
* ``16``: int16_t (2 bytes, signed)
* ``24``: int24_t (3 bytes, signed)
* ``32``: int32_t (4 bytes, signed)
* ``16le``: int16_t (2 bytes, signed, little endian)
* ``24le``: int24_t (3 bytes, signed, little endian)
* ``32le``: int32_t (4 bytes, signed, little endian)
* ``b[.<length>]``: <len> uint8_t (bytes), <length> is needed for reading only
* ``w[.<length>]``: <len> uint16_t (words), <length> is needed for reading only
The commands available can either be used with the full command, or the 1 character shortcut to save some space in the limited available storage:
* ``get.<format>[.<len>]``: ``(g)``: Read the number of bytes matching the format from the device.
* ``put.<format>.<data>[.<data>...]``: ``(p)``: Write data to the device, in the format specified. For ``b`` or ``w`` the provided data determines the length of the data to send.
* ``read.<format>[.<len>].<reg>``: ``(r)``: Read data in the requested format from a register in the device.
* ``write.<format>.<reg>.<data>[.<data>...]``: ``(w)``: Write data to a register in the device in the specified format.
* ``eval``: ``(e)``: Evaluate the previous command, and set as selected data for ``calc`` or ``if`` commands.
* ``value.<valueIndex>``: ``(v)``: (1..4 or a value name) Store the last calculated result, or last read value, in the specified Value field.
* ``calc.<calculation>``: ``(c)``: Calculate a result, like Rules, extra available vars: ``%value%``, ``%pvalue%``, ``%h%``, ``%b0%..%b<n>%``, ``%bx0%..%bx<n>%``, ``%w0%..%w<n>%``, ``%wx0%..%wx<n>%``
* ``if.<calculation>``: ``(i)``: Similar to ``calc`` command, when the calculation-result is 0 execution is cancelled
* ``delay.<msec>``: ``(d)``: (range: 0..500) Some devices, after starting a read, require some time to process data. This can be handled by a delay. If the delay is < 10 msec, it will be handled immediately, longer delays are processed asynchronous to avoid blocking the ESP for too long.
* ``enable.<state>``: ``(l)``: (0 or 1) Set the configured **'Enable' GPIO** pin to the provided state. If the pin is not configured, this command is ignored, and processing continues.
* ``reset.<state>.<msec>``: ``(z)``: (state = 0 or 1, msec = range: 0..500) Pulse the configured **'Reset' GPIO** pin for the provided time (msec) to the state requested, to reset the device. If the pin is not configured, this command is ignored, and processing continues.
During processing, the data has to be made available to some of the following steps to be able to calculate the outcome. The variables to insert the data are listed here:
* ``%pvalue%``: The value currently in the Value field for this command sequence (when run during an Interval), can be read as 'previous-value'.
The next variables are only available after an ``eval`` I2C Command is executed:
* ``%value%``: The value retrieved in decimal presentation. So if a ``read`` or ``get`` command was used. Not applicable for ``b.<length>`` and ``w.<length>`` dataformats.
* ``%h%``: The result of a ``read`` or ``get`` formatted as hex bytes with a single '0x' prefix, using the minimal number of digits needed. For ``b.<length>`` or ``w.<length>`` dataformat all bytes/words are concatenated. If 7 bytes are retrieved using ``get.b.7`` command, ``%h`` will be replaced by ``0x00010203040506``, or 3 words using ``get.w.3`` with ``0x000000010002``, showing the retrieved data of course.
* ``%b<N>%``: The value of byte N (0-based!), retrieved using the ``b.<length>`` dataformat. This will be a decimal presentation of the data.
* ``%bx<N>%``: The value of byte N (0-based!), retrieved using the ``b.<length>`` dataformat. This will be a 2 digit hexadecimal presentation, without '0x' prefix, of the data.
* ``%w<N>%``: The value of word N (0-based!), retrieved using the ``w.<length>`` dataformat. This will be a decimal presentation of the data.
* ``%wx<N>%``: The value of word N (0-based!), retrieved using the ``w.<length>`` dataformat. This will be a 4 digit hexadecimal presentation, without '0x' prefix, of the data.
|
Example I2C command sequences
-----------------------------
AHT2x Temperature / Humidity sensor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* This device is supported in :ref:`P105_page`, and was used for testing the plugin during development, as it has a few interesting requirements:
* All data (temperature and humidity) is read in a single command from the device.
* A delay is needed after the start-read command before we can retrieve valid data.
* The resulting data is split in a somewhat unusual way across the resulting byte buffer.
The I2C commands to read the values are extracted from the data sheet, available from the manufacturer via the `product information page <https://asairsensors.com/product/aht20-integrated-temperature-and-humidity-sensor/>`_ (Scroll down to find the 'Product specifications' link to a pdf file).
The plugin should be configured with these settings:
* **Output Data Type**: ``Temp / Hum``
Once this setting is saved:
* **Values**: the names can be changed to Temp or Temperature and Hum or Humidity, and the number of decimals adjusted as desired (usually 1 or 2 decimals is fine for both measurements). Stats can be enabled, best would be to set the Axis to **L1** for Temperature, and **R1** for Humidity, as the scales for these values don't match in range.
* **Interval**: can be set to 60 seconds to retrieve a measurement every minute.
The I2C Command sequence for retrieving the measurements: (NB: no ready-check is included here, though the data sheet suggests it to be used)
``write.u16.0xAC.0x3300;delay.80;get.b.7;eval;calc.'0x{substring:4:9:%h%}/10485.76';value.2;calc.'0x{substring:9:14:%h%}/5242.88-50';value.1``
Command sequence explanation:
* ``write.u16.0xAC.0x3300``: Write uint16 (word) value 0x3300 to register 0xAC to start a read sequence
* ``delay.80``: Wait for at least 80 msec (async/non-blocking when > 10 msec) before the values are available
* ``get.b.7``: Read 7 bytes from the sensor
* ``eval``: Use the previous command result for evaluation
* ``calc.'0x{substring:4:9:%h%}/10485.76'``: Calculate the humidity value from the data provided. `%h%` is the sequence of bytes read (fmt: `b.7`), prefixed with '0x', and only 5 nibbles are used for the humidity value. This is divided by 10485.75 (2^20 / 100) to get the humidity percentage. Quotes are used because of the decimal point used in this calculation, that's also the argument separator here.
* ``value.2``: Assign the last result to Value2 field (Hum)
* ``calc.'0x{substring:9:14:%h%}/5242.88-50'``: Calculate the temperature value from the data provided. Again 5 nibbles are used, to be divided by 2^20 / 200 and 50 subtracted.
* ``value.1``: Assign the last result to Value1 field (Temp)
|
M5Stack AIN4-20mA Unit / Module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
As documented here: `M5Stack AIN4-20mA Unit <https://docs.m5stack.com/en/unit/AIN4-20mA%20Unit>`_ and here: `M5Stack AIN4-20mA Module 13.2 <https://docs.m5stack.com/en/module/AIN4-20mA%20Module%2013.2>`_
This device can measure DC current in the 4..20 mA range, and has a rather straightforward protocol for reading, as shown in the Protocol overview near the end of that link. The unit has a single input, and the module is equiped with 4 inputs.
The plugin should be configured with these settings:
* **Output Data Type**: ``Single`` (Unit)
* **Output Data Type**: ``Quad`` (Module)
Once this setting is saved:
* **Values**: the name(s) can be changed to a more useful name, and the number of decimals adjusted as desired. Stats can also be enabled, where each value *can* have its own Axis.
The I2C Command sequence for retrieving the measurement from the first input:
``read.u16le.0x20;eval;calc.%value%/100``
Command sequence explanation:
* ``read.u16le.0x20``: Read an uint16 little endian (word) value from register 0x20
* ``eval``: Use the previous command result for evaluation
* ``calc.%value%/100``: Divide the retrieved value by 100 to obtain the mA value
The last calculated result will be stored in the Value field for this I2C command sequence (assumed it was entered in the plugin, not in Rules or a separate Command on the Tools page).
When using the M5Stack AIN4-20mA Module, with 4 input ports, the register address has to be increased with 2 for the next port, so 0x20 for port 0, 0x22 for port 1, 0x24 for port 2 and 0x26 for port 3. And similarly for reading the raw ADC value.
This device supports adjusting the calibration to the current current that is flowing through the input. The procedure is as follows:
* Supply a constant current of known value through the input, f.e. 12 mA.
* Calculate the configuration value by multiplying the input current by 100 => **1200**
* Use the Tools/Command field to send this command to the unit: ``genI2C,cmd,write.u16le.0x30.1200``
* I2C Command explanation:
* ``write.u16le.0x30.1200``: Write a word value (16 bit, Little Endian), to register 0x30, using value **1200**.
* Similar to reading another than input 0, 2 should be added to the register for writing the calibration, so 0x30 for port 0, 0x32 for port 1, 0x34 for port 2 and 0x36 for port 3.
|
Bosch BMP58x Temp/Baro
^^^^^^^^^^^^^^^^^^^^^^
Based on this datasheet: `Bosch Sensortec BMP580 <https://www.lcsc.com/datasheet/lcsc_datasheet_2410121909_Bosch-Sensortec-BMP580_C22391138.pdf>`_ (Via third party)
This device measures the barometric pressure and temperature, with high accuracy (+/- 0.5%) and high speed.
The plugin should be configured with these settings:
* **Output Data Type**: ``Temp / Baro``
Once this setting is saved:
* **Values**: the names can be changed to Temp or Temperature and Baro or Pressure, and the number of decimals adjusted as desired (usually 1 or 2 decimals is fine for temperature, and 0 for pressure). Stats can be enabled, best would be to set the Axis to L1 for Temperature, and R1 for Pressure, as the scales don't match the same range.
* **Interval**: can be set to 60 seconds to retrieve a measurement every minute.
The **I2C Init Commands** sequence for initializing the sensor:
``write.u8.0x36.0x40;write.u8.0x37.0x71``
This configures these parameters:
* Enable Pressure measurement
* No over-sampling (osr)
* 1 Hz output data rate (odr)
* Normal operating mode
If over-sampling or IIR filtering is desired, then information about setting the configuration registers can be obtained from the datasheet, linked above.
The **I2C Exit Commands** sequence for de-initializing the sensor before plugin exit:
``write.u8.0x37.0x70``
This configures these parameters:
* Standby operating mode.
The I2C Command sequence for reading the Temperature:
``read.u24le.0x1D;eval;calc.%value%/65536``
Command sequence explanation:
* ``read.u24le.0x1D``: Read an uint24 little endian value (3 bytes) value from register 0x1D
* ``eval``: Use the previous command result for evaluation
* ``calc.%value%/65536``: Divide the read value by 65536 as the right-most 16 bits are the fraction part
The I2C Command sequence for reading the Barometric pressure:
``read.u24le.0x20;eval;calc.%value%/64``
Command sequence explanation:
* ``read.u24le.0x20``: Read an uint24 little endian value (3 bytes) value from register 0x20
* ``eval``: Use the previous command result for evaluation
* ``calc.%value%/64``: Divide the read value by 64 as the right-most 6 bits are the fraction part
|
Change log
----------
.. versionchanged:: 2.0
...
|added|
2025-04-19 Initial release version.