mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-10-26 22:10:45 +00:00
206 lines
6.1 KiB
Arduino
206 lines
6.1 KiB
Arduino
// #######################################################################################################
|
|
// ######################## Plugin 127 CDM7160 I2C CO2 Sensor ############################################
|
|
// #######################################################################################################
|
|
// development version
|
|
// by: V0JT4
|
|
// Resolves: https://github.com/letscontrolit/ESPEasy/issues/986
|
|
//
|
|
|
|
/** Changelog:
|
|
* 2025-01-12 tonhuisman: Add support for MQTT AutoDiscovery
|
|
* Updated changelog
|
|
* 2022-06-24 tonhuisman: Remove delay from init call, optimize some code
|
|
* 2022-01-13 tonhuisman: Ignore measured values > 15000: unit is still initializing
|
|
* Change status from Development to Testing
|
|
* 2021-12-31 tonhuisman: Migrate plugin from ESPEasyPluginPlayground to ESPEasy repository
|
|
* - Restructured: Use ESPEasy 'modern' code
|
|
* - Restructured: Split into PluginDataStruct
|
|
* - Select Plugin ID 127
|
|
*/
|
|
|
|
|
|
#include "_Plugin_Helper.h"
|
|
#ifdef USES_P127
|
|
|
|
# include "src/PluginStructs/P127_data_struct.h"
|
|
|
|
# define PLUGIN_127
|
|
# define PLUGIN_ID_127 127
|
|
# define PLUGIN_NAME_127 "Gases - CO2 CDM7160"
|
|
# define PLUGIN_VALUENAME1_127 "CO2"
|
|
|
|
|
|
boolean Plugin_127_init = false;
|
|
|
|
|
|
boolean Plugin_127(uint8_t function, struct EventStruct *event, String& string)
|
|
{
|
|
boolean success = false;
|
|
|
|
switch (function) {
|
|
case PLUGIN_DEVICE_ADD:
|
|
{
|
|
auto& dev = Device[++deviceCount];
|
|
dev.Number = PLUGIN_ID_127;
|
|
dev.Type = DEVICE_TYPE_I2C;
|
|
dev.VType = Sensor_VType::SENSOR_TYPE_SINGLE;
|
|
dev.FormulaOption = true;
|
|
dev.ValueCount = 1;
|
|
dev.SendDataOption = true;
|
|
dev.TimerOption = true;
|
|
dev.GlobalSyncOption = true;
|
|
dev.PluginStats = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICENAME:
|
|
{
|
|
string = F(PLUGIN_NAME_127);
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICEVALUENAMES:
|
|
{
|
|
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_127));
|
|
break;
|
|
}
|
|
|
|
# if FEATURE_MQTT_DISCOVER
|
|
case PLUGIN_GET_DISCOVERY_VTYPES:
|
|
{
|
|
success = getDiscoveryVType(event, Plugin_QueryVType_CO2, 255, event->Par5);;
|
|
break;
|
|
}
|
|
# endif // if FEATURE_MQTT_DISCOVER
|
|
|
|
case PLUGIN_I2C_HAS_ADDRESS:
|
|
case PLUGIN_WEBFORM_SHOW_I2C_PARAMS:
|
|
{
|
|
const uint8_t i2cAddressValues[] = { CDM7160_ADDR_0, CDM7160_ADDR };
|
|
|
|
if (function == PLUGIN_WEBFORM_SHOW_I2C_PARAMS) {
|
|
addFormSelectorI2C(F("i2c_addr"), 2, i2cAddressValues, P127_CONFIG_I2C_ADDRESS, CDM7160_ADDR);
|
|
# ifndef LIMIT_BUILD_SIZE
|
|
addFormNote(F("CAD0 High/open=0x69, Low=0x68"));
|
|
# endif // ifndef LIMIT_BUILD_SIZE
|
|
} else {
|
|
success = intArrayContains(2, i2cAddressValues, event->Par1);
|
|
}
|
|
break;
|
|
}
|
|
|
|
# if FEATURE_I2C_GET_ADDRESS
|
|
case PLUGIN_I2C_GET_ADDRESS:
|
|
{
|
|
event->Par1 = P127_CONFIG_I2C_ADDRESS;
|
|
success = true;
|
|
break;
|
|
}
|
|
# endif // if FEATURE_I2C_GET_ADDRESS
|
|
|
|
case PLUGIN_SET_DEFAULTS:
|
|
{
|
|
P127_CONFIG_I2C_ADDRESS = CDM7160_ADDR;
|
|
ExtraTaskSettings.TaskDeviceValueDecimals[0] = 0; // No decimals needed
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WEBFORM_LOAD:
|
|
{
|
|
addFormNumericBox(F("Altitude"), F("altitude"), P127_CONFIG_ALTITUDE, 0, 2550); // Max. 2550 meter supported
|
|
addUnit('m');
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WEBFORM_SAVE:
|
|
{
|
|
P127_CONFIG_I2C_ADDRESS = getFormItemInt(F("i2c_addr"));
|
|
P127_CONFIG_ALTITUDE = getFormItemInt(F("altitude"));
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
case PLUGIN_INIT:
|
|
{
|
|
initPluginTaskData(event->TaskIndex, new (std::nothrow) P127_data_struct(P127_CONFIG_I2C_ADDRESS, P127_CONFIG_ALTITUDE));
|
|
P127_data_struct *P127_data = static_cast<P127_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
success = (nullptr != P127_data) && P127_data->init();
|
|
|
|
break;
|
|
}
|
|
case PLUGIN_ONCE_A_SECOND:
|
|
{
|
|
P127_data_struct *P127_data = static_cast<P127_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
if (nullptr != P127_data) {
|
|
success = P127_data->checkData();
|
|
}
|
|
|
|
break;
|
|
}
|
|
case PLUGIN_READ:
|
|
{
|
|
P127_data_struct *P127_data = static_cast<P127_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
if (nullptr == P127_data) {
|
|
return success;
|
|
}
|
|
|
|
UserVar.setFloat(event->TaskIndex, 0, P127_data->readData());
|
|
|
|
success = true;
|
|
|
|
if (UserVar[event->BaseVarIndex] > 15000) {
|
|
addLog(LOG_LEVEL_ERROR, F("CDM7160: Sensor still initializing, data ignored"));
|
|
success = false; // Do not send out to controllers
|
|
} else if (UserVar[event->BaseVarIndex] > 10000) {
|
|
addLog(LOG_LEVEL_ERROR, F("CDM7160: Sensor saturated! > 10000 ppm"));
|
|
}
|
|
|
|
#ifndef BUILD_NO_DEBUG
|
|
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
|
addLogMove(LOG_LEVEL_INFO, strformat(F("CDM7160: Address: 0x%02x: CO2 ppm: %d, alt: %d, comp: %d"),
|
|
P127_CONFIG_I2C_ADDRESS,
|
|
UserVar[event->BaseVarIndex],
|
|
P127_data->getAltitude(),
|
|
P127_data->getCompensation()));
|
|
}
|
|
#endif // ifndef BUILD_NO_DEBUG
|
|
break;
|
|
}
|
|
case PLUGIN_WRITE:
|
|
{
|
|
P127_data_struct *P127_data = static_cast<P127_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
if (nullptr != P127_data) {
|
|
String command = parseString(string, 1);
|
|
|
|
if (equals(command, F("cdmrst"))) {
|
|
addLog(LOG_LEVEL_INFO, F("CDM7160: reset"));
|
|
P127_data->setReset();
|
|
success = true;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_FIFTY_PER_SECOND: // Handle delays
|
|
{
|
|
P127_data_struct *P127_data = static_cast<P127_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
if (nullptr != P127_data) {
|
|
success = P127_data->plugin_fifty_per_second();
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
return success;
|
|
}
|
|
|
|
#endif // USES_P127
|