First stable compilation with ModbusRTU and ModbusTCP
This commit is contained in:
167
lib/Core/States/State.h
Normal file
167
lib/Core/States/State.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* @file State.h
|
||||
* @brief Defines the abstract base class for all device states.
|
||||
* @author Emmanuel Hernandez Cruz
|
||||
* @date 2025-09-04
|
||||
*
|
||||
* This file contains the definition of the abstract State class, which is a base
|
||||
* to implement the State Pattern. Concrete states (Standby, Running, Random, Fail, etc.)
|
||||
* will inherit from this class.
|
||||
*/
|
||||
#ifndef State_h
|
||||
#define State_h
|
||||
#include <string>
|
||||
#include <Arduino.h>
|
||||
#include <map>
|
||||
#include "Strategies/Strategy_PID.h"
|
||||
#include "Categories/ModbusFloatDecorator.h"
|
||||
#include "Categories/ModbusPoint.h"
|
||||
|
||||
// Forward Declarations
|
||||
template<typename T>class Equipment;
|
||||
class Strategy_Behavior;
|
||||
|
||||
/**
|
||||
* @class State
|
||||
* @brief Abstract base class for a state in the State design pattern.
|
||||
*
|
||||
* This class defines the interface for all concrete states. It manages a
|
||||
* collection of "strategies" that define how Modbus points behave while the
|
||||
* equipment is in this state.
|
||||
*/
|
||||
template<typename T>
|
||||
class State{
|
||||
public:
|
||||
/**
|
||||
* @brief Virtual destructor.
|
||||
* Cleans up all associated Strategy_Behavior objects.
|
||||
*/
|
||||
virtual ~State();
|
||||
|
||||
/**
|
||||
* @brief Executes the state's logic for one update cycle.
|
||||
* This method applies the state's strategies and checks for transitions.
|
||||
* @param equipment Pointer to the Equipment instance.
|
||||
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
|
||||
*/
|
||||
virtual State* update(Equipment<T>* equipment) = 0;
|
||||
/**
|
||||
* @brief Logic to execute once when entering this state.
|
||||
* @param equipment Pointer to the Equipment instance.
|
||||
*/
|
||||
virtual void enterState(Equipment<T>* equipment) {}
|
||||
/**
|
||||
* @brief Logic to execute once when exiting this state.
|
||||
* @param equipment Pointer to the Equipment instance.
|
||||
*/
|
||||
virtual void exitState(Equipment<T>* equipment) {}
|
||||
/**
|
||||
* @brief Logic to apply all strategies created.
|
||||
* @param equipment Pointer to the Equipment instance.
|
||||
*/
|
||||
virtual void _applyStrategies(Equipment<T>* equipment);
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Adds a behavior strategy for a specific Modbus point.
|
||||
* @param pointDescription The description of the Modbus point to apply the strategy to.
|
||||
* @param strategy A pointer to the Strategy_Behavior object. The State will take ownership.
|
||||
*/
|
||||
float getPointValue(Equipment<T>* equipment, const std::string& pointName);
|
||||
void setPointValue(Equipment<T>* equipment, const std::string& pointName, float value);
|
||||
void addStrategy(const std::string& pointDescription, Strategy_Behavior* strategy);
|
||||
std::map<std::string, Strategy_Behavior*> _strategies;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
State<T>::~State(){
|
||||
for (auto const& pair : this->_strategies) {
|
||||
delete pair.second; // 'second' is the pointer to Strategy_Behavior
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a new strategy to the state's behavior map.
|
||||
*
|
||||
* The State object takes ownership of the strategy pointer and will be
|
||||
* responsible for its deletion.
|
||||
*
|
||||
* @param pointDescription The description of the Modbus point this strategy applies to.
|
||||
* @param strategy A pointer to a Strategy_Behavior object.
|
||||
*/
|
||||
template<typename T>
|
||||
void State<T>::addStrategy(const std::string& pointDescription, Strategy_Behavior* strategy){
|
||||
this->_strategies[pointDescription] = strategy;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float State<T>::getPointValue(Equipment<T>* equipment, const std::string& pointName) {
|
||||
ModbusPoint<T>* point = equipment->getModbusPoint(pointName);
|
||||
if (!point) return 0.0f;
|
||||
|
||||
if (point->getType() == PointType::FLOAT) {
|
||||
// If it's a float, cast and get the full float value
|
||||
return static_cast<ModbusFloatDecorator<T>*>(point)->getFloatValue();
|
||||
} else {
|
||||
// Otherwise, get the standard integer value
|
||||
return static_cast<float>(point->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void State<T>::setPointValue(Equipment<T>* equipment, const std::string& pointName, float value) {
|
||||
ModbusPoint<T>* point = equipment->getModbusPoint(pointName);
|
||||
if (!point) return;
|
||||
|
||||
if (point->getType() == PointType::FLOAT) {
|
||||
static_cast<ModbusFloatDecorator<T>*>(point)->setFloatValue(value);
|
||||
} else {
|
||||
point->setValue(round(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Applies all registered strategies for the current state.
|
||||
*
|
||||
* This helper method iterates through all strategies associated with this state.
|
||||
* For each strategy that is ready to run (based on its internal timer), it
|
||||
* retrieves the corresponding Modbus point and applies the new value.
|
||||
* It handles both integer and float point types.
|
||||
*
|
||||
* @param equipment A pointer to the main Equipment object.
|
||||
*/
|
||||
template<typename T>
|
||||
void State<T>::_applyStrategies(Equipment<T>* equipment) {
|
||||
unsigned long currentTime = millis();
|
||||
|
||||
// Use the C++11 compatible for-loop for std::map
|
||||
for (auto const& pair : this->_strategies) {
|
||||
const std::string& description = pair.first;
|
||||
Strategy_Behavior* strategy = pair.second;
|
||||
|
||||
if (strategy->isReady(currentTime)) {
|
||||
ModbusPoint<T>* outputPoint = equipment->getModbusPoint(description);
|
||||
if (!outputPoint) continue;
|
||||
|
||||
float inputValue;
|
||||
|
||||
if (strategy->isPID()) {
|
||||
PIDStrategy* pid = static_cast<PIDStrategy*>(strategy);
|
||||
inputValue = getPointValue(equipment, pid->getInputSensorName());
|
||||
|
||||
ModbusPoint<T>* PIDsetpoint = equipment->getModbusPoint(pid->getSetpointName());
|
||||
if (PIDsetpoint) {
|
||||
pid->setSetpoint(PIDsetpoint->getValue());
|
||||
}
|
||||
} else {
|
||||
inputValue = getPointValue(equipment, description);
|
||||
}
|
||||
|
||||
float newValue = strategy->execute(inputValue);
|
||||
setPointValue(equipment, description, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
50
lib/Core/States/State_Fail.h
Normal file
50
lib/Core/States/State_Fail.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @file State_Fail.h
|
||||
* @brief Defines the FailState class for the device.
|
||||
* @author Emmanuel Hernandez Cruz
|
||||
* @date 2025-09-05
|
||||
*
|
||||
* This file contains the definition for the FailState, which represents
|
||||
* a state where the equipment has encountered an error or fault condition.
|
||||
*/
|
||||
#ifndef Fail_State_h
|
||||
#define Fail_State_h
|
||||
|
||||
#include "State.h" // Include the base class header
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
template<typename T> class Equipment;
|
||||
/**
|
||||
* @class FailState
|
||||
* @brief Represents a failure or alarm state of the equipment.
|
||||
*
|
||||
* In this state, the equipment is in a non-operational fault condition.
|
||||
* It can be configured to apply specific strategies to its Modbus points to
|
||||
* simulate a particular failure scenario (e.g., setting alarm bits, stopping fans).
|
||||
* It waits for a command to transition to another state, such as returning to
|
||||
* Standby after the fault is cleared.
|
||||
*/
|
||||
template<typename T>
|
||||
class FailState : public State<T> {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new FailState object.
|
||||
* This is where strategies for failure behavior would be initialized.
|
||||
*/
|
||||
FailState(const std::vector<std::string>& activeAlarms);
|
||||
|
||||
/**
|
||||
* @brief Executes the fail state's logic for one update cycle.
|
||||
* This method applies the state's strategies and checks for a state transition command.
|
||||
* @param equipment Pointer to the Equipment instance.
|
||||
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
|
||||
*/
|
||||
State<T>* update(Equipment<T>* equipment) override;
|
||||
/** @brief Logic to execute once when entering the fail state. */
|
||||
void enterState(Equipment<T>* equipment) override;
|
||||
/** @brief Logic to execute once when exiting the fail state. */
|
||||
void exitState(Equipment<T>* equipment) override;
|
||||
};
|
||||
#endif
|
||||
47
lib/Core/States/State_Running.h
Normal file
47
lib/Core/States/State_Running.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file State_Running.h
|
||||
* @brief Defines the RunningState class for the device.
|
||||
* @author Emmanuel Hernandez Cruz
|
||||
* @date 2025-09-05
|
||||
*
|
||||
* This file contains the definition for the RunningState, which represents
|
||||
* the state where the equipment is actively performing its primary function.
|
||||
*/
|
||||
#ifndef Running_State_h
|
||||
#define Running_State_h
|
||||
|
||||
#include "State.h" // Include the base class header
|
||||
template<typename T> class Equipment;
|
||||
|
||||
/**
|
||||
* @class RunningState
|
||||
* @brief Represents the active running state of the equipment.
|
||||
*
|
||||
* In this state, the equipment is fully operational and performing its main
|
||||
* tasks. It applies a set of predefined strategies to its Modbus points to
|
||||
* simulate active behavior (e.g., fans running at various speeds) and waits
|
||||
* for a command to transition to another state.
|
||||
*/
|
||||
template<typename T>
|
||||
class RunningState : public State<T> {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new RunningState object.
|
||||
* Initializes the strategies for various Modbus points that are active
|
||||
* during the running state, such as setting fan speed behaviors.
|
||||
*/
|
||||
RunningState();
|
||||
|
||||
/**
|
||||
* @brief Executes the running state's logic for one update cycle.
|
||||
* This method applies the state's strategies and checks for a state transition command.
|
||||
* @param equipment Pointer to the Equipment instance.
|
||||
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
|
||||
*/
|
||||
State<T>* update(Equipment<T>* equipment) override;
|
||||
/** @brief Logic to execute once when entering the running state. */
|
||||
void enterState(Equipment<T>* equipment) override;
|
||||
/** @brief Logic to execute once when exiting the running state. */
|
||||
void exitState(Equipment<T>* equipment) override;
|
||||
};
|
||||
#endif
|
||||
48
lib/Core/States/State_Standby.h
Normal file
48
lib/Core/States/State_Standby.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file State_Standby.h
|
||||
* @brief Defines the StandbyState class for the device.
|
||||
* @author Emmanuel Hernandez Cruz
|
||||
* @date 2025-09-05
|
||||
*
|
||||
* This file contains the definition for the StandbyState, which represents
|
||||
* the state where the equipment is idle but ready to start. It defines
|
||||
* specific behaviors for Modbus points while in this state.
|
||||
*/
|
||||
#ifndef Standby_State_h
|
||||
#define Standby_State_h
|
||||
|
||||
#include "State.h" // Include the base class header
|
||||
|
||||
template<typename T> class Equipment;
|
||||
/**
|
||||
* @class StandbyState
|
||||
* @brief Represents the standby state of the equipment.
|
||||
*
|
||||
* In this state, the equipment is operational but not actively running its
|
||||
* primary function. It applies a set of predefined strategies to its Modbus
|
||||
* points to simulate standby behavior and waits for a command to transition
|
||||
* to another state (e.g., Running).
|
||||
*/
|
||||
template<typename T>
|
||||
class StandbyState : public State<T> {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new StandbyState object.
|
||||
* Initializes the strategies for various Modbus points that are active
|
||||
* during the standby state.
|
||||
*/
|
||||
StandbyState();
|
||||
|
||||
/**
|
||||
* @brief Executes the standby state's logic for one update cycle.
|
||||
* This method applies the state's strategies and checks for a state transition command.
|
||||
* @param equipment Pointer to the Equipment instance.
|
||||
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
|
||||
*/
|
||||
State<T>* update(Equipment<T>* equipment) override;
|
||||
/** @brief Logic to execute once when entering the standby state. */
|
||||
void enterState(Equipment<T>* equipment) override;
|
||||
/** @brief Logic to execute once when exiting the standby state. */
|
||||
void exitState(Equipment<T>* equipment) override;
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user