221 lines
6.9 KiB
C++
221 lines
6.9 KiB
C++
/**
|
|
* @file Equipment.h
|
|
* @brief Defines the main Equipment class for the device emulator.
|
|
* @author Emmanuel Hernandez Cruz
|
|
* @date 2025-09-02
|
|
*
|
|
* This file contains the definition for the Equipment class, which acts as the
|
|
* central context for the State design pattern. It manages the current state
|
|
* of the device and holds all of its Modbus points.
|
|
*/
|
|
#ifndef Equipment_h
|
|
#define Equipment_h
|
|
#include <Arduino.h>
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
#include "States/State_Standby.h"
|
|
|
|
// Forward Declarations
|
|
template<typename T> class State;
|
|
template<typename T> class ModbusPoint;
|
|
|
|
/**
|
|
* @class Equipment
|
|
* @brief The main class representing the emulated device.
|
|
*
|
|
* This class orchestrates the device's behavior. It holds a collection of all
|
|
* Modbus points and manages the device's current operational state (e.g.,
|
|
* Standby, Running) by delegating actions to a concrete State object.
|
|
*/
|
|
template<typename T>
|
|
class Equipment {
|
|
public:
|
|
/**
|
|
* @brief Constructs a new Equipment object.
|
|
* Initializes the device in the default initial state (Standby).
|
|
*/
|
|
Equipment();
|
|
|
|
Equipment(T* server);
|
|
/** @brief The main update loop for the equipment, called repeatedly. Delegates to the current state. */
|
|
void update();
|
|
/** @brief Delegates the enter state logic to the current state object. */
|
|
void enterState();
|
|
/** @brief Delegates the exit state logic to the current state object. */
|
|
void exitState();
|
|
/**
|
|
* @brief Sets a simple integer identifier for the current state.
|
|
* @param stateId The integer ID representing the state.
|
|
*/
|
|
void setState(int stateId);
|
|
/**
|
|
* @brief Gets the simple integer identifier for the current state.
|
|
* @return The integer ID of the state.
|
|
*/
|
|
int getState();
|
|
/**
|
|
* @brief Transitions the equipment to a new state.
|
|
* Handles exiting the old state, deleting it, and entering the new one.
|
|
* @param newState A pointer to the new State object. The Equipment takes ownership.
|
|
*/
|
|
void changeState(State<T>* newState);
|
|
/**
|
|
* @brief Adds a Modbus point to the equipment's internal map.
|
|
* @param description The unique string description used as a key.
|
|
* @param point A pointer to the ModbusPoint object.
|
|
*/
|
|
void addModbusPoint(const std::string& description, ModbusPoint<T>* point);
|
|
/**
|
|
* @brief Retrieves a Modbus point by its description.
|
|
* @param description The string key for the Modbus point.
|
|
* @return A pointer to the ModbusPoint object, or nullptr if not found.
|
|
*/
|
|
ModbusPoint<T>* getModbusPoint(const std::string& description);
|
|
/**
|
|
* @brief Sets the value of a specific Modbus point.
|
|
* @param description The string key for the Modbus point.
|
|
* @param value The value to set. Note: This float may be truncated or cast
|
|
* depending on the underlying point's `setValue` implementation.
|
|
*/
|
|
void setModbusPoint(const std::string& description, float value);
|
|
|
|
private:
|
|
State<T>* _state; /**< @brief Pointer to the current state object. */
|
|
std::map<std::string, ModbusPoint<T>*> _points;/**< @brief Map of all Modbus points, keyed by description. */
|
|
int _stateId; /**< @brief A simple integer identifier for the current state. */
|
|
T* _server;
|
|
};
|
|
|
|
template<typename T>
|
|
Equipment<T>::Equipment() : _server(nullptr) {
|
|
this->_state = new StandbyState<T>();
|
|
this->_state->enterState(this);
|
|
}
|
|
|
|
/**
|
|
* @brief Constructs a new Equipment object with a server instance.
|
|
* @param server Pointer to the Modbus server instance (e.g., ModbusIP, ModbusRTU).
|
|
*/
|
|
template<typename T>
|
|
Equipment<T>::Equipment(T* server)
|
|
: _server(server)
|
|
{
|
|
this->_state = new StandbyState<T>();
|
|
this->_state->enterState(this);
|
|
}
|
|
|
|
/**
|
|
* @brief The main update loop for the equipment.
|
|
*
|
|
* This method delegates the update logic to the current state object. If the
|
|
* state's update method returns a pointer to a new state, this method
|
|
* triggers a state transition.
|
|
*/
|
|
template<typename T>
|
|
void Equipment<T>::update() {
|
|
State<T>* newState = this->_state->update(this);
|
|
if (newState != nullptr) {
|
|
changeState(newState);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Delegates the enter state logic to the current state object.
|
|
*/
|
|
template<typename T>
|
|
void Equipment<T>::enterState() {
|
|
this->_state->enterState(this);
|
|
}
|
|
|
|
/**
|
|
* @brief Delegates the exit state logic to the current state object.
|
|
*/
|
|
template<typename T>
|
|
void Equipment<T>::exitState() {
|
|
this->_state->exitState(this);
|
|
}
|
|
|
|
/**
|
|
* @brief Adds a Modbus point to the equipment's internal collections.
|
|
* The point is added to a map for quick lookup by description and to a
|
|
* vector for simple iteration.
|
|
* @param description The unique string description used as a key.
|
|
* @param point A pointer to the ModbusPoint object.
|
|
*/
|
|
template<typename T>
|
|
void Equipment<T>::addModbusPoint(const std::string& description, ModbusPoint<T>* point) {
|
|
this->_points[description] = point;
|
|
}
|
|
|
|
/**
|
|
* @brief Retrieves a Modbus point by its description.
|
|
* @param description The string key for the Modbus point.
|
|
* @return A pointer to the ModbusPoint object, or nullptr if not found.
|
|
*/
|
|
template<typename T>
|
|
ModbusPoint<T>* Equipment<T>::getModbusPoint(const std::string& description) {
|
|
auto it = this->_points.find(description);
|
|
if (it != this->_points.end()) {
|
|
return it->second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the value of a specific Modbus point.
|
|
* Finds the point by its description and calls its `setValue` method.
|
|
* @param description The string key for the Modbus point.
|
|
* @param value The value to set. This float is cast to an int before being passed.
|
|
*/
|
|
template<typename T>
|
|
void Equipment<T>::setModbusPoint(const std::string& description, float value) {
|
|
ModbusPoint<T>* point = getModbusPoint(description);
|
|
if (point != nullptr) {
|
|
point->setValue(value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the simple integer identifier for the current state.
|
|
* @return The integer ID of the state.
|
|
*/
|
|
template<typename T>
|
|
int Equipment<T>::getState() {
|
|
return _stateId;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets a simple integer identifier for the current state.
|
|
* @param stateId The integer ID representing the state.
|
|
*/
|
|
template<typename T>
|
|
void Equipment<T>::setState(int stateId) {
|
|
this->_stateId = stateId;
|
|
}
|
|
|
|
/**
|
|
* @brief Transitions the equipment to a new state.
|
|
*
|
|
* This method handles the full lifecycle of a state transition: it calls
|
|
* `exitState` on the current state, deletes the old state object to prevent
|
|
* memory leaks, assigns the new state, and finally calls `enterState` on the
|
|
* new state.
|
|
*
|
|
* @param newState A pointer to the new State object. The Equipment takes ownership.
|
|
*/
|
|
template<typename T>
|
|
void Equipment<T>::changeState(State<T>* newState) {
|
|
if (this->_state != nullptr) {
|
|
this->_state->exitState(this);
|
|
delete this->_state;
|
|
}
|
|
this->_state = newState;
|
|
|
|
if (this->_state != nullptr) {
|
|
this->_state->enterState(this);
|
|
}
|
|
}
|
|
|
|
#endif
|