diff --git a/docs/source/Plugin/P105.rst b/docs/source/Plugin/P105.rst index c28fc651d..b1c030e61 100644 --- a/docs/source/Plugin/P105.rst +++ b/docs/source/Plugin/P105.rst @@ -79,6 +79,9 @@ When selecting the **AHT1x** Sensor model, an extra option is made available: * **AHT10 Alternative initialization**: Some AHT10 clone sensors do not seem to like the regular AHT10/AHT15 initialization sequence. They do however accept a soft reset command. By enabling this checkbox, only the soft reset is sent to the device. Only available for AHT1x devices. +* **Temperature offset** Depending on the sensor and the location of the sensor, it may be required to apply some temperature compensation. This can be set in steps of 0.1 degree. This also applies a compensation to the **Humidity** reading. + + Data Acquisition ^^^^^^^^^^^^^^^^ @@ -97,6 +100,7 @@ Change log .. versionchanged:: 2.0 ... + |changed| 2024/12/21 Add temperature offset |changed| 2024-12-03 Add alternative initialization option diff --git a/docs/source/Plugin/P105_DeviceConfiguration.png b/docs/source/Plugin/P105_DeviceConfiguration.png index 0064657c4..e82e6f94c 100644 Binary files a/docs/source/Plugin/P105_DeviceConfiguration.png and b/docs/source/Plugin/P105_DeviceConfiguration.png differ diff --git a/docs/source/Plugin/P164.rst b/docs/source/Plugin/P164.rst index 3662aae8d..49de70f7a 100644 --- a/docs/source/Plugin/P164.rst +++ b/docs/source/Plugin/P164.rst @@ -99,7 +99,7 @@ This group of settings, **Single event with all values** and **Send to Controlle Values ^^^^^^ -The plugin provides the ``TVOC`` and ``eCO2`` values. A formula can be set to recalculate. The number of decimals can be set as desired, and defaults to 2. +The plugin provides the ``TVOC``, ``eCO2`` and ``AQI`` values. A formula can be set to recalculate. The number of decimals can be set as desired, and defaults to 0. In selected builds, per Value is a **Stats** checkbox available, that when checked, gathers the data and presents recent data in a graph, as described here: :ref:`Task Value Statistics: ` @@ -112,6 +112,8 @@ Change log .. versionchanged:: 2.0 ... + |changed| 2024-12-21 Added AQI value + |added| 2023-12-27 Initial release version. diff --git a/docs/source/Plugin/P164_DeviceConfiguration.png b/docs/source/Plugin/P164_DeviceConfiguration.png index 86b7abb91..cc716ec26 100644 Binary files a/docs/source/Plugin/P164_DeviceConfiguration.png and b/docs/source/Plugin/P164_DeviceConfiguration.png differ diff --git a/src/_P105_AHT.ino b/src/_P105_AHT.ino index b11240f81..5b1de3d78 100644 --- a/src/_P105_AHT.ino +++ b/src/_P105_AHT.ino @@ -27,6 +27,7 @@ */ /** History: + * 2024-12-21 chromoxdor: Add temperature offset + simple humidity compensation * 2024-12-03 tonhuisman: Add alternative initialization for AHT10 (clone), see https://github.com/letscontrolit/ESPEasy/issues/5172 * Small code optimization. * 2024-04-28 tonhuisman: Update plugin name and documentation as DHT20 and AM2301B actually contain an AHT20! @@ -48,6 +49,11 @@ # define PLUGIN_VALUENAME2_105 "Humidity" +# define P105_I2C_ADRESS PCONFIG(0) +# define P105_AHT_TYPE PCONFIG(1) +# define P105_ALT_INIT PCONFIG(2) +# define P105_TEMPERATURE_OFFSET PCONFIG(3) + boolean Plugin_105(uint8_t function, struct EventStruct *event, String& string) { boolean success = false; @@ -87,7 +93,7 @@ boolean Plugin_105(uint8_t function, struct EventStruct *event, String& string) const uint8_t i2cAddressValues[2] = { 0x38, 0x39 }; if (function == PLUGIN_WEBFORM_SHOW_I2C_PARAMS) { - addFormSelectorI2C(F("i2c_addr"), 2, i2cAddressValues, PCONFIG(0)); + addFormSelectorI2C(F("i2c_addr"), 2, i2cAddressValues, P105_I2C_ADRESS); addFormNote(F("SDO Low=0x38, High=0x39. NB: Only available on AHT1x sensors.")); } else { success = intArrayContains(2, i2cAddressValues, event->Par1); @@ -99,7 +105,7 @@ boolean Plugin_105(uint8_t function, struct EventStruct *event, String& string) # if FEATURE_I2C_GET_ADDRESS case PLUGIN_I2C_GET_ADDRESS: { - event->Par1 = PCONFIG(0); + event->Par1 = P105_I2C_ADRESS; success = true; break; } @@ -107,13 +113,14 @@ boolean Plugin_105(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_SET_DEFAULTS: { - PCONFIG(1) = static_cast(AHTx_device_type::AHT20_DEVICE); + P105_AHT_TYPE = static_cast(AHTx_device_type::AHT20_DEVICE); + P105_TEMPERATURE_OFFSET = 0; break; } case PLUGIN_WEBFORM_LOAD: { - if (static_cast(PCONFIG(1)) == AHTx_device_type::AHT10_DEVICE) { + if (static_cast(P105_AHT_TYPE) == AHTx_device_type::AHT10_DEVICE) { bool hasOtherI2CDevices = false; for (taskIndex_t x = 0; validTaskIndex(x) && !hasOtherI2CDevices; ++x) { @@ -143,29 +150,35 @@ boolean Plugin_105(uint8_t function, struct EventStruct *event, String& string) const int indices[] = { static_cast(AHTx_device_type::AHT10_DEVICE), static_cast(AHTx_device_type::AHT20_DEVICE), static_cast(AHTx_device_type::AHT21_DEVICE) }; - addFormSelector(F("Sensor model"), F("ahttype"), 3, options, indices, PCONFIG(1), true); + addFormSelector(F("Sensor model"), F("ahttype"), 3, options, indices, P105_AHT_TYPE, true); addFormNote(F("Changing Sensor model will reload the page.")); - if (static_cast(AHTx_device_type::AHT10_DEVICE) == PCONFIG(1)) { - addFormCheckBox(F("AHT10 Alternative initialization"), F("altinit"), PCONFIG(2)); + if (static_cast(AHTx_device_type::AHT10_DEVICE) == P105_AHT_TYPE) { + addFormCheckBox(F("AHT10 Alternative initialization"), F("altinit"), P105_ALT_INIT); } } + addFormNumericBox(F("Temperature offset"), F("tempoffset"), P105_TEMPERATURE_OFFSET); + addUnit(F("x 0.1C")); + addFormNote("Offset in units of 0.1 degree Celsius and also corrects humidity."); success = true; + break; } case PLUGIN_WEBFORM_SAVE: { - PCONFIG(1) = getFormItemInt(F("ahttype")); + P105_AHT_TYPE = getFormItemInt(F("ahttype")); - if (static_cast(PCONFIG(1)) != AHTx_device_type::AHT10_DEVICE) { - PCONFIG(0) = 0x38; // AHT20/AHT21 only support a single I2C address. + if (static_cast(P105_AHT_TYPE) != AHTx_device_type::AHT10_DEVICE) { + P105_I2C_ADRESS = 0x38; // AHT20/AHT21 only support a single I2C address. } else { - PCONFIG(0) = getFormItemInt(F("i2c_addr")); - PCONFIG(2) = isFormItemChecked(F("altinit")) ? 1 : 0; + P105_I2C_ADRESS = getFormItemInt(F("i2c_addr")); + P105_ALT_INIT = isFormItemChecked(F("altinit")) ? 1 : 0; } - success = true; + + P105_TEMPERATURE_OFFSET = getFormItemInt(F("tempoffset")); + success = true; break; } @@ -173,7 +186,7 @@ boolean Plugin_105(uint8_t function, struct EventStruct *event, String& string) { success = initPluginTaskData( event->TaskIndex, - new (std::nothrow) P105_data_struct(PCONFIG(0), static_cast(PCONFIG(1)), 1 == PCONFIG(2))); + new (std::nothrow) P105_data_struct(P105_I2C_ADRESS, static_cast(P105_AHT_TYPE), 1 == P105_ALT_INIT)); break; } @@ -202,11 +215,11 @@ boolean Plugin_105(uint8_t function, struct EventStruct *event, String& string) } P105_data->state = AHTx_state::AHTx_Values_read; - UserVar.setFloat(event->TaskIndex, 0, P105_data->getTemperature()); - UserVar.setFloat(event->TaskIndex, 1, P105_data->getHumidity()); + UserVar.setFloat(event->TaskIndex, 0, P105_data->getTemperature() + (P105_TEMPERATURE_OFFSET / 10.0f)); + UserVar.setFloat(event->TaskIndex, 1, P105_data->getHumidity() * (1 - 0.005f * P105_TEMPERATURE_OFFSET)); if (loglevelActiveFor(LOG_LEVEL_INFO)) { - addLogMove(LOG_LEVEL_INFO, strformat(F("%s : Addr: 0x%02x"), P105_data->getDeviceName().c_str(), PCONFIG(0))); + addLogMove(LOG_LEVEL_INFO, strformat(F("%s : Addr: 0x%02x"), P105_data->getDeviceName().c_str(), P105_I2C_ADRESS)); addLogMove(LOG_LEVEL_INFO, strformat(F("%s : Temperature: %s : Humidity: %s"), P105_data->getDeviceName().c_str(),