mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-12 01:24:04 +00:00
248 lines
9.2 KiB
Arduino
248 lines
9.2 KiB
Arduino
#include "_Plugin_Helper.h"
|
|
#ifdef USES_P153
|
|
|
|
// #######################################################################################################
|
|
// ######################### Plugin 153: Environment - SHT4x Temperature, Humidity #######################
|
|
// #######################################################################################################
|
|
|
|
/**
|
|
* 2023-08-26 tonhuisman: BUGFIX: Fixed wrong VType to correctly use SENSOR_TYPE_TEMP_HUM, so it will send data correctly to Domoticz
|
|
* 2023-06-10 tonhuisman: Return NaN values if there is an error connecting to the sensor, or a checksum error is reported
|
|
* 2023-06-10 tonhuisman: BUGFIX: The switch to Normal configuration wasn't working, resulting in checksum errors
|
|
* 2023-04-24 tonhuisman: Rename Boot configuration to Startup configuration, add PLUGIN_WRITE support for commands
|
|
* Minor improvements
|
|
* 2023-04-23 tonhuisman: Add Boot Configuration and Normal Configuration options, to allow evaporating condensation
|
|
* after start of the plugin
|
|
* 2023-04-22 tonhuisman: Start plugin for SHT4x (SHT40/SHT41/SHT43/SHT45) I2C Temperature and Humidity sensor
|
|
* Using direct I2C communication
|
|
**/
|
|
|
|
/** Commands:
|
|
* sht4x,startup : Re-start with the Startup Configuration, like a plugin re-start, using the same Interval runs,
|
|
* only accepted if Startup and Normal configuration are different, and Interval runs > 0.
|
|
* This allows to remove condensation from the sensor from Rules, f.e. once a day.
|
|
*/
|
|
|
|
# define PLUGIN_153
|
|
# define PLUGIN_ID_153 153
|
|
# define PLUGIN_NAME_153 "Environment - SHT4x"
|
|
# define PLUGIN_VALUENAME1_153 "Temperature"
|
|
# define PLUGIN_VALUENAME2_153 "Humidity"
|
|
|
|
# include "./src/PluginStructs/P153_data_struct.h"
|
|
|
|
bool P153_CheckIntervalError(struct EventStruct *event, int interval) {
|
|
bool result = false;
|
|
P153_configuration_e conf = static_cast<P153_configuration_e>(P153_STARTUP_CONFIGURATION);
|
|
|
|
if (((P153_configuration_e::HighResolution200mW1000msec == conf) ||
|
|
(P153_configuration_e::HighResolution110mW1000msec == conf) ||
|
|
(P153_configuration_e::HighResolution20mW1000msec == conf))
|
|
&& (interval <= 10)) {
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
boolean Plugin_153(uint8_t function, struct EventStruct *event, String& string)
|
|
{
|
|
boolean success = false;
|
|
|
|
const __FlashStringHelper *_intervalError = F("Interval must be increased or Heater duration decreased!"); // used 2x
|
|
|
|
switch (function)
|
|
{
|
|
case PLUGIN_DEVICE_ADD:
|
|
{
|
|
Device[++deviceCount].Number = PLUGIN_ID_153;
|
|
Device[deviceCount].Type = DEVICE_TYPE_I2C;
|
|
Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_TEMP_HUM;
|
|
Device[deviceCount].Ports = 0;
|
|
Device[deviceCount].PullUpOption = false;
|
|
Device[deviceCount].InverseLogicOption = false;
|
|
Device[deviceCount].FormulaOption = true;
|
|
Device[deviceCount].ValueCount = 2;
|
|
Device[deviceCount].SendDataOption = true;
|
|
Device[deviceCount].TimerOption = true;
|
|
Device[deviceCount].GlobalSyncOption = true;
|
|
Device[deviceCount].PluginStats = true;
|
|
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICENAME:
|
|
{
|
|
string = F(PLUGIN_NAME_153);
|
|
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICEVALUENAMES:
|
|
{
|
|
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_153));
|
|
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_153));
|
|
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_I2C_HAS_ADDRESS:
|
|
case PLUGIN_WEBFORM_SHOW_I2C_PARAMS:
|
|
{
|
|
const uint8_t i2cAddressValues[] = { 0x44, 0x45, 0x46 };
|
|
|
|
if (PLUGIN_WEBFORM_SHOW_I2C_PARAMS == function) {
|
|
addFormSelectorI2C(F("i2c_addr"), 3, i2cAddressValues, P153_I2C_ADDRESS);
|
|
addFormNote(F("Chip type determines address: SHT-4x-<b>A</b>xxx = 0x44, SHT-4x-<b>B</b>xxx = 0x45, SHT-4x-<b>C</b>xxx = 0x46"));
|
|
} else {
|
|
success = intArrayContains(3, i2cAddressValues, event->Par1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
# if FEATURE_I2C_GET_ADDRESS
|
|
case PLUGIN_I2C_GET_ADDRESS:
|
|
{
|
|
event->Par1 = P153_I2C_ADDRESS;
|
|
success = true;
|
|
break;
|
|
}
|
|
# endif // if FEATURE_I2C_GET_ADDRESS
|
|
|
|
case PLUGIN_SET_DEFAULTS:
|
|
{
|
|
P153_STARTUP_CONFIGURATION = static_cast<int>(P153_configuration_e::HighResolution);
|
|
P153_NORMAL_CONFIGURATION = static_cast<int>(P153_configuration_e::HighResolution);
|
|
P153_INTERVAL_LOOPS = 0;
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WEBFORM_LOAD:
|
|
{
|
|
addFormTextBox(F("Temperature offset"), F("tempoffset"), toString(P153_TEMPERATURE_OFFSET, 2), 5);
|
|
addUnit(F("°C"));
|
|
|
|
{
|
|
const __FlashStringHelper *configurations[] = {
|
|
F("Low resolution"),
|
|
F("Medium resolution"),
|
|
F("High resolution"),
|
|
F("High res., Heater 200 mWatt for 1 sec."),
|
|
F("High res., Heater 200 mWatt for 0.1 sec."),
|
|
F("High res., Heater 110 mWatt for 1 sec."),
|
|
F("High res., Heater 110 mWatt for 0.1 sec."),
|
|
F("High res., Heater 20 mWatt for 1 sec."),
|
|
F("High res., Heater 20 mWatt for 0.1 sec."),
|
|
};
|
|
const int configurationOptions[] = {
|
|
static_cast<int>(P153_configuration_e::LowResolution),
|
|
static_cast<int>(P153_configuration_e::MediumResolution),
|
|
static_cast<int>(P153_configuration_e::HighResolution),
|
|
static_cast<int>(P153_configuration_e::HighResolution200mW1000msec),
|
|
static_cast<int>(P153_configuration_e::HighResolution200mW100msec),
|
|
static_cast<int>(P153_configuration_e::HighResolution110mW1000msec),
|
|
static_cast<int>(P153_configuration_e::HighResolution110mW100msec),
|
|
static_cast<int>(P153_configuration_e::HighResolution20mW1000msec),
|
|
static_cast<int>(P153_configuration_e::HighResolution20mW100msec),
|
|
};
|
|
addFormSelector(F("Startup Configuration"),
|
|
F("startup"),
|
|
sizeof(configurationOptions) / sizeof(configurationOptions[0]),
|
|
configurations,
|
|
configurationOptions,
|
|
P153_STARTUP_CONFIGURATION);
|
|
addFormNote(F("Heater should not exceed 10% dutycycle, so 1 sec. heater must have Interval > 10 sec.!"));
|
|
|
|
addFormNumericBox(F("Use Normal Configuration after"), F("loops"), P153_INTERVAL_LOOPS, 0, 10);
|
|
addUnit(F("Interval runs (0..10)"));
|
|
|
|
addFormSelector(F("Normal Configuration"),
|
|
F("normal"),
|
|
3, // Only non-heater options
|
|
configurations,
|
|
configurationOptions,
|
|
P153_NORMAL_CONFIGURATION);
|
|
}
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WEBFORM_SAVE:
|
|
{
|
|
P153_I2C_ADDRESS = getFormItemInt(F("i2c_addr"));
|
|
P153_TEMPERATURE_OFFSET = getFormItemFloat(F("tempoffset"));
|
|
P153_STARTUP_CONFIGURATION = getFormItemInt(F("startup"));
|
|
P153_INTERVAL_LOOPS = getFormItemInt(F("loops"));
|
|
P153_NORMAL_CONFIGURATION = getFormItemInt(F("normal"));
|
|
|
|
int interval = getFormItemInt(F("TDT"));
|
|
|
|
if (P153_CheckIntervalError(event, interval)) {
|
|
addHtmlError(_intervalError);
|
|
}
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_INIT:
|
|
{
|
|
int interval = Settings.TaskDeviceTimer[event->TaskIndex];
|
|
|
|
if (!P153_CheckIntervalError(event, interval)) {
|
|
initPluginTaskData(event->TaskIndex, new (std::nothrow) P153_data_struct(P153_I2C_ADDRESS,
|
|
P153_TEMPERATURE_OFFSET,
|
|
static_cast<P153_configuration_e>(P153_STARTUP_CONFIGURATION),
|
|
static_cast<P153_configuration_e>(P153_NORMAL_CONFIGURATION),
|
|
P153_INTERVAL_LOOPS));
|
|
P153_data_struct *P153_data = static_cast<P153_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
success = (nullptr != P153_data) && P153_data->init();
|
|
} else {
|
|
addLog(LOG_LEVEL_ERROR, concat(F("SHT4x: "), _intervalError));
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_READ:
|
|
{
|
|
P153_data_struct *P153_data = static_cast<P153_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
if (nullptr != P153_data) {
|
|
success = P153_data->plugin_read(event);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WRITE:
|
|
{
|
|
P153_data_struct *P153_data = static_cast<P153_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
if (nullptr != P153_data) {
|
|
success = P153_data->plugin_write(event, string);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_CONFIG_VALUE:
|
|
{
|
|
P153_data_struct *P153_data = static_cast<P153_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
if (nullptr != P153_data) {
|
|
success = P153_data->plugin_get_config_value(event, string);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
return success;
|
|
}
|
|
|
|
#endif // USES_P153
|