[Serial Proxy] Use capture filtering

This commit is contained in:
Gijs Noorlander
2020-03-21 11:20:30 +01:00
parent 698d904552
commit 62c1782e65
5 changed files with 104 additions and 57 deletions
+15
View File
@@ -599,6 +599,21 @@ char * MatchState::GetCapture (char * s, const int n) const
return s;
} // end of MatchState::GetCapture
String MatchState::GetCapture (const int n) const
{
if (result != REGEXP_MATCHED || n >= level || capture [n].len <= 0)
{
return "";
}
String s;
s.reserve(capture [n].len);
for (int i = 0; i < capture [n].len; ++i)
{
s += capture [n].init[i];
}
return s;
}
// match repeatedly on a string, return count of matches
unsigned int MatchState::MatchCount (const char * pattern)
{
+3
View File
@@ -15,12 +15,14 @@
Version 1.0 - 30th April 2011 : initial release.
Version 1.1 - 1st May 2011 : added some helper functions, made more modular.
Version 1.2 - 19th May 2011 : added more helper functions for replacing etc.
Version 1.2a - 12th March 2020 : TD-er: Added functions to get String captures + proper init of vars.
*/
#pragma once
#include <Arduino.h>
// Maximum of captures we can return.
// Increase if you need more, decrease to save memory.
@@ -112,6 +114,7 @@ public:
char * GetMatch (char * s) const;
// return capture string n
char * GetCapture (char * s, const int n) const;
String GetCapture (const int n) const;
// get result of previous match
char GetResult () const { return result; }
+2 -30
View File
@@ -31,7 +31,6 @@
#define P087_DEFAULT_BAUDRATE 38400
// Plugin settings:
// Validate:
// - [0..9]
@@ -130,40 +129,12 @@ boolean Plugin_087(byte function, struct EventStruct *event, String& string) {
case PLUGIN_WEBFORM_LOAD: {
serialHelper_webformLoad(event);
/*
P087_data_struct *P087_data =
static_cast<P087_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr != P087_data && P087_data->isInitialized()) {
String detectedString = F("Detected: ");
detectedString += String(P087_data->P087_easySerial->baudRate());
addUnit(detectedString);
*/
addFormNumericBox(F("Baudrate"), P087_BAUDRATE_LABEL, P087_BAUDRATE, 2400, 115200);
addUnit(F("baud"));
/*
{
// In a separate scope to free memory of String array as soon as possible
sensorTypeHelper_webformLoad_header();
String options[P087_NR_OUTPUT_OPTIONS];
for (int i = 0; i < P087_NR_OUTPUT_OPTIONS; ++i) {
options[i] = Plugin_087_valuename(i, true);
}
for (byte i = 0; i < P087_NR_OUTPUT_VALUES; ++i) {
const byte pconfigIndex = i + P087_QUERY1_CONFIG_POS;
sensorTypeHelper_loadOutputSelector(event, pconfigIndex, i, P087_NR_OUTPUT_OPTIONS, options);
}
}
*/
addFormSubHeader(F("Filtering"));
P087_html_show_matchForms(event);
addFormSubHeader(F("Statistics"));
P087_html_show_stats(event);
@@ -204,6 +175,7 @@ boolean Plugin_087(byte function, struct EventStruct *event, String& string) {
if (P087_data->init(serial_rx, serial_tx, P087_BAUDRATE)) {
LoadCustomTaskSettings(event->TaskIndex, P087_data->_lines, P87_Nlines, 0);
P087_data->post_init();
success = true;
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
@@ -367,7 +339,7 @@ void P087_html_show_matchForms(struct EventStruct *event) {
label += String(lineNr);
addRowLabel_tr_id(label, id);
addNumericBox(id, capture, 0, 99);
addNumericBox(id, capture, -1, P87_MAX_CAPTURE_INDEX);
break;
}
case 1:
+72 -25
View File
@@ -4,16 +4,16 @@
#ifdef USES_P087
P087_data_struct::P087_data_struct() : P087_easySerial(nullptr) {}
P087_data_struct::P087_data_struct() : easySerial(nullptr) {}
P087_data_struct::~P087_data_struct() {
reset();
}
void P087_data_struct::reset() {
if (P087_easySerial != nullptr) {
delete P087_easySerial;
P087_easySerial = nullptr;
if (easySerial != nullptr) {
delete easySerial;
easySerial = nullptr;
}
}
@@ -22,24 +22,46 @@ bool P087_data_struct::init(const int16_t serial_rx, const int16_t serial_tx, un
return false;
}
reset();
P087_easySerial = new ESPeasySerial(serial_rx, serial_tx);
easySerial = new ESPeasySerial(serial_rx, serial_tx);
if (isInitialized()) {
P087_easySerial->begin(baudrate);
easySerial->begin(baudrate);
return true;
}
return false;
}
void P087_data_struct::post_init() {
for (uint8_t i = 0; i < P87_MAX_CAPTURE_INDEX; ++i) {
capture_index_used[i] = false;
}
String log = F("P087_post_init:");
for (uint8_t i = 0; i < P087_NR_FILTERS; ++i) {
// Create some quick lookup table to see if we have a filter for the specific index
capture_index_must_not_match[i] = _lines[i * 3 + P087_FIRST_FILTER_POS + 1].toInt() == P087_Filter_Comp::NotEqual;
int index = _lines[i * 3 + P087_FIRST_FILTER_POS].toInt();
// Index is negative when not used.
if (index >= 0 && index < P87_MAX_CAPTURE_INDEX && _lines[i * 3 + P087_FIRST_FILTER_POS + 1].length() > 0) {
log += ' ';
log += String(i);
log += ':';
log += String(index);
capture_index[i] = index;
capture_index_used[index] = true;
}
}
addLog(LOG_LEVEL_DEBUG, log);
}
bool P087_data_struct::isInitialized() const {
return P087_easySerial != nullptr;
return easySerial != nullptr;
}
void P087_data_struct::sendString(const String& data) {
if (isInitialized()) {
if (data.length() > 0) {
setDisableFilterWindowTimer();
P087_easySerial->write(data.c_str());
easySerial->write(data.c_str());
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("Proxy: Sending: ");
@@ -56,16 +78,16 @@ bool P087_data_struct::loop() {
}
bool fullSentenceReceived = false;
if (P087_easySerial != nullptr) {
int available = P087_easySerial->available();
if (easySerial != nullptr) {
int available = easySerial->available();
while (available > 0 && !fullSentenceReceived) {
// Look for end marker
char c = P087_easySerial->read();
char c = easySerial->read();
--available;
if (available == 0) {
available = P087_easySerial->available();
available = easySerial->available();
delay(0);
}
@@ -207,19 +229,12 @@ static std::vector<capture_tuple> capture_vector;
// called for each match
void P087_data_struct::match_callback(const char *match, const unsigned int length, const MatchState& ms)
{
char cap[10]; // must be large enough to hold captures
Serial.print("Matched: ");
Serial.write((byte *)match, length);
Serial.println();
for (byte i = 0; i < ms.level; i++)
{
Serial.print("Capture ");
Serial.print(i, DEC);
Serial.print(" = ");
ms.GetCapture(cap, i);
Serial.println(cap);
capture_tuple tuple;
tuple.first = 1;
tuple.second = ms.GetCapture(i);
capture_vector.push_back(tuple);
} // end of for each capture
}
@@ -243,8 +258,40 @@ bool P087_data_struct::matchRegexp(String& received) const {
bool match_result = false;
if (globalMatch()) {
unsigned long count = ms.GlobalMatch(_lines[P087_REGEX_POS].c_str(), match_callback);
match_result = count != 0;
capture_vector.clear();
ms.GlobalMatch(_lines[P087_REGEX_POS].c_str(), match_callback);
const uint8_t vectorlength = capture_vector.size();
for (uint8_t i = 0; i < vectorlength; ++i) {
if (capture_vector[i].first < P87_MAX_CAPTURE_INDEX && capture_index_used[capture_vector[i].first]) {
for (uint8_t n = 0; n < P087_NR_FILTERS; ++n) {
if (capture_index[n] == capture_vector[i].first) {
String log;
log.reserve(32);
log = F("P087: Index: ");
log += capture_vector[i].first;
log += F(" Found ");
log += capture_vector[i].second;
// Found a Capture Filter with this capture index.
if (capture_vector[i].second == _lines[n * 3 + P087_FIRST_FILTER_POS + 2]) {
log += F(" Matches");
// Found a match. Now check if it is supposed to be one or not.
if (capture_index_must_not_match[n]) {
log += F(" (!=)");
addLog(LOG_LEVEL_INFO, log);
return false;
} else {
match_result = true;
log += F(" (==)");
}
} else {
log += F(" No Match");
}
addLog(LOG_LEVEL_INFO, log);
}
}
}
}
capture_vector.clear();
} else {
char result = ms.Match(_lines[P087_REGEX_POS].c_str());
+12 -2
View File
@@ -18,6 +18,7 @@
# define P087_NR_FILTERS 10
# define P87_Nlines (P087_FIRST_FILTER_POS + 3 * (P087_NR_FILTERS))
# define P87_Nchars 128
# define P87_MAX_CAPTURE_INDEX 32
enum P087_Filter_Comp {
@@ -45,6 +46,10 @@ public:
const int16_t serial_tx,
unsigned long baudrate);
// Called after loading the config from the settings.
// Will interpret some data and load caches.
void post_init();
bool isInitialized() const;
void sendString(const String& data);
@@ -82,7 +87,7 @@ public:
bool disableFilterWindowActive() const;
// called for each match
// called for each match when calling Global_Match
static void match_callback(const char *match,
const unsigned int length,
const MatchState & ms);
@@ -97,13 +102,18 @@ private:
bool max_length_reached() const;
ESPeasySerial *P087_easySerial = nullptr;
ESPeasySerial *easySerial = nullptr;
String sentence_part;
uint16_t max_length = 550;
uint32_t sentences_received = 0;
uint32_t sentences_received_error = 0;
uint32_t length_last_received = 0;
unsigned long disable_filter_window = 0;
uint8_t capture_index[P87_MAX_CAPTURE_INDEX] = {0};
bool capture_index_used[P87_MAX_CAPTURE_INDEX];
bool capture_index_must_not_match[P87_MAX_CAPTURE_INDEX];
};