Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[P153] Add plugin Environment - SHT4x (Temperature Humidity sensor) #4625

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
235 changes: 235 additions & 0 deletions src/_P153_SHT4x.ino
@@ -0,0 +1,235 @@
#include "_Plugin_Helper.h"
#ifdef USES_P153

// #######################################################################################################
// ######################### Plugin 153: Environment - SHT4x Temperature, Humidity #######################
// #######################################################################################################

/**
* 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
**/
# 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_BOOT_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_DUAL;
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_BOOT_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("Temp offset"), F("tempoffset"), toString(P153_TEMPERATURE_OFFSET, 2), 5);
addUnit(F("&deg;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("Boot Configuration"),
F("boot"),
sizeof(configurationOptions) / sizeof(configurationOptions[0]),
configurations,
configurationOptions,
P153_BOOT_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_BOOT_CONFIGURATION = getFormItemInt(F("boot"));
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_BOOT_CONFIGURATION),
static_cast<P153_configuration_e>(P153_BOOT_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
12 changes: 12 additions & 0 deletions src/src/CustomBuild/define_plugin_sets.h
Expand Up @@ -334,6 +334,9 @@ To create/register a plugin, you have to :
#ifndef FEATURE_ESPEASY_P2P
#define FEATURE_ESPEASY_P2P 1
#endif
#if defined(ESP8266) && !defined(LIMIT_BUILD_SIZE)
#define LIMIT_BUILD_SIZE
#endif

#ifndef FEATURE_I2CMULTIPLEXER
#define FEATURE_I2CMULTIPLEXER 1
Expand Down Expand Up @@ -1529,6 +1532,9 @@ To create/register a plugin, you have to :
#ifndef USES_P151
#define USES_P151 // Environment - I2C Honeywell Pressure
#endif
#ifndef USES_P153
#define USES_P153 // Environment - SHT4x
#endif

#endif

Expand Down Expand Up @@ -1788,6 +1794,9 @@ To create/register a plugin, you have to :
#ifndef USES_P151
#define USES_P151 // Environment - I2C Honeywell Pressure
#endif
#ifndef USES_P153
#define USES_P153 // Environment - SHT4x
#endif

// Controllers
#ifndef USES_C011
Expand Down Expand Up @@ -2139,6 +2148,9 @@ To create/register a plugin, you have to :
#ifndef USES_P151
#define USES_P151 // Environment - I2C Honeywell Pressure
#endif
#ifndef USES_P153
#define USES_P153 // Environment - SHT4x
#endif

// Controllers
#ifndef USES_C015
Expand Down
2 changes: 2 additions & 0 deletions src/src/PluginStructs/P145_data_struct.cpp
Expand Up @@ -800,7 +800,9 @@ void P145_data_struct::heaterControl(void)
{
unsigned long now = millis();
long time = timePassedSince(heaterChangeTime); // Time a state is active
# ifdef P145_DEBUG
P145_heaterState lastState = heaterState; // To detect a state change
# endif // ifdef P145_DEBUG

// Check if the heaterPin has been changed => change in controller
if (heaterPin != lastHeaterPin)
Expand Down