mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-10-26 22:10:45 +00:00
235 lines
7.0 KiB
Arduino
235 lines
7.0 KiB
Arduino
#include "_Plugin_Helper.h"
|
|
#ifdef USES_P009
|
|
|
|
# include "src/DataStructs/PinMode.h"
|
|
# include "src/ESPEasyCore/ESPEasyGPIO.h"
|
|
# include "src/Helpers/_Plugin_Helper_webform.h"
|
|
|
|
# include "src/PluginStructs/P009_data_struct.h"
|
|
|
|
// #######################################################################################################
|
|
// #################################### Plugin 009: MCP23017 input #######################################
|
|
// #######################################################################################################
|
|
|
|
|
|
# define PLUGIN_009
|
|
# define PLUGIN_ID_009 9
|
|
# define PLUGIN_NAME_009 "Switch input - MCP23017"
|
|
# define PLUGIN_VALUENAME1_009 "State"
|
|
|
|
|
|
boolean Plugin_009(uint8_t function, struct EventStruct *event, String& string)
|
|
{
|
|
boolean success = false;
|
|
|
|
// static int8_t switchstate[TASKS_MAX];
|
|
|
|
switch (function)
|
|
{
|
|
case PLUGIN_DEVICE_ADD:
|
|
{
|
|
auto& dev = Device[++deviceCount];
|
|
dev.Number = PLUGIN_ID_009;
|
|
dev.Type = DEVICE_TYPE_I2C;
|
|
dev.VType = Sensor_VType::SENSOR_TYPE_SWITCH;
|
|
dev.InverseLogicOption = true;
|
|
dev.ValueCount = 1;
|
|
dev.SendDataOption = true;
|
|
dev.TimerOption = true;
|
|
dev.TimerOptional = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICENAME:
|
|
{
|
|
string = F(PLUGIN_NAME_009);
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICEVALUENAMES:
|
|
{
|
|
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_009));
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_I2C_HAS_ADDRESS:
|
|
case PLUGIN_WEBFORM_SHOW_I2C_PARAMS:
|
|
{
|
|
const uint8_t i2cAddressValues[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 };
|
|
|
|
if (function == PLUGIN_WEBFORM_SHOW_I2C_PARAMS) {
|
|
String portNames[16];
|
|
int portValues[16];
|
|
const uint8_t unit = (CONFIG_PORT - 1) / 16;
|
|
const uint8_t port = CONFIG_PORT - (unit * 16);
|
|
const uint8_t address = 0x20 + unit;
|
|
|
|
for (uint8_t x = 0; x < 16; ++x) {
|
|
portValues[x] = x + 1;
|
|
portNames[x] = 'P';
|
|
portNames[x] += (x < 8 ? 'A' : 'B');
|
|
portNames[x] += (x < 8 ? x : x - 8);
|
|
}
|
|
addFormSelectorI2C(F("pi2c"), 8, i2cAddressValues, address);
|
|
const FormSelectorOptions selector(16, portNames, portValues);
|
|
selector.addFormSelector(F("Port"), F("pport"), port);
|
|
} else {
|
|
success = intArrayContains(8, i2cAddressValues, event->Par1);
|
|
}
|
|
break;
|
|
}
|
|
|
|
# if FEATURE_I2C_GET_ADDRESS
|
|
case PLUGIN_I2C_GET_ADDRESS:
|
|
{
|
|
event->Par1 = P009_data_struct::getI2C_address(event);
|
|
success = true;
|
|
break;
|
|
}
|
|
# endif // if FEATURE_I2C_GET_ADDRESS
|
|
|
|
case PLUGIN_WEBFORM_LOAD:
|
|
{
|
|
// @giig1967g: set current task value for taking actions after changes
|
|
const uint32_t key = createKey(PLUGIN_MCP, CONFIG_PORT);
|
|
|
|
auto it = globalMapPortStatus.find(key);
|
|
|
|
if (it != globalMapPortStatus.end()) {
|
|
it->second.previousTask = event->TaskIndex;
|
|
}
|
|
|
|
SwitchWebformLoad(
|
|
P009_BOOTSTATE,
|
|
P009_DEBOUNCE,
|
|
P009_DOUBLECLICK,
|
|
P009_DC_MAX_INT,
|
|
P009_LONGPRESS,
|
|
P009_LP_MIN_INT,
|
|
P009_SAFE_BTN);
|
|
|
|
# if FEATURE_MQTT_DISCOVER && FEATURE_MQTT_DEVICECLASS
|
|
|
|
addFormSelector_binarySensorDeviceClass(F("MQTT Device class"),
|
|
F("devcls"),
|
|
P009_MQTT_DEVICECLASS);
|
|
# endif // if FEATURE_MQTT_DISCOVER && FEATURE_MQTT_DEVICECLASS
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WEBFORM_SAVE:
|
|
{
|
|
uint8_t i2c = getFormItemInt(F("pi2c"));
|
|
uint8_t port = getFormItemInt(F("pport"));
|
|
CONFIG_PORT = (((i2c - 0x20) << 4) + port);
|
|
|
|
SwitchWebformSave(
|
|
event->TaskIndex,
|
|
PLUGIN_MCP,
|
|
P009_BOOTSTATE,
|
|
P009_DEBOUNCE,
|
|
P009_DOUBLECLICK,
|
|
P009_DC_MAX_INT,
|
|
P009_LONGPRESS,
|
|
P009_LP_MIN_INT,
|
|
P009_SAFE_BTN);
|
|
|
|
# if FEATURE_MQTT_DISCOVER && FEATURE_MQTT_DEVICECLASS
|
|
P009_MQTT_DEVICECLASS = getFormItemInt(F("devcls"));
|
|
# endif // if FEATURE_MQTT_DISCOVER && FEATURE_MQTT_DEVICECLASS
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
# if FEATURE_MQTT_DISCOVER
|
|
case PLUGIN_GET_DISCOVERY_VTYPES:
|
|
|
|
success = getDiscoveryVType(event, Settings.TaskDevicePin1Inversed[event->TaskIndex]
|
|
? Plugin_QueryVType_BinarySensorInv
|
|
: Plugin_QueryVType_BinarySensor, 255, event->Par5);
|
|
# if FEATURE_MQTT_DEVICECLASS
|
|
string = MQTT_binary_deviceClassName(P009_MQTT_DEVICECLASS); // User selected device_cLass/dev_cls value
|
|
# endif // if FEATURE_MQTT_DEVICECLASS
|
|
break;
|
|
# endif // if FEATURE_MQTT_DISCOVER
|
|
|
|
case PLUGIN_INIT:
|
|
{
|
|
// apply INIT only if PIN is in range. Do not start INIT if pin not set in the device page.
|
|
if (CONFIG_PORT >= 0)
|
|
{
|
|
success = initPluginTaskData(event->TaskIndex, new (std::nothrow) P009_data_struct(event));
|
|
}
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_TEN_PER_SECOND:
|
|
{
|
|
P009_data_struct *P009_data =
|
|
static_cast<P009_data_struct *>(getPluginTaskData(event->TaskIndex));
|
|
|
|
if (nullptr != P009_data)
|
|
{
|
|
P009_data->tenPerSecond(event);
|
|
success = true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_READ:
|
|
{
|
|
// We do not actually read the pin state as this is already done 10x/second
|
|
// Instead we just send the last known state stored in Uservar
|
|
#ifndef BUILD_NO_DEBUG
|
|
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
|
addLog(LOG_LEVEL_INFO,
|
|
strformat(F("MCP : Port=%d State=%d"), CONFIG_PORT, UserVar[event->BaseVarIndex]));
|
|
}
|
|
#endif
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_REQUEST:
|
|
{
|
|
// parseString(string, 1) = device
|
|
// parseString(string, 2) = command
|
|
// parseString(string, 3) = gpio number
|
|
|
|
// returns pin value using syntax: [plugin#mcpgpio#pinstate#xx]
|
|
if ((string.length() >= 16) && string.substring(0, 16).equalsIgnoreCase(F("mcpgpio,pinstate")))
|
|
{
|
|
int32_t par1;
|
|
|
|
if (validIntFromString(parseString(string, 3), par1)) {
|
|
string = GPIO_MCP_Read(par1);
|
|
}
|
|
success = true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_TASKTIMER_IN:
|
|
case PLUGIN_DEVICETIMER_IN:
|
|
{
|
|
Scheduler.clearGPIOTimer(PLUGIN_MCP, event->Par1);
|
|
GPIO_MCP_Write(event->Par1, event->Par2);
|
|
|
|
// WARNING: operator [] creates an entry in the map if key does not exist
|
|
const uint32_t key = createKey(PLUGIN_MCP, event->Par1);
|
|
portStatusStruct tempStatus = globalMapPortStatus[key];
|
|
|
|
tempStatus.state = event->Par2;
|
|
tempStatus.mode = PIN_MODE_OUTPUT;
|
|
tempStatus.forceMonitor = (tempStatus.monitor) ? 1 : 0; // added to send event for longpulse command
|
|
savePortStatus(key, tempStatus);
|
|
break;
|
|
}
|
|
}
|
|
return success;
|
|
}
|
|
|
|
#endif // USES_P009
|