Merge remote-tracking branch 'origin/bugfix/3374_websource_command' into bugfix/3374_websource_command

This commit is contained in:
TD-er
2020-11-23 10:03:38 +01:00
6 changed files with 117 additions and 98 deletions
+4 -4
View File
@@ -52,11 +52,11 @@ Rules examples
On Switch#State Do
if [Switch#State]=1
Servo,12,1,-45
Servo,14,2,45
Servo,1,12,-45
Servo,2,14,45
else
Servo,12,1,0
Servo,14,2,0
Servo,1,12,0
Servo,2,14,0
endif
EndOn
+2 -83
View File
@@ -43,13 +43,7 @@
#define PLUGIN_ID_001 1
#define PLUGIN_NAME_001 "Switch input - Switch"
#define PLUGIN_VALUENAME1_001 "State"
#ifdef USE_SERVO
#ifdef ESP32
#include <Servo.h>
#endif
Servo servo1;
Servo servo2;
#endif // USE_SERVO
// Make sure the initial default is a switch (value 0)
#define PLUGIN_001_TYPE_SWITCH 0
#define PLUGIN_001_TYPE_DIMMER 3 // Due to some changes in previous versions, do not use 2.
@@ -112,13 +106,9 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
case PLUGIN_GET_DEVICEGPIONAMES:
{
// FIXME TD-er: This plugin is handling too much.
// FIXME TD-er: Split functionality of this plugin into 2 new ones:
// - switch/dimmer input
// - PWM output
// - switch output (relays)
// - servo output
// - sending pulses
// - playing tunes
event->String1 = formatGpioName_bidirectional("");
break;
}
@@ -721,77 +711,6 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
// WARNING: don't read "globalMapPortStatus[key]" here, as it will create a new entry if key does not exist
if (command == F("servo")) {
// IRAM: doing servo stuff uses 740 bytes IRAM. (doesnt matter how many instances)
#ifdef USE_SERVO
// GPIO number is stored inside event->Par2 instead of event->Par1 as in all the other commands
// So needs to reload the tempPortStruct.
success = true;
if ((event->Par1 >= 0) && (event->Par1 <= 2)) {
portStatusStruct tempStatus;
const uint32_t key = createKey(PLUGIN_ID_001, event->Par2); // WARNING: 'servo' uses Par2 instead of Par1
// WARNING: operator [] creates an entry in the map if key does not exist
// So the next command should be part of each command:
tempStatus = globalMapPortStatus[key];
switch (event->Par1)
{
case 1:
// SPECIAL CASE TO ALLOW SERVO TO BE DETATTCHED AND SAVE POWER.
if (event->Par3 >= 9000) {
servo1.detach();
#ifdef ESP32
detachLedChannel(event->Par2);
#endif
} else {
#ifdef ESP32
// Must keep track of used channels or else cause conflicts with PWM
int8_t ledChannel = attachLedChannel(event->Par2);
servo1.attach(event->Par2, ledChannel);
#else
servo1.attach(event->Par2);
#endif
servo1.write(event->Par3);
}
break;
case 2:
if (event->Par3 >= 9000) {
servo2.detach();
#ifdef ESP32
detachLedChannel(event->Par2);
#endif
} else {
#ifdef ESP32
// Must keep track of used channels or else cause conflicts with PWM
int8_t ledChannel = attachLedChannel(event->Par2);
servo2.attach(event->Par2, ledChannel);
#else
servo2.attach(event->Par2);
#endif
servo2.write(event->Par3);
}
break;
}
// setPinState(PLUGIN_ID_001, event->Par2, PIN_MODE_SERVO, event->Par3);
tempStatus.mode = PIN_MODE_SERVO;
tempStatus.state = event->Par3;
tempStatus.output = event->Par3;
tempStatus.command = 1; // set to 1 in order to display the status in the PinStatus page
savePortStatus(key, tempStatus);
log = String(F("SW : GPIO ")) + String(event->Par2) + String(F(" Servo set to ")) + String(event->Par3);
addLog(LOG_LEVEL_INFO, log);
SendStatusOnlyIfNeeded(event->Source, SEARCH_PIN_STATE, key, log, 0);
// SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_001, event->Par2, log, 0));
}
#else
addLog(LOG_LEVEL_ERROR, F("USE_SERVO not included in build"));
#endif // USE_SERVO
} else
if (command == F("inputswitchstate")) {
success = true;
+2
View File
@@ -27,6 +27,7 @@
#include "../Commands/Rules.h"
#include "../Commands/SDCARD.h"
#include "../Commands/Settings.h"
#include "../Commands/Servo.h"
#include "../Commands/System.h"
#include "../Commands/Tasks.h"
#include "../Commands/Time.h"
@@ -330,6 +331,7 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch
COMMAND_CASE_R("serialfloat", Command_SerialFloat, 0); // Diagnostic.h
#endif // ifndef BUILD_NO_DIAGNOSTIC_COMMANDS
COMMAND_CASE_R( "settings", Command_Settings_Print, 0); // Settings.h
COMMAND_CASE_A( "servo", Command_Servo, 3); // Servo.h
}
COMMAND_CASE_A("status", Command_GPIO_Status, 2); // GPIO.h
COMMAND_CASE_R("subnet", Command_Subnet, 1); // Network Command
+84
View File
@@ -0,0 +1,84 @@
#include "../Commands/Servo.h"
#include "../Commands/Common.h"
#include "../DataStructs/EventStructCommandWrapper.h"
#include "../DataStructs/PinMode.h"
#include "../DataStructs/PortStatusStruct.h"
#include "../ESPEasyCore/Controller.h"
#include "../ESPEasyCore/ESPEasyGPIO.h"
#include "../ESPEasyCore/ESPEasy_Log.h"
#include "../Globals/GlobalMapPortStatus.h"
#include "../Helpers/PortStatus.h"
#ifdef USE_SERVO
ServoPinMap_t ServoPinMap;
#endif // ifdef USE_SERVO
String Command_Servo(struct EventStruct *event, const char *Line)
{
#ifdef USE_SERVO
// GPIO number is stored inside event->Par2 instead of event->Par1 as in all the other commands
// So needs to reload the tempPortStruct.
// FIXME TD-er: For now only fixed to "P001" even when it is for internal GPIO pins
pluginID_t pluginID = 1;
// Par1: Servo ID (obsolete/unused since 2020/11/22)
// Par2: GPIO pin
// Par3: angle 0...180 degree
if (checkValidPortRange(pluginID, event->Par2)) {
portStatusStruct tempStatus;
const uint32_t key = createKey(pluginID, event->Par2); // WARNING: 'servo' uses Par2 instead of Par1
// WARNING: operator [] creates an entry in the map if key does not exist
// So the next command should be part of each command:
tempStatus = globalMapPortStatus[key];
// SPECIAL CASE TO ALLOW SERVO TO BE DETATTCHED AND SAVE POWER.
if (event->Par3 >= 9000) {
auto it = ServoPinMap.find(event->Par2);
if (it != ServoPinMap.end()) {
it->second.detach();
# ifdef ESP32
detachLedChannel(event->Par2);
# endif // ifdef ESP32
ServoPinMap.erase(it);
}
// Set parameters to make sure the port status will be removed.
tempStatus.task = 0;
tempStatus.monitor = 0;
tempStatus.command = 0;
} else {
# ifdef ESP32
// Must keep track of used channels or else cause conflicts with PWM
int8_t ledChannel = attachLedChannel(event->Par2);
ServoPinMap[event->Par2].attach(event->Par2, ledChannel);
# else // ifdef ESP32
ServoPinMap[event->Par2].attach(event->Par2);
# endif // ifdef ESP32
ServoPinMap[event->Par2].write(event->Par3);
tempStatus.command = 1; // set to 1 in order to display the status in the PinStatus page
tempStatus.state = 1;
tempStatus.output = 1;
tempStatus.dutyCycle = event->Par3;
}
// setPinState(PLUGIN_ID_001, event->Par2, PIN_MODE_SERVO, event->Par3);
tempStatus.mode = PIN_MODE_SERVO;
savePortStatus(key, tempStatus);
String log = String(F("Servo : GPIO ")) + String(event->Par2) + String(F(" Servo set to ")) + String(event->Par3);
addLog(LOG_LEVEL_INFO, log);
SendStatusOnlyIfNeeded(event->Source, SEARCH_PIN_STATE, key, log, 0);
// SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_001, event->Par2, log, 0));
return return_command_success();
}
#else // ifdef USE_SERVO
addLog(LOG_LEVEL_ERROR, F("USE_SERVO not included in build"));
#endif // USE_SERVO
return return_command_failed();
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef COMMANDS_SERVO_H
#define COMMANDS_SERVO_H
#include "../../ESPEasy_common.h"
#include <Arduino.h>
#include <map>
#ifdef USE_SERVO
# ifdef ESP32
# include <Servo.h>
# endif // ifdef ESP32
// IRAM: doing servo stuff uses 740 bytes IRAM. (doesnt matter how many instances)
typedef std::map<uint8_t, Servo> ServoPinMap_t;
extern ServoPinMap_t ServoPinMap;
#endif // USE_SERVO
String Command_Servo(struct EventStruct *event,
const char *Line);
#endif // ifndef COMMANDS_SERVO_H
+1 -11
View File
@@ -22,17 +22,7 @@ void savePortStatus(uint32_t key, struct portStatusStruct& tempStatus) {
}
bool existPortStatus(uint32_t key) {
bool retValue = false;
// check if KEY exists:
std::map<uint32_t, portStatusStruct>::iterator it;
it = globalMapPortStatus.find(key);
if (it != globalMapPortStatus.end()) { // if KEY exists...
retValue = true;
}
return retValue;
return globalMapPortStatus.find(key) != globalMapPortStatus.end();
}
void removeTaskFromPort(uint32_t key) {