Complied V2 version, ready to start testing and start developing GUI
This commit is contained in:
156
lib/Core/ConfigParser.h
Normal file
156
lib/Core/ConfigParser.h
Normal file
@@ -0,0 +1,156 @@
|
||||
#ifndef CONFIG_PARSER_H
|
||||
#define CONFIG_PARSER_H
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <ModbusIP_ESP8266.h>
|
||||
#include <ModbusRTU.h>
|
||||
// Core inclusion
|
||||
#include "Equipment/Equipment.h"
|
||||
#include "ModbusPoints/Modbus_Point.h"
|
||||
#include "ModbusPoints/Modbus_PointFactory.h"
|
||||
#include "Storage.h"
|
||||
|
||||
// Current Strategies inclusions
|
||||
#include "Strategies/Strategy_Behavior.h"
|
||||
#include "Strategies/Strategy_Ramp.h"
|
||||
#include "Strategies/Strategy_Random.h"
|
||||
#include "Strategies/Strategy_Saw.h"
|
||||
#include "Strategies/Strategy_Square.h"
|
||||
#include "Strategies/Strategy_SingleValue.h"
|
||||
|
||||
class ConfigParser {
|
||||
private:
|
||||
// Create the Equipment generic instance using ModbusIP as default
|
||||
// Note: The original Equipment code use templates, it is possible to instantiate with ModbusIP
|
||||
static Equipment<ModbusIP>* _equipmentInstance;
|
||||
static WiFiServer* _pythonServer;
|
||||
static int _pythonPort;
|
||||
static int _modeIsTCP;
|
||||
public:
|
||||
|
||||
static Equipment<ModbusIP>* getEquipmentInstance() {
|
||||
if (_equipmentInstance == nullptr) {
|
||||
_equipmentInstance = new Equipment<ModbusIP>();
|
||||
}
|
||||
return _equipmentInstance;
|
||||
}
|
||||
/**
|
||||
* @brief Start the TCP socket server to listen Python though WiFi
|
||||
*/
|
||||
static void initPythonTCPServer(int port = 8888){
|
||||
_pythonPort = port;
|
||||
_pythonServer = new WiFiServer(_pythonPort);
|
||||
_pythonServer->begin();
|
||||
Serial.print(F("[ConfigParser] Python server started on port: "));
|
||||
Serial.println(_pythonPort);
|
||||
}
|
||||
/**
|
||||
* @brief Check if Python send Json through Wi-Fi and apply
|
||||
*/
|
||||
static void checkPythonTCPClient(ModbusIP& mbIP, ModbusRTU& mbRTU, bool* modeIsTCP){
|
||||
if (_pythonServer==nullptr) return;
|
||||
WiFiClient client = _pythonServer->available();
|
||||
if (client) {
|
||||
Serial.println(F("[ConfigParser] Python connected over Wi-Fi..."));
|
||||
String jsonConfig = client.readString();
|
||||
// Apply configuration if it is a valid JSON
|
||||
apply(jsonConfig, mbIP, mbRTU, modeIsTCP);
|
||||
// Store backup configuration in LittleFS
|
||||
Storage::saveConfigFile(jsonConfig);
|
||||
client.println("OK");
|
||||
client.stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main fucntion: Deserialize the Json and configure Modbus and strategies
|
||||
*/
|
||||
static void apply(const String& jsonConfig, ModbusIP& mbIP, ModbusRTU& mbRTU, bool* modeIsTCP) {
|
||||
Serial.println(F("[ConfigParser] Apply new configuration..."));
|
||||
JsonDocument doc;
|
||||
DeserializationError error = deserializeJson(doc, jsonConfig);
|
||||
if (error) {
|
||||
Serial.print(F("[ConfigParser] Deserialize Json Error: "));
|
||||
Serial.println(error.f_str());
|
||||
return;
|
||||
}
|
||||
// 1. Clean Hardware and RAM: Clear all Modbus points and strategies in the Equipment instance
|
||||
Equipment<ModbusIP>* eq = getEquipmentInstance();
|
||||
eq->clearEquipment();
|
||||
// 2. Network and Modbus protocol configuration.
|
||||
if (doc.containsKey("connection")){
|
||||
JsonObject connection = doc["connection"];
|
||||
String type = connection["type"] | "TCP";
|
||||
if (type.equalsIgnoreCase("TCP")){
|
||||
*modeIsTCP = true;
|
||||
int port = connection["port"] | 502;
|
||||
mbIP.server(port);
|
||||
Serial.print(F("[ConfigParser] Modbus TCP server started in port: "));
|
||||
Serial.println(port);
|
||||
} else {
|
||||
*modeIsTCP = false;
|
||||
int slaveId = connection["slave_id"] | 1;
|
||||
mbRTU.server(slaveId);
|
||||
Serial.print(F("[ConfigParser] Modbus RTU server started in slave ID: "));
|
||||
Serial.println(slaveId);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Rebuild the tags and strategies.
|
||||
if (doc.containsKey("points")){
|
||||
JsonArray pointsArray = doc["points"];
|
||||
Serial.print(F("[ConfigParser] Mapping requester registers: "));
|
||||
Serial.println(pointsArray.size());
|
||||
|
||||
for(JsonObject p : pointsArray){
|
||||
int address = p["address"];
|
||||
int category = p["cateogry"];
|
||||
int initVal = p["init_val"] | 0;
|
||||
const char* desc = p["desc"] | "Empty_Desc";
|
||||
|
||||
Modbus_Point<ModbusIP>* newPoint = nullptr;
|
||||
|
||||
if (*modeIsTCP) {
|
||||
newPoint = createModbus_Point(&mbIP, category, address, initVal, desc);
|
||||
} else {
|
||||
newPoint = createModbus_Point((ModbusIP*)&mbRTU, category, address, initVal, desc);
|
||||
}
|
||||
if (newPoint != nullptr) {
|
||||
newPoint->addToModbusServer();
|
||||
|
||||
if (p.containsKey("strategy")){
|
||||
const char* stratType = p["strategy"];
|
||||
unsigned long interval = p["interval"] | 1000;
|
||||
|
||||
Strategy_Behavior* strategy = nullptr;
|
||||
if (strcmp(stratType, "ramp") == 0) {
|
||||
strategy = new RampStrategy((float)(p["target"] | 0.0f), (float)(p["step"] | 100.0f), (int)(p["interval"] | 1000));
|
||||
}
|
||||
else if (strcmp(stratType, "random") == 0) {
|
||||
strategy = new RandomStrategy(interval);
|
||||
}
|
||||
else if (strcmp(stratType, "saw") == 0) {
|
||||
strategy = new SawStrategy((float)(p["min"] | 0.0f), (float)(p["max"] | 100.0f), (float)(p["step"] | 5.0f), (int)(p["interval"] | 1000));
|
||||
}
|
||||
else if (strcmp(stratType, "square") == 0) {
|
||||
strategy = new SquareStrategy((float)(p["lower"] | 0.0f), (float)(p["upper"] | 100.0f), (int)(p["interval"] | 1000));
|
||||
}
|
||||
else if (strcmp(stratType, "single") == 0 || strcmp(stratType, "none") == 0) {
|
||||
strategy = new SingleValueStrategy((float)(p["setpoint"] | 50.0f), (float)(p["noise"] | 0.5f), (int)(p["interval"] | 1000));
|
||||
}
|
||||
}
|
||||
eq->addModbus_Point(desc, newPoint);
|
||||
}
|
||||
}
|
||||
Serial.println(F("[ConfigParser] Tag deployment completed successfully."));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline Equipment<ModbusIP>* ConfigParser::_equipmentInstance = nullptr;
|
||||
inline WiFiServer* ConfigParser::_pythonServer = nullptr;
|
||||
inline int ConfigParser::_modeIsTCP = true;
|
||||
inline int ConfigParser::_pythonPort = 8888;
|
||||
#endif
|
||||
Reference in New Issue
Block a user