Skip to content

Commit

Permalink
[TimingStats] Add timing stats for controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
TD-er committed Dec 19, 2018
1 parent 17f403d commit 9affa6b
Show file tree
Hide file tree
Showing 22 changed files with 138 additions and 62 deletions.
4 changes: 2 additions & 2 deletions src/Controller.ino
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ void sendData(struct EventStruct *event)
{
event->ProtocolIndex = getProtocolIndex(Settings.Protocol[event->ControllerIndex]);
if (validUserVar(event)) {
CPlugin_ptr[event->ProtocolIndex](CPLUGIN_PROTOCOL_SEND, event, dummyString);
CPluginCall(event->ProtocolIndex, CPLUGIN_PROTOCOL_SEND, event, dummyString);
} else {
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
String log = F("Invalid value detected for controller ");
String controllerName;
CPlugin_ptr[event->ProtocolIndex](CPLUGIN_GET_DEVICENAME, event, controllerName);
CPluginCall(event->ProtocolIndex, CPLUGIN_GET_DEVICENAME, event, controllerName);
log += controllerName;
addLog(LOG_LEVEL_DEBUG, log);
}
Expand Down
69 changes: 56 additions & 13 deletions src/ESPEasy-Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,17 +266,18 @@
#define PLUGIN_REQUEST 26
#define PLUGIN_TIME_CHANGE 27

#define CPLUGIN_PROTOCOL_ADD 1
#define CPLUGIN_PROTOCOL_TEMPLATE 2
#define CPLUGIN_PROTOCOL_SEND 3
#define CPLUGIN_PROTOCOL_RECV 4
#define CPLUGIN_GET_DEVICENAME 5
#define CPLUGIN_WEBFORM_SAVE 6
#define CPLUGIN_WEBFORM_LOAD 7
#define CPLUGIN_GET_PROTOCOL_DISPLAY_NAME 8
#define CPLUGIN_TASK_CHANGE_NOTIFICATION 9
#define CPLUGIN_INIT 10
#define CPLUGIN_UDP_IN 11
// Make sure the CPLUGIN_* does not overlap PLUGIN_*
#define CPLUGIN_PROTOCOL_ADD 41
#define CPLUGIN_PROTOCOL_TEMPLATE 42
#define CPLUGIN_PROTOCOL_SEND 43
#define CPLUGIN_PROTOCOL_RECV 44
#define CPLUGIN_GET_DEVICENAME 45
#define CPLUGIN_WEBFORM_SAVE 46
#define CPLUGIN_WEBFORM_LOAD 47
#define CPLUGIN_GET_PROTOCOL_DISPLAY_NAME 48
#define CPLUGIN_TASK_CHANGE_NOTIFICATION 49
#define CPLUGIN_INIT 50
#define CPLUGIN_UDP_IN 51

#define CONTROLLER_HOSTNAME 1
#define CONTROLLER_IP 2
Expand Down Expand Up @@ -1624,7 +1625,7 @@ boolean (*Plugin_ptr[PLUGIN_MAX])(byte, struct EventStruct*, String&);
std::vector<byte> Plugin_id;
std::vector<int> Task_id_to_Plugin_id;

boolean (*CPlugin_ptr[CPLUGIN_MAX])(byte, struct EventStruct*, String&);
bool (*CPlugin_ptr[CPLUGIN_MAX])(byte, struct EventStruct*, String&);
byte CPlugin_id[CPLUGIN_MAX];

boolean (*NPlugin_ptr[NPLUGIN_MAX])(byte, struct EventStruct*, String&);
Expand Down Expand Up @@ -1900,7 +1901,42 @@ bool mustLogFunction(int function) {
return false;
}

String getCPluginCFunctionName(int function) {
switch(function) {
case CPLUGIN_PROTOCOL_ADD: return F("CPLUGIN_PROTOCOL_ADD");
case CPLUGIN_PROTOCOL_TEMPLATE: return F("CPLUGIN_PROTOCOL_TEMPLATE");
case CPLUGIN_PROTOCOL_SEND: return F("CPLUGIN_PROTOCOL_SEND");
case CPLUGIN_PROTOCOL_RECV: return F("CPLUGIN_PROTOCOL_RECV");
case CPLUGIN_GET_DEVICENAME: return F("CPLUGIN_GET_DEVICENAME");
case CPLUGIN_WEBFORM_SAVE: return F("CPLUGIN_WEBFORM_SAVE");
case CPLUGIN_WEBFORM_LOAD: return F("CPLUGIN_WEBFORM_LOAD");
case CPLUGIN_GET_PROTOCOL_DISPLAY_NAME: return F("CPLUGIN_GET_PROTOCOL_DISPLAY_NAME");
case CPLUGIN_TASK_CHANGE_NOTIFICATION: return F("CPLUGIN_TASK_CHANGE_NOTIFICATION");
case CPLUGIN_INIT: return F("CPLUGIN_INIT");
case CPLUGIN_UDP_IN: return F("CPLUGIN_UDP_IN");
}
return F("Unknown");
}

bool mustLogCFunction(int function) {
switch(function) {
case CPLUGIN_PROTOCOL_ADD: return false;
case CPLUGIN_PROTOCOL_TEMPLATE: return false;
case CPLUGIN_PROTOCOL_SEND: return true;
case CPLUGIN_PROTOCOL_RECV: return true;
case CPLUGIN_GET_DEVICENAME: return false;
case CPLUGIN_WEBFORM_SAVE: return false;
case CPLUGIN_WEBFORM_LOAD: return false;
case CPLUGIN_GET_PROTOCOL_DISPLAY_NAME: return false;
case CPLUGIN_TASK_CHANGE_NOTIFICATION: return false;
case CPLUGIN_INIT: return false;
case CPLUGIN_UDP_IN: return true;
}
return false;
}

std::map<int,TimingStats> pluginStats;
std::map<int,TimingStats> controllerStats;
std::map<int,TimingStats> miscStats;
unsigned long timediff_calls = 0;
unsigned long timediff_cpu_cycles_total = 0;
Expand Down Expand Up @@ -1939,12 +1975,16 @@ unsigned long timingstats_last_reset = 0;
#define CONNECT_CLIENT_STATS 30
#define LOAD_CUSTOM_TASK_STATS 31
#define WIFI_ISCONNECTED_STATS 32
#define LOAD_TASK_SETTINGS 33
#define RULES_PROCESSING 34
#define BACKGROUND_TASKS 35




#define START_TIMER const unsigned statisticsTimerStart(micros());
#define STOP_TIMER_TASK(T,F) if (mustLogFunction(F)) pluginStats[T*32 + F].add(usecPassedSince(statisticsTimerStart));
#define STOP_TIMER_TASK(T,F) if (mustLogFunction(F)) pluginStats[T*256 + F].add(usecPassedSince(statisticsTimerStart));
#define STOP_TIMER_CONTROLLER(T,F) if (mustLogCFunction(F)) controllerStats[T*256 + F].add(usecPassedSince(statisticsTimerStart));
//#define STOP_TIMER_LOADFILE miscStats[LOADFILE_STATS].add(usecPassedSince(statisticsTimerStart));
#define STOP_TIMER(L) miscStats[L].add(usecPassedSince(statisticsTimerStart));

Expand All @@ -1971,6 +2011,9 @@ String getMiscStatsName(int stat) {
case CONNECT_CLIENT_STATS: return F("connectClient()");
case LOAD_CUSTOM_TASK_STATS: return F("LoadCustomTaskSettings()");
case WIFI_ISCONNECTED_STATS: return F("WiFi.isConnected()");
case LOAD_TASK_SETTINGS: return F("LoadTaskSettings()");
case RULES_PROCESSING: return F("rulesProcessing()");
case BACKGROUND_TASKS: return F("backgroundtasks()");
case C001_DELAY_QUEUE:
case C002_DELAY_QUEUE:
case C003_DELAY_QUEUE:
Expand Down
6 changes: 4 additions & 2 deletions src/ESPEasy.ino
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ int firstEnabledMQTTController() {
bool getControllerProtocolDisplayName(byte ProtocolIndex, byte parameterIdx, String& protoDisplayName) {
EventStruct tmpEvent;
tmpEvent.idx=parameterIdx;
return CPlugin_ptr[ProtocolIndex](CPLUGIN_GET_PROTOCOL_DISPLAY_NAME, &tmpEvent, protoDisplayName);
return CPluginCall(ProtocolIndex, CPLUGIN_GET_PROTOCOL_DISPLAY_NAME, &tmpEvent, protoDisplayName);
}

void updateLoopStats() {
Expand Down Expand Up @@ -836,7 +836,7 @@ void SensorSendTask(byte TaskIndex)
{
byte varIndex = TaskIndex * VARS_PER_TASK;

boolean success = false;
bool success = false;
byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[TaskIndex]);
LoadTaskSettings(TaskIndex);

Expand Down Expand Up @@ -903,6 +903,7 @@ void backgroundtasks()
{
return;
}
START_TIMER
runningBackgroundTasks=true;

#if defined(ESP8266)
Expand Down Expand Up @@ -940,4 +941,5 @@ void backgroundtasks()
statusLED(false);

runningBackgroundTasks=false;
STOP_TIMER(BACKGROUND_TASKS);
}
2 changes: 2 additions & 0 deletions src/ESPEasyRules.ino
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ void checkRuleSets() {
void rulesProcessing(String &event) {
if (!Settings.UseRules)
return;
START_TIMER
checkRAM(F("rulesProcessing"));
unsigned long timer = millis();
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
Expand Down Expand Up @@ -99,6 +100,7 @@ void rulesProcessing(String &event) {
log += F(" milliSeconds");
addLog(LOG_LEVEL_DEBUG, log);
}
STOP_TIMER(RULES_PROCESSING);
backgroundtasks();
}

Expand Down
8 changes: 4 additions & 4 deletions src/ESPEasyStatistics.ino
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ void logStatistics(byte loglevel, bool clearStats) {
log.reserve(80);
for (auto& x: pluginStats) {
if (!x.second.isEmpty()) {
const int pluginId = x.first/32;
const int pluginId = x.first/256;
String P_name = "";
Plugin_ptr[pluginId](PLUGIN_GET_DEVICENAME, NULL, P_name);
log = F("PluginStats P_");
log += pluginId + 1;
log += '_';
log += P_name;
log += ' ';
log += getPluginFunctionName(x.first%32);
log += getPluginFunctionName(x.first%256);
log += ' ';
log += getLogLine(x.second);
addLog(loglevel, log);
Expand Down Expand Up @@ -49,7 +49,7 @@ void jsonStatistics(bool clearStats) {
stream_json_start_array(F("plugin"));
for (auto& x: pluginStats) {
if (!x.second.isEmpty()) {
const int pluginId = x.first/32;
const int pluginId = x.first/256;
if (currentPluginId != pluginId) {
// new plugin
currentPluginId = pluginId;
Expand All @@ -74,7 +74,7 @@ void jsonStatistics(bool clearStats) {

unsigned long minVal, maxVal;
unsigned int c = x.second.getMinMax(minVal, maxVal);
stream_plugin_function_timing_stats_json(getPluginFunctionName(x.first%32),
stream_plugin_function_timing_stats_json(getPluginFunctionName(x.first%256),
c, minVal, maxVal, x.second.getAvg());
if (clearStats) x.second.reset();
firstFunction = false;
Expand Down
2 changes: 2 additions & 0 deletions src/ESPEasyStorage.ino
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ String LoadTaskSettings(byte TaskIndex)
checkRAM(F("LoadTaskSettings"));
if (ExtraTaskSettings.TaskIndex == TaskIndex)
return(String()); //already loaded
START_TIMER
ExtraTaskSettings.clear();
String result = "";
result = LoadFromFile(TaskSettings_Type, TaskIndex, (char*)FILE_CONFIG, (byte*)&ExtraTaskSettings, sizeof(struct ExtraTaskSettingsStruct));
Expand All @@ -433,6 +434,7 @@ String LoadTaskSettings(byte TaskIndex)
//the plugin call should populate ExtraTaskSettings with its default values.
PluginCall(PLUGIN_GET_DEVICEVALUENAMES, &TempEvent, dummyString);
}
STOP_TIMER(LOAD_TASK_SETTINGS);

return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Scheduler.ino
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ void process_system_event_queue() {
Plugin_ptr[Index](Function, &EventQueue.front().event, tmpString);
break;
case ControllerPluginEnum:
CPlugin_ptr[Index](Function, &EventQueue.front().event, tmpString);
CPluginCall(Index, Function, &EventQueue.front().event, tmpString);
break;
case NotificationPluginEnum:
NPlugin_ptr[Index](Function, &EventQueue.front().event, tmpString);
Expand Down
38 changes: 29 additions & 9 deletions src/WebServer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ void handle_controllers() {
ControllerSettings.ClientTimeout = CONTROLLER_CLIENTTIMEOUT_DFLT;
// ControllerSettings.MaxQueueDepth = 0;
if (Protocol[ProtocolIndex].usesTemplate)
CPlugin_ptr[ProtocolIndex](CPLUGIN_PROTOCOL_TEMPLATE, &TempEvent, dummyString);
CPluginCall(ProtocolIndex, CPLUGIN_PROTOCOL_TEMPLATE, &TempEvent, dummyString);
safe_strncpy(ControllerSettings.Subscribe, TempEvent.String1.c_str(), sizeof(ControllerSettings.Subscribe));
safe_strncpy(ControllerSettings.Publish, TempEvent.String2.c_str(), sizeof(ControllerSettings.Publish));
safe_strncpy(ControllerSettings.MQTTLwtTopic, TempEvent.String3.c_str(), sizeof(ControllerSettings.MQTTLwtTopic));
Expand Down Expand Up @@ -1297,7 +1297,7 @@ void handle_controllers() {
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[controllerindex]);
TempEvent.ControllerIndex = controllerindex;
TempEvent.ProtocolIndex = ProtocolIndex;
CPlugin_ptr[ProtocolIndex](CPLUGIN_WEBFORM_SAVE, &TempEvent, dummyString);
CPluginCall(ProtocolIndex, CPLUGIN_WEBFORM_SAVE, &TempEvent, dummyString);
ControllerSettings.UseDNS = usedns.toInt();
if (ControllerSettings.UseDNS)
{
Expand Down Expand Up @@ -1331,7 +1331,7 @@ void handle_controllers() {
ControllerSettings.ClientTimeout = clienttimeout;


CPlugin_ptr[ProtocolIndex](CPLUGIN_INIT, &TempEvent, dummyString);
CPluginCall(ProtocolIndex, CPLUGIN_INIT, &TempEvent, dummyString);
}
}
addHtmlError(SaveControllerSettings(controllerindex, ControllerSettings));
Expand Down Expand Up @@ -1370,7 +1370,7 @@ void handle_controllers() {
html_TD();
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[x]);
String ProtocolName = "";
CPlugin_ptr[ProtocolIndex](CPLUGIN_GET_DEVICENAME, 0, ProtocolName);
CPluginCall(ProtocolIndex, CPLUGIN_GET_DEVICENAME, 0, ProtocolName);
TXBuffer += ProtocolName;

html_TD();
Expand All @@ -1396,7 +1396,7 @@ void handle_controllers() {
for (byte x = 0; x <= protocolCount; x++)
{
String ProtocolName = "";
CPlugin_ptr[x](CPLUGIN_GET_DEVICENAME, 0, ProtocolName);
CPluginCall(x, CPLUGIN_GET_DEVICENAME, 0, ProtocolName);
boolean disabled = false;// !((controllerindex == 0) || !Protocol[x].usesMQTT);
addSelector_Item(ProtocolName,
Protocol[x].Number,
Expand Down Expand Up @@ -1521,7 +1521,7 @@ void handle_controllers() {

TempEvent.ControllerIndex = controllerindex;
TempEvent.ProtocolIndex = ProtocolIndex;
CPlugin_ptr[ProtocolIndex](CPLUGIN_WEBFORM_LOAD, &TempEvent,TXBuffer.buf);
CPluginCall(ProtocolIndex, CPLUGIN_WEBFORM_LOAD, &TempEvent,TXBuffer.buf);

}

Expand Down Expand Up @@ -2072,7 +2072,7 @@ void handle_devices() {
Settings.ControllerEnabled[TempEvent.ControllerIndex] && Settings.Protocol[TempEvent.ControllerIndex])
{
TempEvent.ProtocolIndex = getProtocolIndex(Settings.Protocol[TempEvent.ControllerIndex]);
CPlugin_ptr[TempEvent.ProtocolIndex](CPLUGIN_TASK_CHANGE_NOTIFICATION, &TempEvent, dummyString);
CPluginCall(TempEvent.ProtocolIndex, CPLUGIN_TASK_CHANGE_NOTIFICATION, &TempEvent, dummyString);
}
}
}
Expand Down Expand Up @@ -4414,7 +4414,7 @@ long stream_timing_statistics(bool clearStats) {
long timeSinceLastReset = timePassedSince(timingstats_last_reset);
for (auto& x: pluginStats) {
if (!x.second.isEmpty()) {
const int pluginId = x.first/32;
const int pluginId = x.first/256;
String P_name = "";
Plugin_ptr[pluginId](PLUGIN_GET_DEVICENAME, NULL, P_name);
if (x.second.thresholdExceeded(TIMING_STATS_THRESHOLD)) {
Expand All @@ -4427,7 +4427,27 @@ long stream_timing_statistics(bool clearStats) {
TXBuffer += '_';
TXBuffer += P_name;
html_TD();
TXBuffer += getPluginFunctionName(x.first%32);
TXBuffer += getPluginFunctionName(x.first%256);
stream_html_timing_stats(x.second, timeSinceLastReset);
if (clearStats) x.second.reset();
}
}
for (auto& x: controllerStats) {
if (!x.second.isEmpty()) {
const int pluginId = x.first/256;
String C_name = "";
CPluginCall(pluginId, CPLUGIN_GET_DEVICENAME, NULL, C_name);
if (x.second.thresholdExceeded(TIMING_STATS_THRESHOLD)) {
html_TR_TD_highlight();
} else {
html_TR_TD();
}
TXBuffer += F("C_");
TXBuffer += pluginId + 1;
TXBuffer += '_';
TXBuffer += C_name;
html_TD();
TXBuffer += getCPluginCFunctionName(x.first%256);
stream_html_timing_stats(x.second, timeSinceLastReset);
if (clearStats) x.second.reset();
}
Expand Down
4 changes: 2 additions & 2 deletions src/_C001.ino
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
#define CPLUGIN_NAME_001 "Domoticz HTTP"


boolean CPlugin_001(byte function, struct EventStruct *event, String& string)
bool CPlugin_001(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
bool success = false;

switch (function)
{
Expand Down
4 changes: 2 additions & 2 deletions src/_C002.ino
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

#include <ArduinoJson.h>

boolean CPlugin_002(byte function, struct EventStruct *event, String& string)
bool CPlugin_002(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
bool success = false;

switch (function)
{
Expand Down
6 changes: 3 additions & 3 deletions src/_C003.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
#define CPLUGIN_ID_003 3
#define CPLUGIN_NAME_003 "Nodo Telnet"

boolean CPlugin_003(byte function, struct EventStruct *event, String& string)
bool CPlugin_003(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
bool success = false;

switch (function)
{
Expand Down Expand Up @@ -57,7 +57,7 @@ boolean CPlugin_003(byte function, struct EventStruct *event, String& string)
}

bool do_process_c003_delay_queue(int controller_number, const C003_queue_element& element, ControllerSettingsStruct& ControllerSettings) {
boolean success = false;
bool success = false;
char log[80];
addLog(LOG_LEVEL_DEBUG, String(F("TELNT : connecting to ")) + ControllerSettings.getHostPortString());
// Use WiFiClient class to create TCP connections
Expand Down
4 changes: 2 additions & 2 deletions src/_C004.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
#define CPLUGIN_ID_004 4
#define CPLUGIN_NAME_004 "ThingSpeak"

boolean CPlugin_004(byte function, struct EventStruct *event, String& string)
bool CPlugin_004(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
bool success = false;

switch (function)
{
Expand Down
Loading

0 comments on commit 9affa6b

Please sign in to comment.